xfsprogs-3.1.9ubuntu2/0000775000000000000000000000000012254353675011630 5ustar xfsprogs-3.1.9ubuntu2/libhandle/0000775000000000000000000000000012062211563013534 5ustar xfsprogs-3.1.9ubuntu2/libhandle/Makefile0000664000000000000000000000072511432652134015203 0ustar # # Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTLIBRARY = libhandle.la LT_CURRENT = 1 LT_REVISION = 3 LT_AGE = 0 LTLDFLAGS += -Wl,--version-script,libhandle.sym CFILES = handle.c jdm.c LSRCFILES = libhandle.sym default: ltdepend $(LTLIBRARY) include $(BUILDRULES) install: default $(INSTALL_LTLIB) install-dev: default $(INSTALL_LTLIB_DEV) install-qa: install-dev -include .ltdep xfsprogs-3.1.9ubuntu2/libhandle/libhandle.sym0000664000000000000000000000147311307015331016211 0ustar /* * The symbol versioning ensures that a new application requiring symbol foo() * can't run with old libhandle.so not providing foo() - the global SONAME * version info can't enforce this since we never change the SONAME. * * Older versions of libhandle (<= 1.0.3) do not to use symbol versioning -- * all the original symbols are in LIBHANDLE_1.0.3 now. */ LIBHANDLE_1.0.3 { global: /* handle.h APIs */ path_to_handle; path_to_fshandle; handle_to_fshandle; free_handle; open_by_fshandle; open_by_handle; readlink_by_handle; attr_multi_by_handle; attr_list_by_handle; parents_by_handle; parentpaths_by_handle; fssetdm_by_handle; /* jdm.h APIs */ jdm_getfshandle; jdm_new_filehandle; jdm_delete_filehandle; jdm_open; jdm_readlink; jdm_attr_multi; jdm_attr_list; jdm_parents; jdm_parentpaths; }; xfsprogs-3.1.9ubuntu2/libhandle/handle.c0000664000000000000000000002231511604735741015150 0ustar /* * Copyright (c) 1995, 2001-2003, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include /* just pick a value we know is more than big enough */ #define MAXHANSIZ 64 /* * The actual content of a handle is supposed to be opaque here. * But, to do handle_to_fshandle, we need to know what it is. Sigh. * However we can get by with knowing only that the first 8 bytes of * a file handle are the file system ID, and that a file system handle * consists of only those 8 bytes. */ #define FSIDSIZE 8 typedef union { int fd; char *path; } comarg_t; static int obj_to_handle(char *, int, unsigned int, comarg_t, void**, size_t*); static int handle_to_fsfd(void *, char **); static char *path_to_fspath(char *path); /* * Filesystem Handle -> Open File Descriptor Cache * * Maps filesystem handles to a corresponding open file descriptor for that * filesystem. We need this because we're doing handle operations via xfsctl * and we need to remember the open file descriptor for each filesystem. */ struct fdhash { int fsfd; char fsh[FSIDSIZE]; struct fdhash *fnxt; char fspath[MAXPATHLEN]; }; static struct fdhash *fdhash_head = NULL; int path_to_fshandle( char *path, /* input, path to convert */ void **fshanp, /* output, pointer to data */ size_t *fshlen) /* output, size of returned data */ { int result; int fd; comarg_t obj; struct fdhash *fdhp; char *tmppath; char *fspath; fspath = path_to_fspath(path); if (fspath == NULL) return -1; fd = open(fspath, O_RDONLY); if (fd < 0) return -1; obj.path = path; result = obj_to_handle(fspath, fd, XFS_IOC_PATH_TO_FSHANDLE, obj, fshanp, fshlen); if (result < 0) { close(fd); return result; } if (handle_to_fsfd(*fshanp, &tmppath) >= 0) { /* this filesystem is already in the cache */ close(fd); } else { /* new filesystem. add it to the cache */ fdhp = malloc(sizeof(struct fdhash)); if (fdhp == NULL) { errno = ENOMEM; return -1; } fdhp->fsfd = fd; strncpy(fdhp->fspath, fspath, sizeof(fdhp->fspath)); memcpy(fdhp->fsh, *fshanp, FSIDSIZE); fdhp->fnxt = fdhash_head; fdhash_head = fdhp; } return result; } int path_to_handle( char *path, /* input, path to convert */ void **hanp, /* output, pointer to data */ size_t *hlen) /* output, size of returned data */ { int fd; int result; comarg_t obj; char *fspath; fspath = path_to_fspath(path); if (fspath == NULL) return -1; fd = open(fspath, O_RDONLY); if (fd < 0) return -1; obj.path = path; result = obj_to_handle(fspath, fd, XFS_IOC_PATH_TO_HANDLE, obj, hanp, hlen); close(fd); return result; } /* Given a path, return a suitable "fspath" for use in obtaining * an fd for xfsctl calls. For regular files and directories the * input path is sufficient. For other types the parent directory * is used to avoid issues with opening dangling symlinks and * potentially blocking in an open on a named pipe. Also * symlinks to files on other filesystems would be a problem, * since an fd would be obtained for the wrong fs. */ static char * path_to_fspath(char *path) { static char dirpath[MAXPATHLEN]; struct stat statbuf; if (lstat(path, &statbuf) != 0) return NULL; if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode)) return path; strcpy(dirpath, path); return dirname(dirpath); } int fd_to_handle ( int fd, /* input, file descriptor */ void **hanp, /* output, pointer to data */ size_t *hlen) /* output, size of returned data */ { comarg_t obj; obj.fd = fd; return obj_to_handle(NULL, fd, XFS_IOC_FD_TO_HANDLE, obj, hanp, hlen); } int handle_to_fshandle( void *hanp, size_t hlen, void **fshanp, size_t *fshlen) { if (hlen < FSIDSIZE) { errno = EINVAL; return -1; } *fshanp = malloc(FSIDSIZE); if (*fshanp == NULL) { errno = ENOMEM; return -1; } *fshlen = FSIDSIZE; memcpy(*fshanp, hanp, FSIDSIZE); return 0; } static int handle_to_fsfd(void *hanp, char **path) { struct fdhash *fdhp; /* * Look in cache for matching fsid field in the handle * (which is at the start of the handle). * When found return the file descriptor and path that * we have in the cache. */ for (fdhp = fdhash_head; fdhp != NULL; fdhp = fdhp->fnxt) { if (memcmp(fdhp->fsh, hanp, FSIDSIZE) == 0) { *path = fdhp->fspath; return fdhp->fsfd; } } errno = EBADF; return -1; } static int obj_to_handle( char *fspath, int fsfd, unsigned int opcode, comarg_t obj, void **hanp, size_t *hlen) { char hbuf [MAXHANSIZ]; int ret; __uint32_t handlen; xfs_fsop_handlereq_t hreq; if (opcode == XFS_IOC_FD_TO_HANDLE) { hreq.fd = obj.fd; hreq.path = NULL; } else { hreq.fd = 0; hreq.path = obj.path; } hreq.oflags = O_LARGEFILE; hreq.ihandle = NULL; hreq.ihandlen = 0; hreq.ohandle = hbuf; hreq.ohandlen = &handlen; ret = xfsctl(fspath, fsfd, opcode, &hreq); if (ret) return ret; *hanp = malloc(handlen); if (*hanp == NULL) { errno = ENOMEM; return -1; } memcpy(*hanp, hbuf, handlen); *hlen = handlen; return 0; } int open_by_fshandle( void *fshanp, size_t fshlen, int rw) { int fsfd; char *path; xfs_fsop_handlereq_t hreq; if ((fsfd = handle_to_fsfd(fshanp, &path)) < 0) return -1; hreq.fd = 0; hreq.path = NULL; hreq.oflags = rw | O_LARGEFILE; hreq.ihandle = fshanp; hreq.ihandlen = fshlen; hreq.ohandle = NULL; hreq.ohandlen = NULL; return xfsctl(path, fsfd, XFS_IOC_OPEN_BY_HANDLE, &hreq); } int open_by_handle( void *hanp, size_t hlen, int rw) { int fsfd; char *path; xfs_fsop_handlereq_t hreq; if ((fsfd = handle_to_fsfd(hanp, &path)) < 0) return -1; hreq.fd = 0; hreq.path = NULL; hreq.oflags = rw | O_LARGEFILE; hreq.ihandle = hanp; hreq.ihandlen = hlen; hreq.ohandle = NULL; hreq.ohandlen = NULL; return xfsctl(path, fsfd, XFS_IOC_OPEN_BY_HANDLE, &hreq); } int readlink_by_handle( void *hanp, size_t hlen, void *buf, size_t bufsiz) { int fd; __u32 buflen = (__u32)bufsiz; char *path; xfs_fsop_handlereq_t hreq; if ((fd = handle_to_fsfd(hanp, &path)) < 0) return -1; hreq.fd = 0; hreq.path = NULL; hreq.oflags = O_LARGEFILE; hreq.ihandle = hanp; hreq.ihandlen = hlen; hreq.ohandle = buf; hreq.ohandlen = &buflen; return xfsctl(path, fd, XFS_IOC_READLINK_BY_HANDLE, &hreq); } /*ARGSUSED4*/ int attr_multi_by_handle( void *hanp, size_t hlen, void *buf, int rtrvcnt, int flags) { int fd; char *path; xfs_fsop_attrmulti_handlereq_t amhreq; if ((fd = handle_to_fsfd(hanp, &path)) < 0) return -1; amhreq.hreq.fd = 0; amhreq.hreq.path = NULL; amhreq.hreq.oflags = O_LARGEFILE; amhreq.hreq.ihandle = hanp; amhreq.hreq.ihandlen = hlen; amhreq.hreq.ohandle = NULL; amhreq.hreq.ohandlen = NULL; amhreq.opcount = rtrvcnt; amhreq.ops = buf; return xfsctl(path, fd, XFS_IOC_ATTRMULTI_BY_HANDLE, &amhreq); } int attr_list_by_handle( void *hanp, size_t hlen, void *buf, size_t bufsize, int flags, struct attrlist_cursor *cursor) { int error, fd; char *path; xfs_fsop_attrlist_handlereq_t alhreq; if ((fd = handle_to_fsfd(hanp, &path)) < 0) return -1; alhreq.hreq.fd = 0; alhreq.hreq.path = NULL; alhreq.hreq.oflags = O_LARGEFILE; alhreq.hreq.ihandle = hanp; alhreq.hreq.ihandlen = hlen; alhreq.hreq.ohandle = NULL; alhreq.hreq.ohandlen = NULL; memcpy(&alhreq.pos, cursor, sizeof(alhreq.pos)); alhreq.flags = flags; alhreq.buffer = buf; alhreq.buflen = bufsize; /* prevent needless EINVAL from the kernel */ if (alhreq.buflen > XATTR_LIST_MAX) alhreq.buflen = XATTR_LIST_MAX; error = xfsctl(path, fd, XFS_IOC_ATTRLIST_BY_HANDLE, &alhreq); memcpy(cursor, &alhreq.pos, sizeof(alhreq.pos)); return error; } int parents_by_handle( void *hanp, size_t hlen, parent_t *buf, size_t bufsiz, unsigned int *count) { errno = EOPNOTSUPP; return -1; } int parentpaths_by_handle( void *hanp, size_t hlen, parent_t *buf, size_t bufsiz, unsigned int *count) { errno = EOPNOTSUPP; return -1; } int fssetdm_by_handle( void *hanp, size_t hlen, struct fsdmidata *fsdmidata) { int fd; char *path; xfs_fsop_setdm_handlereq_t dmhreq; if ((fd = handle_to_fsfd(hanp, &path)) < 0) return -1; dmhreq.hreq.fd = 0; dmhreq.hreq.path = NULL; dmhreq.hreq.oflags = O_LARGEFILE; dmhreq.hreq.ihandle = hanp; dmhreq.hreq.ihandlen = hlen; dmhreq.hreq.ohandle = NULL; dmhreq.hreq.ohandlen = NULL; dmhreq.data = fsdmidata; return xfsctl(path, fd, XFS_IOC_FSSETDM_BY_HANDLE, &dmhreq); } /*ARGSUSED1*/ void free_handle( void *hanp, size_t hlen) { free(hanp); } xfsprogs-3.1.9ubuntu2/libhandle/jdm.c0000664000000000000000000001163311140033220014442 0ustar /* * Copyright (c) 1995, 2001-2002, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include /* internal fshandle - typecast to a void for external use */ #define FSHANDLE_SZ 8 typedef struct fshandle { char fsh_space[FSHANDLE_SZ]; } fshandle_t; /* private file handle - for use by open_by_fshandle */ #define FILEHANDLE_SZ 24 #define FILEHANDLE_SZ_FOLLOWING 14 #define FILEHANDLE_SZ_PAD 2 typedef struct filehandle { fshandle_t fh_fshandle; /* handle of fs containing this inode */ int16_t fh_sz_following; /* bytes in handle after this member */ char fh_pad[FILEHANDLE_SZ_PAD]; /* padding, must be zeroed */ __uint32_t fh_gen; /* generation count */ xfs_ino_t fh_ino; /* 64 bit ino */ } filehandle_t; static void jdm_fill_filehandle( filehandle_t *handlep, fshandle_t *fshandlep, xfs_bstat_t *statp ) { handlep->fh_fshandle = *fshandlep; handlep->fh_sz_following = FILEHANDLE_SZ_FOLLOWING; memset(handlep->fh_pad, 0, FILEHANDLE_SZ_PAD); handlep->fh_gen = statp->bs_gen; handlep->fh_ino = statp->bs_ino; } jdm_fshandle_t * jdm_getfshandle( char *mntpnt ) { fshandle_t *fshandlep; size_t fshandlesz; char resolved[MAXPATHLEN]; /* sanity checks */ ASSERT( sizeof( fshandle_t ) == FSHANDLE_SZ ); ASSERT( sizeof( filehandle_t ) == FILEHANDLE_SZ ); ASSERT( sizeof( filehandle_t ) - offsetofmember( filehandle_t, fh_pad ) == FILEHANDLE_SZ_FOLLOWING ); ASSERT( sizeofmember( filehandle_t, fh_pad ) == FILEHANDLE_SZ_PAD ); ASSERT( FILEHANDLE_SZ_PAD == sizeof( int16_t )); fshandlep = NULL; /* for lint */ fshandlesz = sizeof( *fshandlep ); if (!realpath( mntpnt, resolved )) return NULL; if (path_to_fshandle( resolved, ( void ** )&fshandlep, &fshandlesz )) return NULL; assert( fshandlesz == sizeof( *fshandlep )); return ( jdm_fshandle_t * )fshandlep; } /* externally visible functions */ void jdm_new_filehandle( jdm_filehandle_t **handlep, size_t *hlen, jdm_fshandle_t *fshandlep, xfs_bstat_t *statp) { /* allocate and fill filehandle */ *hlen = sizeof(filehandle_t); *handlep = (filehandle_t *) malloc(*hlen); if (*handlep) jdm_fill_filehandle(*handlep, (fshandle_t *) fshandlep, statp); } /* ARGSUSED */ void jdm_delete_filehandle( jdm_filehandle_t *handlep, size_t hlen ) { free(handlep); } intgen_t jdm_open( jdm_fshandle_t *fshp, xfs_bstat_t *statp, intgen_t oflags ) { register fshandle_t *fshandlep = ( fshandle_t * )fshp; filehandle_t filehandle; intgen_t fd; jdm_fill_filehandle( &filehandle, fshandlep, statp ); fd = open_by_fshandle( ( void * )&filehandle, sizeof( filehandle ), oflags ); return fd; } intgen_t jdm_readlink( jdm_fshandle_t *fshp, xfs_bstat_t *statp, char *bufp, size_t bufsz ) { register fshandle_t *fshandlep = ( fshandle_t * )fshp; filehandle_t filehandle; intgen_t rval; jdm_fill_filehandle( &filehandle, fshandlep, statp ); rval = readlink_by_handle( ( void * )&filehandle, sizeof( filehandle ), ( void * )bufp, bufsz ); return rval; } int jdm_attr_multi( jdm_fshandle_t *fshp, xfs_bstat_t *statp, char *bufp, int rtrvcnt, int flags) { register fshandle_t *fshandlep = ( fshandle_t * )fshp; filehandle_t filehandle; int rval; jdm_fill_filehandle( &filehandle, fshandlep, statp ); rval = attr_multi_by_handle ( ( void * )&filehandle, sizeof( filehandle ), (void *) bufp, rtrvcnt, flags); return rval; } int jdm_attr_list( jdm_fshandle_t *fshp, xfs_bstat_t *statp, char *bufp, size_t bufsz, int flags, struct attrlist_cursor *cursor) { register fshandle_t *fshandlep = ( fshandle_t * )fshp; filehandle_t filehandle; int rval; /* prevent needless EINVAL from the kernel */ if (bufsz > XATTR_LIST_MAX) bufsz = XATTR_LIST_MAX; jdm_fill_filehandle( &filehandle, fshandlep, statp ); rval = attr_list_by_handle (( void * )&filehandle, sizeof( filehandle ), bufp, bufsz, flags, cursor); return rval; } int jdm_parents( jdm_fshandle_t *fshp, xfs_bstat_t *statp, parent_t *bufp, size_t bufsz, unsigned int *count) { errno = EOPNOTSUPP; return -1; } int jdm_parentpaths( jdm_fshandle_t *fshp, xfs_bstat_t *statp, parent_t *bufp, size_t bufsz, unsigned int *count) { errno = EOPNOTSUPP; return -1; } xfsprogs-3.1.9ubuntu2/debian/0000775000000000000000000000000013265631731013045 5ustar xfsprogs-3.1.9ubuntu2/debian/Makefile0000664000000000000000000000171211307270755014506 0ustar # # Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LSRCFILES = changelog compat control copyright rules DEV_DOC_DIR = $(PKG_DOC_DIR)/../xfslibs-dev BOOT_MKFS_BIN = $(TOPDIR)/mkfs/mkfs.xfs-xfsprogs-udeb LDIRDIRT = xfslibs-dev xfsprogs xfsprogs-udeb LDIRT = files *.log *.substvars *.debhelper default: include $(BUILDRULES) install: default ifeq ($(PKG_DISTRIBUTION), debian) $(INSTALL) -m 755 -d $(PKG_DOC_DIR) $(INSTALL) -m 644 changelog $(PKG_DOC_DIR)/changelog.Debian endif install-dev: default ifeq ($(PKG_DISTRIBUTION), debian) $(INSTALL) -m 755 -d $(PKG_DOC_DIR) $(INSTALL) -m 755 -d $(DEV_DOC_DIR) $(INSTALL) -m 644 copyright $(DEV_DOC_DIR) $(INSTALL) -m 644 changelog $(DEV_DOC_DIR)/changelog.Debian endif install-d-i: default ifeq ($(PKG_DISTRIBUTION), debian) $(INSTALL) -m 755 -d $(PKG_ROOT_SBIN_DIR) $(INSTALL) -m 755 $(BOOT_MKFS_BIN) $(PKG_ROOT_SBIN_DIR)/mkfs.xfs endif xfsprogs-3.1.9ubuntu2/debian/compat0000664000000000000000000000000211140033220014216 0ustar 5 xfsprogs-3.1.9ubuntu2/debian/control0000664000000000000000000000473412225525313014451 0ustar Source: xfsprogs Section: admin Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: XFS Development Team Uploaders: Nathan Scott , Anibal Monsalve Salazar Build-Depends: uuid-dev, autoconf, debhelper (>= 5), gettext, libtool, libreadline-gplv2-dev | libreadline5-dev, libblkid-dev (>= 2.17), linux-libc-dev, autotools-dev Standards-Version: 3.9.1 Homepage: http://oss.sgi.com/projects/xfs/ Package: xfsprogs Depends: ${shlibs:Depends}, ${misc:Depends} Provides: fsck-backend Suggests: xfsdump, acl, attr, quota Breaks: xfsdump (<< 3.0.0) Replaces: xfsdump (<< 3.0.0) Architecture: any Description: Utilities for managing the XFS filesystem A set of commands to use the XFS filesystem, including mkfs.xfs. . XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can support large files and large filesystems, extended attributes, variable block sizes, is extent based, and makes extensive use of Btrees (directories, extents, free space) to aid both performance and scalability. . Refer to the documentation at http://oss.sgi.com/projects/xfs/ for complete details. Package: xfslibs-dev Section: libdevel Priority: extra Depends: libc6-dev | libc-dev, uuid-dev, xfsprogs (>= 3.0.0), ${misc:Depends} Breaks: xfsprogs (<< 3.0.0) Architecture: any Description: XFS filesystem-specific static libraries and headers xfslibs-dev contains the libraries and header files needed to develop XFS filesystem-specific programs. . XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can support large files and large filesystems, extended attributes, variable block sizes, is extent based, and makes extensive use of Btrees (directories, extents, free space) to aid both performance and scalability. . Refer to the documentation at http://oss.sgi.com/projects/xfs/ for complete details. Package: xfsprogs-udeb XC-Package-Type: udeb Section: debian-installer Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A stripped-down version of xfsprogs, for debian-installer This package is an xfsprogs package built for reduced size, so that it can help to save space in debian-installer. . Don't attempt to install this package, it has no support for a couple of features you surely want. Anyway, it should fail to install. xfsprogs-3.1.9ubuntu2/debian/rules0000775000000000000000000000442412225525427014130 0ustar #!/usr/bin/make -f export DH_VERBOSE=1 package = xfsprogs develop = xfslibs-dev bootpkg = xfsprogs-udeb version = $(shell dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2) target ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) udebpkg = $(bootpkg)_$(version)_$(target).udeb dirme = debian/$(package) dirdev = debian/$(develop) dirdi = debian/$(bootpkg) pkgme = DIST_ROOT=`pwd`/$(dirme); export DIST_ROOT; pkgdev = DIST_ROOT=`pwd`/$(dirdev); export DIST_ROOT; pkgdi = DIST_ROOT=`pwd`/$(dirdi); export DIST_ROOT; stdenv = @GZIP=-q; export GZIP; options = export DEBUG=-DNDEBUG DISTRIBUTION=debian \ INSTALL_USER=root INSTALL_GROUP=root \ LOCAL_CONFIGURE_OPTIONS="--enable-readline=yes --enable-blkid=yes" ; diopts = $(options) \ export OPTIMIZER=-Os LOCAL_CONFIGURE_OPTIONS="--enable-gettext=no" ; checkdir = test -f debian/rules build: built built: dibuild config @echo "== dpkg-buildpackage: build" 1>&2 $(MAKE) default touch built config: .census .census: @echo "== dpkg-buildpackage: configure" 1>&2 $(checkdir) dh_autotools-dev_updateconfig $(options) $(MAKE) include/platform_defs.h touch .census dibuild: $(checkdir) @echo "== dpkg-buildpackage: installer" 1>&2 if [ ! -f mkfs/mkfs.xfs-$(bootpkg) ]; then \ $(diopts) $(MAKE) include/platform_defs.h; \ for dir in include libxfs libdisk mkfs; do \ $(MAKE) -C $$dir; \ done; \ mv mkfs/mkfs.xfs mkfs/mkfs.xfs-$(bootpkg); \ $(MAKE) distclean; \ fi clean: @echo "== dpkg-buildpackage: clean" 1>&2 $(checkdir) -rm -f built .census mkfs/mkfs.xfs-$(bootpkg) $(MAKE) distclean -rm -rf $(dirme) $(dirdev) $(dirdi) -rm -f debian/*substvars debian/files* debian/*.debhelper dh_autotools-dev_restoreconfig dh_clean binary-indep: binary-arch: checkroot built @echo "== dpkg-buildpackage: binary-arch" 1>&2 $(checkdir) -rm -rf $(dirme) $(dirdev) $(dirdi) $(pkgme) $(MAKE) -C . install $(pkgdev) $(MAKE) -C . install-dev $(pkgdi) $(MAKE) -C debian install-d-i $(pkgme) $(MAKE) dist rmdir debian/xfslibs-dev/usr/share/doc/xfsprogs dh_installdocs dh_installchangelogs dh_strip dh_compress dh_fixperms dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch checkroot: test 0 -eq `id -u` .PHONY: binary binary-arch binary-indep clean checkroot xfsprogs-3.1.9ubuntu2/debian/changelog0000664000000000000000000005560313265631726014734 0ustar xfsprogs (3.1.9ubuntu2.1) trusty; urgency=medium * [dda4129] xfs_logprint: Handle multiply-logged inode fields. xlog_print_trans_inode() will error "illegal inode type" if more than one flag is set on f->ilf_fields. (LP: #1763086) -- Eric Desrochers Tue, 10 Apr 2018 16:23:17 -0400 xfsprogs (3.1.9ubuntu2) trusty; urgency=medium * Patch m4/libtool.m4 for powerpc64le and regenerate configure. -- Matthias Klose Wed, 18 Dec 2013 18:14:04 +0100 xfsprogs (3.1.9ubuntu1) saucy; urgency=low * Use the autotools-dev dh addon to update config.guess/config.sub for arm64. -- Colin Watson Thu, 10 Oct 2013 14:25:32 +0100 xfsprogs (3.1.9) unstable; urgency=low * New upstream release -- Nathan Scott Wed, 31 Oct 2012 13:29:00 +1100 xfsprogs (3.1.8) unstable; urgency=low * New upstream release * Numerous xfs_repair fixes -- Nathan Scott Mon, 19 Mar 2012 14:21:00 +1100 xfsprogs (3.1.7) unstable; urgency=low * New upstream release * Fix libreadline build dependency (closes: #553875) -- Nathan Scott Thu, 17 Nov 2011 08:47:00 +1100 xfsprogs (3.1.6) unstable; urgency=low * New upstream release * Handle upcoming libreadline5-dev removal (closes: #553875) -- Nathan Scott Wed, 11 Oct 2011 16:47:10 +1100 xfsprogs (3.1.5) unstable; urgency=low * New upstream release * No more xfsquota error message for non-quota mounts (closes: #618730) -- Nathan Scott Wed, 31 Mar 2011 09:00:00 +1100 xfsprogs (3.1.4) unstable; urgency=low * New upstream release (32 projid resolution, fsr uses /proc/mounts) * Annotate Debian packages as being team maintained now. * Resolve Lenny upgrade issue with xfsdump (closes: #601988, #601710) -- Nathan Scott Tue, 09 Nov 2010 22:39:04 +1100 xfsprogs (3.1.3) unstable; urgency=low * New upstream release * Enforce building with libblkid (closes: #593320) -- Nathan Scott Thu, 26 Aug 2010 23:06:46 +1000 xfsprogs (3.1.2) unstable; urgency=low * New upstream release * Allow for building on GNU/kFreeBSD (closes: #485796) -- Nathan Scott Mon, 3 May 2010 14:25:43 +1100 xfsprogs (3.1.1) unstable; urgency=low * New upstream release -- Nathan Scott Thu, 28 Jan 2010 20:54:22 +1100 xfsprogs (3.1.0) unstable; urgency=low * New upstream release * Merged German translation (closes: #521389) * Merged German translation update (closes: #557100) * Uptodate po file is provided now (closes: #538962) * Fixed typos in xfs_quota man page (closes: #481715) * Tighten permissions on temp fsr files (closes: #559490) -- Nathan Scott Thu, 10 Dec 2009 09:19:37 +1100 xfsprogs (3.0.4) unstable; urgency=low * New bugfix release * Resolve a libxfs unaligned access (closes: #517553) -- Nathan Scott Thu, 17 Sep 2009 14:32:48 +1000 xfsprogs (3.0.2) unstable; urgency=low * New bugfix release -- Nathan Scott Wed, 06 May 2009 11:29:18 +1000 xfsprogs (3.0.0-1) unstable; urgency=low * New upstream release (closes: #263170) * Remove watch file, xfsprogs is native * Updated dependencies as this requires xfsdump 3 also -- Nathan Scott Wed, 28 Jan 2009 21:15:07 +1100 xfsprogs (2.10.2-1) unstable; urgency=low * New upstream release * No longer ignore -i maxpct option in mkfs.xfs (closes: #500593) * Correct features2 superblock field handling (closes: #473135) * 32 bit emulation on 64 bit kernels works (closes: #485020) * Fix up large sector handling in mkfs (closes: #489421) -- Nathan Scott Sat, 20 Dec 2008 10:14:27 +1100 xfsprogs (2.9.10-1) unstable; urgency=low * New upstream release -- Anibal Monsalve Salazar Fri, 05 Sep 2008 14:02:20 +1000 xfsprogs (2.9.8-1) unstable; urgency=low * New upstream release * xfsprogs and xfsprogs-udeb depend on ${misc:Depends} * Add Homepage control header * Add watch file * Fix the following lintian issues: W: xfsprogs source: package-uses-deprecated-debhelper-compat-version 1 W: xfsprogs source: ancient-standards-version 3.5.9 (current is 3.7.3) W: xfslibs-dev: package-contains-empty-directory usr/share/doc/xfsprogs/ -- Anibal Monsalve Salazar Tue, 22 Apr 2008 13:04:05 +1000 xfsprogs (2.9.7-1) unstable; urgency=high * New upstream release. * Add -y fsck option (closes: #463810) * Lazy superblock counters not yet mkfs default (closes: #465737, #468184) * xfs_repair memory requirements significantly reduced (closes: #289665) -- Nathan Scott Sat, 01 Mar 2008 06:24:21 +1100 xfsprogs (2.9.5-1) unstable; urgency=low * New upstream release. -- Nathan Scott Tue, 22 Jan 2008 16:46:18 +1100 xfsprogs (2.9.0-1) unstable; urgency=low * New upstream release. -- Nathan Scott Tue, 12 Jun 2007 07:22:21 +1000 xfsprogs (2.8.20-1) unstable; urgency=low * New upstream release (closes: #414079) * Fixed up autoconf version dependency (closes: #414073) -- Nathan Scott Fri, 16 Mar 2007 08:24:33 +1100 xfsprogs (2.8.19-1) unstable; urgency=low * New upstream release (closes: #409063) -- Nathan Scott Wed, 31 Jan 2007 08:53:32 +1100 xfsprogs (2.8.18-1) unstable; urgency=low * New upstream release (closes: #399888) -- Nathan Scott Fri, 08 Dec 2006 08:30:29 +1100 xfsprogs (2.8.12-1) unstable; urgency=low * New upstream release. -- Nathan Scott Tue, 29 Aug 2006 14:28:05 +1000 xfsprogs (2.8.11-1) unstable; urgency=low * New upstream release. * More efficient use of buffer cache memory (closes: #382935) -- Nathan Scott Tue, 08 Aug 2006 17:06:58 +1000 xfsprogs (2.8.10-1) unstable; urgency=low * New upstream release. -- Nathan Scott Wed, 02 Aug 2006 11:17:07 +1000 xfsprogs (2.8.4-1) unstable; urgency=low * New upstream release. * Improved udeb packaging, thanks to Frans Pop (closes: #375439) * Fix filesystem-from-path detection logic (closes: #374687) -- Nathan Scott Mon, 26 Jun 2006 10:04:18 +1000 xfsprogs (2.8.3-1) unstable; urgency=low * New upstream release. * Fix segv in xfs_growfs command (closes: #374686) * Ensure source tarball in correct location (closes: #374696) -- Nathan Scott Wed, 21 Jun 2006 15:19:56 +1000 xfsprogs (2.7.16-1) unstable; urgency=low * New upstream release. -- Nathan Scott Wed, 05 Apr 2006 11:45:58 +1000 xfsprogs (2.7.14-1) unstable; urgency=low * New upstream release. * Switch from debmake to debhelper -- Nathan Scott Wed, 15 Feb 2006 20:04:55 +1100 xfsprogs (2.7.12-1) unstable; urgency=low * New upstream release. * Includes polish translation from Jakub Bogusz. -- Nathan Scott Tue, 31 Jan 2006 13:35:39 +1100 xfsprogs (2.7.7-1) unstable; urgency=low * New upstream release. * Add support for (optional) ATTR2 format extension (closes: #336350) * Allow gcc -pedantic option for C++ users (closes: #249429) * Fix segv in xfs_db frag command (closes: #338207) -- Nathan Scott Wed, 16 Nov 2005 16:32:35 +1100 xfsprogs (2.7.4-1) unstable; urgency=low * New upstream release. -- Nathan Scott Sat, 08 Oct 2005 10:34:10 +1000 xfsprogs (2.6.36-1) unstable; urgency=low * New upstream release. * Fix xfs_repair secondary SB search 32 bit wrap (closes: #320081) -- Nathan Scott Thu, 28 Jul 2005 14:01:50 +1000 xfsprogs (2.6.28-1) unstable; urgency=low * New upstream release. * Fix compilation with gcc version 4 (closes: #300544) -- Nathan Scott Wed, 30 Mar 2005 10:52:07 +1000 xfsprogs (2.6.26-2) unstable; urgency=low * No code differences, recompiled with a more recent gcc version. -- Nathan Scott Tue, 29 Mar 2005 11:57:57 +1000 xfsprogs (2.6.26-1) unstable; urgency=low * New upstream release. * Man page updates (closes: #295397) * Fix compilation with gcc version 4 (closes: #297876) * Switch build dependency from readline4 to readline5. -- Nathan Scott Tue, 08 Mar 2005 16:56:35 +1100 xfsprogs (2.6.23-1) unstable; urgency=low * New upstream release. -- Nathan Scott Fri, 17 Sep 2004 17:04:45 +1000 xfsprogs (2.6.21-1) unstable; urgency=low * New upstream release. * Fix xfs_io build for older glibc versions (current stable). -- Nathan Scott Mon, 09 Aug 2004 16:09:42 +1000 xfsprogs (2.6.20-1) unstable; urgency=low * New upstream release. * Fix xfs_io segfault on non-XFS files. (closes: #260470) * Fix packaging botch, deleted files included. (closes: #260491) -- Nathan Scott Wed, 28 Jul 2004 21:11:38 +1000 xfsprogs (2.6.19-1) unstable; urgency=low * New upstream release. -- Nathan Scott Sat, 17 Jul 2004 11:28:39 +1000 xfsprogs (2.6.18-1) unstable; urgency=low * New upstream release. -- Nathan Scott Fri, 25 Jun 2004 16:57:09 +1000 xfsprogs (2.6.15-1) unstable; urgency=low * New upstream release. -- Nathan Scott Wed, 09 Jun 2004 21:10:14 +1000 xfsprogs (2.6.14-1) unstable; urgency=low * New upstream release. * Add a Provides: fsck-backend clause as requested in the context of bug number 111651. -- Nathan Scott Thu, 13 May 2004 09:56:19 +1000 xfsprogs (2.6.11-1) unstable; urgency=low * New upstream release. -- Nathan Scott Fri, 16 Apr 2004 11:50:56 +1000 xfsprogs (2.6.5-1) unstable; urgency=low * New upstream release. -- Nathan Scott Thu, 26 Feb 2004 14:44:41 +1100 xfsprogs (2.6.3-1) unstable; urgency=low * New upstream release. * Add support for debian-installer. (closes: #225444) Author: Steve Langasek. * Use debhelper instead of debmake, for proper udeb building. Author: Steve Langasek. * Drop boot-floppies support. (closes: #112715) Author: Steve Langasek. * Add support for the security attribute namespace. -- Nathan Scott Mon, 19 Jan 2004 10:08:59 +1100 xfsprogs (2.6.0-1) unstable; urgency=low * New upstream release. * Note: change in the mkfs algorithm for sizing allocation groups. -- Nathan Scott Tue, 28 Oct 2003 15:23:48 +1100 xfsprogs (2.5.11-1) unstable; urgency=low * New upstream release. -- Nathan Scott Fri, 10 Oct 2003 09:37:57 +1000 xfsprogs (2.5.6-1) unstable; urgency=low * New upstream release. -- Nathan Scott Tue, 19 Aug 2003 09:44:48 +1000 xfsprogs (2.5.5-1) unstable; urgency=low * New upstream release. -- Nathan Scott Thu, 07 Aug 2003 12:58:36 +1000 xfsprogs (2.5.4-1) unstable; urgency=low * New upstream release, includes xfs_copy command * Fix shell quoting in xfs_bmap, from Kai S. Juse (closes: #202588) -- Nathan Scott Wed, 23 Jul 2003 10:36:28 +1000 xfsprogs (2.5.3-1) unstable; urgency=low * New upstream release * Changed mkfs.xfs default log size scaling algorithm slightly, to create larger logs at smaller filesystem sizes by default * Enable support for sector sizes larger than 512 bytes -- Nathan Scott Mon, 7 Jul 2003 16:06:21 +1000 xfsprogs (2.4.12-1) unstable; urgency=low * New upstream release -- Nathan Scott Mon, 2 Jun 2003 13:51:06 +1000 xfsprogs (2.4.10-1) unstable; urgency=low * New upstream release * Add missing xfslibs-dev dependency on uuid-dev (closes: #193309) -- Nathan Scott Thu, 15 May 2003 08:50:22 +1000 xfsprogs (2.4.9-1) unstable; urgency=low * New upstream release -- Nathan Scott Fri, 2 May 2003 09:34:17 +1000 xfsprogs (2.4.4-1) unstable; urgency=low * New upstream release * Dependencies on libreadline4 and libreadline4-dev added -- Nathan Scott Sun, 30 Mar 2003 10:30:18 +1000 xfsprogs (2.4.1-1) unstable; urgency=low * New upstream release * Updated policy version to which this package conforms * Note: unwritten extents are now enabled by default in mkfs.xfs -- Nathan Scott Tue, 18 Mar 2003 16:16:43 +1100 xfsprogs (2.3.11-1) unstable; urgency=low * Add missing build dependency on gettext (closes: #181331) -- Nathan Scott Tue, 18 Feb 2003 08:57:46 +1100 xfsprogs (2.3.10-1) unstable; urgency=low * New upstream release -- Nathan Scott Mon, 17 Feb 2003 14:52:20 +1100 xfsprogs (2.3.6-1) unstable; urgency=low * New upstream release -- Nathan Scott Thu, 31 Oct 2002 17:26:44 +1100 xfsprogs (2.3.5-1) unstable; urgency=low * New upstream release * Fix mkfs bug, patch from Anton Blanchard (closes: #163897) -- Nathan Scott Mon, 7 Oct 2002 05:19:51 +1000 xfsprogs (2.3.4-1) unstable; urgency=low * New upstream release -- Nathan Scott Mon, 7 Oct 2002 05:19:51 +1000 xfsprogs (2.3.0-1) unstable; urgency=low * New upstream release * Improve backwards compatibility of tools using the XFS geometry ioctl for older kernel versions which don't support the new ioctl -- Nathan Scott Tue, 3 Sep 2002 09:55:48 +1000 xfsprogs (2.2.1-1) unstable; urgency=low * New upstream release * Default mkfs.xfs blocksize is now 4096 bytes, not getpagesize(2) * Fix to allow install process to work for newer autoconf versions -- Nathan Scott Wed, 7 Aug 2002 11:37:23 +1000 xfsprogs (2.1.2-1) unstable; urgency=low * New upstream release * Support for the XFS version 2 log format -- Nathan Scott Tue, 30 Jul 2002 09:49:08 +1000 xfsprogs (2.0.6-2) unstable; urgency=low * Fix a problem in xfs_repair's handling of ACLs -- Nathan Scott Thu, 30 May 2002 17:22:05 +1000 xfsprogs (2.0.6-1) unstable; urgency=low * New upstream release -- Nathan Scott Thu, 30 May 2002 14:31:30 +1000 xfsprogs (2.0.4-1) unstable; urgency=low * New upstream release, minor changes only -- Nathan Scott Wed, 17 Apr 2002 15:30:52 +1000 xfsprogs (2.0.3-1) unstable; urgency=low * New upstream bugfix release -- Nathan Scott Sat, 13 Apr 2002 09:45:06 +1000 xfsprogs (2.0.2-1) unstable; urgency=low * New upstream bugfix release -- Nathan Scott Thu, 4 Apr 2002 12:11:01 +1100 xfsprogs (2.0.1-1) unstable; urgency=low * New upstream bugfix (minor) release -- Nathan Scott Tue, 12 Mar 2002 13:25:32 +1100 xfsprogs (2.0.0-1) unstable; urgency=low * New upstream release with support for new libhandle interfaces * Major release for switch to official extended attributes syscalls -- Nathan Scott Thu, 7 Feb 2002 13:25:26 +1100 xfsprogs (1.3.18-1) unstable; urgency=low * New upstream bugfix (minor) release -- Nathan Scott Thu, 17 Jan 2002 11:13:19 +1100 xfsprogs (1.3.17-1) unstable; urgency=low * New upstream release * mkfs.xfs overwrites other filesystem signatures * xfs_repair fix for "avl_insert: duplicate range" bug -- Nathan Scott Mon, 14 Jan 2002 10:59:50 +1100 xfsprogs (1.3.16-1) unstable; urgency=low * Remove temporary file use in xfs_db * Add "type text" command into xfs_db -- Nathan Scott Mon, 17 Dec 2001 12:17:54 +1100 xfsprogs (1.3.15-1) unstable; urgency=low * Fix minor package version numbering issue (closes: #117545) * Fix bug in mkfs.xfs device size cross-check for realtime device * Reenable use of the BLKBSZSET ioctl in libxfs -- Nathan Scott Wed, 12 Dec 2001 09:25:42 +1100 xfsprogs (1.3.14-1) unstable; urgency=low * Fix minor package version numbering issue (closes: #117545) * Fix bug in mkfs.xfs device size cross-check for realtime device -- Nathan Scott Wed, 5 Dec 2001 17:13:06 +1100 xfsprogs (1.3.13-0) unstable; urgency=low * New upstream release * Fixes an important mkfs.xfs bug for >1TB filesystems * xfs_repair will no longer blindly zero a dirty log -- Nathan Scott Fri, 26 Oct 2001 10:42:26 +1000 xfsprogs (1.3.11-0) unstable; urgency=low * Upstream release fixing several issues on 64 bit platforms -- Nathan Scott Wed, 17 Oct 2001 10:00:35 +1000 xfsprogs (1.3.10-0) unstable; urgency=low * New upstream release * Fix up some issues building the bootfloppies package -- Nathan Scott Fri, 12 Oct 2001 17:43:20 +1000 xfsprogs (1.3.9-0) unstable; urgency=low * Upstream bug fix release * Additional and updated manual page entries -- Nathan Scott Fri, 5 Oct 2001 14:39:47 +1000 xfsprogs (1.3.8-0) unstable; urgency=low * New upstream release * Fix inclusion of mkfs man page in boot floppies package (closes: #112634) -- Nathan Scott Wed, 19 Sep 2001 14:49:30 +1000 xfsprogs (1.3.7-0) unstable; urgency=low * New upstream release * Change to libhandle licensing (was GPL, now LGPL-2.1) * Create a boot-floppies package with smaller mkfs.xfs (closes: #111426) * Make install-sh posix compliant so ash as /bin/sh works (closes: #111985) -- Nathan Scott Mon, 10 Sep 2001 10:52:04 +1000 xfsprogs (1.3.5-0) unstable; urgency=low * Upstream bugfix release; fixes listed below * Fix bug in xfs_db bit handling on big endian platforms * Fix mkfs.xfs bug related to too-small final allocation group * Fix signedness bug in DMAPI ioctl structure definition -- Nathan Scott Mon, 13 Aug 2001 09:38:27 +1000 xfsprogs (1.3.4-0) unstable; urgency=low * Upstream bugfix release; fixes listed below * Fix endian bug in xfs_db "frag" command * Several man pages updated to document external log usage * IA64 build issues fixed (use -fno-strict-aliasing for libraries) * Fixed several minor compiler warnings when building on IA64 * Added a Suggests entry for dvhtool (for those using SGI disks) * configure.in changes to allow cross compilation -- Nathan Scott Sat, 4 Aug 2001 10:32:00 +1000 xfsprogs (1.3.3-0) unstable; urgency=low * New upstream release -- Nathan Scott Fri, 27 Jul 2001 07:59:49 +1000 xfsprogs (1.3.2-0) unstable; urgency=low * New upstream release -- Nathan Scott Mon, 23 Jul 2001 10:27:37 +1000 xfsprogs (1.3.1-0) unstable; urgency=low * Reworked package slightly so that it's not Debian native * Debian-specific changes now documented in changelog.Debian.gz * New upstream release (see /usr/share/doc/xfsprogs/changelog.gz) * Checked standards compliance - update standards version to 3.5.5 -- Nathan Scott Sat, 15 Jul 2001 16:34:43 +1000 xfsprogs (1.3.0) unstable; urgency=low * Reworked Makefiles to use libtool * New libdisk to allow sharing of generic mount/disk code and * Also abstracts individual driver support (LVM, MD, XVM..) * Partition table detection so mkfs.xfs doesn't blindly overwrite * Small xfs_repair bug fix from Steve -- Nathan Scott Thu, 19 Jul 2001 10:12:03 +1000 xfsprogs (1.2.8) unstable; urgency=low * Fixed a bug in libxfs /etc/mtab read-only mount detection * First try procfs, fall back to /etc/mtab, for read-only mounts * Sync with recent mount code changes for reiserfs and ext3 probes * Fix logprint build problem under gcc 3.0 -- Nathan Scott Mon, 2 Jul 2001 13:59:08 +1000 xfsprogs (1.2.7) unstable; urgency=low * New xfs_freeze(8) command - volume manager snapshot helper -- Nathan Scott Tue, 22 May 2001 17:22:32 +1000 xfsprogs (1.2.6) unstable; urgency=low * Merge support for -d agsize=/su=/sw= (AG, stripe unit/width size) * Merge support for dynamic configuration of default log size * Document these updates, and fix a couple of man page typos too -- Nathan Scott Tue, 15 May 2001 12:34:17 +1000 xfsprogs (1.2.5) unstable; urgency=low * Fix missing Makefile include entries for LVM headers * Add experimental xfs_rtcp (realtime copy) command * PowerPC build failure fixups - thanks to Robert Ramiega * Cleanup arch-specific code, esp. the byteswab routines * Suggests xfsdump and attr packages -- Nathan Scott Tue, 8 May 2001 15:50:27 +1000 xfsprogs (1.2.4) unstable; urgency=low * Add -L option to mkfs.xfs (filesystem label) -- Nathan Scott Tue, 1 May 2001 14:03:14 +1000 xfsprogs (1.2.3) unstable; urgency=low * Add dquot and quotaoff log item support into xfs_logprint * Fix logprint core dump reporting AGI in "continue"'d transactions -- Nathan Scott Fri, 27 Apr 2001 10:17:25 +1000 xfsprogs (1.2.2) unstable; urgency=low * Fix problem in xfs_db (check) group quota logic * Fixes to warnings from recent gcc and/or 64-bit builds -- Nathan Scott Fri, 13 Apr 2001 09:50:37 +1000 xfsprogs (1.2.1) unstable; urgency=low * Support for group quota added * Stripe unit/stripe width extraction for MD devices * Added mkfs.xfs heuristics for size of internal log * Sync up with recent changes to XFS kernel headers -- Nathan Scott Wed, 4 Apr 2001 13:54:00 +1000 xfsprogs (1.1.6) unstable; urgency=low * Fix sparc build failure - fcntl.h missing O_DIRECT (closes: #90211) * Added README.quota describing the use of quota with XFS -- Nathan Scott Tue, 20 Mar 2001 11:25:03 +1100 xfsprogs (1.1.5) unstable; urgency=low * Upgraded LVM stripe unit/width support to 0.9beta2 (IOP 10) * Kernel now supports O_DIRECT - re-enable its use in xfs_mkfile * BLKSETSIZE ioctl replaced by BLKBSZSET ioctl in libxfs * libxfs_init extended so only mkfs and xfs_repair use BLKBSZSET * NOTE: this requires an XFS kernel from 9 March '01 or later -- Nathan Scott Sun, 18 Mar 2001 14:31:17 +1100 xfsprogs (1.1.3) unstable; urgency=low * Minor changes to xfs_logprint tail verification * Update build Makefile to pick up extra dirt before packaging -- Nathan Scott Thu, 1 Mar 2001 12:24:28 +1100 xfsprogs (1.1.2) unstable; urgency=low * Fix stdarg.h issue causing build failure with glibc 2.2.2 * Changes to libhandle for supporting extended attributes -- Nathan Scott Tue, 20 Feb 2001 08:29:36 +1100 xfsprogs (1.1.0) unstable; urgency=low * Initial release (closes: #83829) -- Nathan Scott Thu, 4 Jan 2001 11:15:11 -0500 Local variables: mode: debian-changelog End: xfsprogs-3.1.9ubuntu2/debian/copyright0000664000000000000000000000127211140033220014755 0ustar This package was debianized by Nathan Scott nathans@debian.org on Sun, 19 Nov 2000 07:37:09 -0500. It can be downloaded from ftp://oss.sgi.com/projects/xfs/download/ Copyright: Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. You are free to distribute this software under the terms of the GNU General Public License. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL file. The library named "libhandle" is licensed under Version 2.1 of the GNU Lesser General Public License. On Debian systems, refer to /usr/share/common-licenses/LGPL-2.1 for the complete text of the GNU Lesser General Public License. xfsprogs-3.1.9ubuntu2/libxfs/0000775000000000000000000000000012062211563013101 5ustar xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc.c0000664000000000000000000011250411650373061015377 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Allocation group level functions. */ static inline int xfs_ialloc_cluster_alignment( xfs_alloc_arg_t *args) { if (xfs_sb_version_hasalign(&args->mp->m_sb) && args->mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp))) return args->mp->m_sb.sb_inoalignmt; return 1; } /* * Lookup a record by ino in the btree given by cur. */ int /* error */ xfs_inobt_lookup( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agino_t ino, /* starting inode of chunk */ xfs_lookup_t dir, /* <=, >=, == */ int *stat) /* success/failure */ { cur->bc_rec.i.ir_startino = ino; cur->bc_rec.i.ir_freecount = 0; cur->bc_rec.i.ir_free = 0; return xfs_btree_lookup(cur, dir, stat); } /* * Update the record referred to by cur to the value given. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int /* error */ xfs_inobt_update( struct xfs_btree_cur *cur, /* btree cursor */ xfs_inobt_rec_incore_t *irec) /* btree record */ { union xfs_btree_rec rec; rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino); rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount); rec.inobt.ir_free = cpu_to_be64(irec->ir_free); return xfs_btree_update(cur, &rec); } /* * Get the data from the pointed-to record. */ int /* error */ xfs_inobt_get_rec( struct xfs_btree_cur *cur, /* btree cursor */ xfs_inobt_rec_incore_t *irec, /* btree record */ int *stat) /* output: success/failure */ { union xfs_btree_rec *rec; int error; error = xfs_btree_get_rec(cur, &rec, stat); if (!error && *stat == 1) { irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino); irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount); irec->ir_free = be64_to_cpu(rec->inobt.ir_free); } return error; } /* * Verify that the number of free inodes in the AGI is correct. */ #ifdef DEBUG STATIC int xfs_check_agi_freecount( struct xfs_btree_cur *cur, struct xfs_agi *agi) { if (cur->bc_nlevels == 1) { xfs_inobt_rec_incore_t rec; int freecount = 0; int error; int i; error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); if (error) return error; do { error = xfs_inobt_get_rec(cur, &rec, &i); if (error) return error; if (i) { freecount += rec.ir_freecount; error = xfs_btree_increment(cur, 0, &i); if (error) return error; } } while (i == 1); if (!XFS_FORCED_SHUTDOWN(cur->bc_mp)) ASSERT(freecount == be32_to_cpu(agi->agi_freecount)); } return 0; } #else #define xfs_check_agi_freecount(cur, agi) 0 #endif /* * Initialise a new set of inodes. */ STATIC void xfs_ialloc_inode_init( struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_agblock_t length, unsigned int gen) { struct xfs_buf *fbuf; struct xfs_dinode *free; int blks_per_cluster, nbufs, ninodes; int version; int i, j; xfs_daddr_t d; /* * Loop over the new block(s), filling in the inodes. * For small block sizes, manipulate the inodes in buffers * which are multiples of the blocks size. */ if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { blks_per_cluster = 1; nbufs = length; ninodes = mp->m_sb.sb_inopblock; } else { blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / mp->m_sb.sb_blocksize; nbufs = length / blks_per_cluster; ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; } /* * Figure out what version number to use in the inodes we create. * If the superblock version has caught up to the one that supports * the new inode format, then use the new inode version. Otherwise * use the old version so that old kernels will continue to be * able to use the file system. */ if (xfs_sb_version_hasnlink(&mp->m_sb)) version = 2; else version = 1; for (j = 0; j < nbufs; j++) { /* * Get the block. */ d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize * blks_per_cluster, XBF_LOCK); ASSERT(fbuf); ASSERT(!XFS_BUF_GETERROR(fbuf)); /* * Initialize all inodes in this buffer and then log them. * * XXX: It would be much better if we had just one transaction * to log a whole cluster of inodes instead of all the * individual transactions causing a lot of log traffic. */ xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog); for (i = 0; i < ninodes; i++) { int ioffset = i << mp->m_sb.sb_inodelog; uint isize = sizeof(struct xfs_dinode); free = xfs_make_iptr(mp, fbuf, i); free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); free->di_version = version; free->di_gen = cpu_to_be32(gen); free->di_next_unlinked = cpu_to_be32(NULLAGINO); xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1); } xfs_trans_inode_alloc_buf(tp, fbuf); } } /* * Allocate new inodes in the allocation group specified by agbp. * Return 0 for success, else error code. */ STATIC int /* error code or 0 */ xfs_ialloc_ag_alloc( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *agbp, /* alloc group buffer */ int *alloc) { xfs_agi_t *agi; /* allocation group header */ xfs_alloc_arg_t args; /* allocation argument structure */ xfs_btree_cur_t *cur; /* inode btree cursor */ xfs_agnumber_t agno; int error; int i; xfs_agino_t newino; /* new first inode's number */ xfs_agino_t newlen; /* new number of inodes */ xfs_agino_t thisino; /* current inode number, for loop */ int isaligned = 0; /* inode allocation at stripe unit */ /* boundary */ struct xfs_perag *pag; args.tp = tp; args.mp = tp->t_mountp; /* * Locking will ensure that we don't have two callers in here * at one time. */ newlen = XFS_IALLOC_INODES(args.mp); if (args.mp->m_maxicount && args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount) return XFS_ERROR(ENOSPC); args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); /* * First try to allocate inodes contiguous with the last-allocated * chunk of inodes. If the filesystem is striped, this will fill * an entire stripe unit with inodes. */ agi = XFS_BUF_TO_AGI(agbp); newino = be32_to_cpu(agi->agi_newino); agno = be32_to_cpu(agi->agi_seqno); args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + XFS_IALLOC_BLOCKS(args.mp); if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); args.type = XFS_ALLOCTYPE_THIS_BNO; args.mod = args.total = args.wasdel = args.isfl = args.userdata = args.minalignslop = 0; args.prod = 1; /* * We need to take into account alignment here to ensure that * we don't modify the free list if we fail to have an exact * block. If we don't have an exact match, and every oher * attempt allocation attempt fails, we'll end up cancelling * a dirty transaction and shutting down. * * For an exact allocation, alignment must be 1, * however we need to take cluster alignment into account when * fixing up the freelist. Use the minalignslop field to * indicate that extra blocks might be required for alignment, * but not to use them in the actual exact allocation. */ args.alignment = 1; args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1; /* Allow space for the inode btree to split. */ args.minleft = args.mp->m_in_maxlevels - 1; if ((error = xfs_alloc_vextent(&args))) return error; } else args.fsbno = NULLFSBLOCK; if (unlikely(args.fsbno == NULLFSBLOCK)) { /* * Set the alignment for the allocation. * If stripe alignment is turned on then align at stripe unit * boundary. * If the cluster size is smaller than a filesystem block * then we're doing I/O for inodes in filesystem block size * pieces, so don't need alignment anyway. */ isaligned = 0; if (args.mp->m_sinoalign) { ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); args.alignment = args.mp->m_dalign; isaligned = 1; } else args.alignment = xfs_ialloc_cluster_alignment(&args); /* * Need to figure out where to allocate the inode blocks. * Ideally they should be spaced out through the a.g. * For now, just allocate blocks up front. */ args.agbno = be32_to_cpu(agi->agi_root); args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); /* * Allocate a fixed-size extent of inodes. */ args.type = XFS_ALLOCTYPE_NEAR_BNO; args.mod = args.total = args.wasdel = args.isfl = args.userdata = args.minalignslop = 0; args.prod = 1; /* * Allow space for the inode btree to split. */ args.minleft = args.mp->m_in_maxlevels - 1; if ((error = xfs_alloc_vextent(&args))) return error; } /* * If stripe alignment is turned on, then try again with cluster * alignment. */ if (isaligned && args.fsbno == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.agbno = be32_to_cpu(agi->agi_root); args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); args.alignment = xfs_ialloc_cluster_alignment(&args); if ((error = xfs_alloc_vextent(&args))) return error; } if (args.fsbno == NULLFSBLOCK) { *alloc = 0; return 0; } ASSERT(args.len == args.minlen); /* * Stamp and write the inode buffers. * * Seed the new inode cluster with a random generation number. This * prevents short-term reuse of generation numbers if a chunk is * freed and then immediately reallocated. We use random numbers * rather than a linear progression to prevent the next generation * number from being easily guessable. */ xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len, random32()); /* * Convert the results. */ newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); be32_add_cpu(&agi->agi_count, newlen); be32_add_cpu(&agi->agi_freecount, newlen); pag = xfs_perag_get(args.mp, agno); pag->pagi_freecount += newlen; xfs_perag_put(pag); agi->agi_newino = cpu_to_be32(newino); /* * Insert records describing the new inode chunk into the btree. */ cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno); for (thisino = newino; thisino < newino + newlen; thisino += XFS_INODES_PER_CHUNK) { cur->bc_rec.i.ir_startino = thisino; cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK; cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE; error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i); if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } ASSERT(i == 0); error = xfs_btree_insert(cur, &i); if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } ASSERT(i == 1); } xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); /* * Log allocation group header fields */ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT | XFS_AGI_NEWINO); /* * Modify/log superblock values for inode count and inode free count. */ xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, (long)newlen); xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, (long)newlen); *alloc = 1; return 0; } STATIC xfs_agnumber_t xfs_ialloc_next_ag( xfs_mount_t *mp) { xfs_agnumber_t agno; spin_lock(&mp->m_agirotor_lock); agno = mp->m_agirotor; if (++mp->m_agirotor == mp->m_maxagi) mp->m_agirotor = 0; spin_unlock(&mp->m_agirotor_lock); return agno; } /* * Select an allocation group to look for a free inode in, based on the parent * inode and then mode. Return the allocation group buffer. */ STATIC xfs_buf_t * /* allocation group buffer */ xfs_ialloc_ag_select( xfs_trans_t *tp, /* transaction pointer */ xfs_ino_t parent, /* parent directory inode number */ mode_t mode, /* bits set to indicate file type */ int okalloc) /* ok to allocate more space */ { xfs_buf_t *agbp; /* allocation group header buffer */ xfs_agnumber_t agcount; /* number of ag's in the filesystem */ xfs_agnumber_t agno; /* current ag number */ int flags; /* alloc buffer locking flags */ xfs_extlen_t ineed; /* blocks needed for inode allocation */ xfs_extlen_t longest = 0; /* longest extent available */ xfs_mount_t *mp; /* mount point structure */ int needspace; /* file mode implies space allocated */ xfs_perag_t *pag; /* per allocation group data */ xfs_agnumber_t pagno; /* parent (starting) ag number */ /* * Files of these types need at least one block if length > 0 * (and they won't fit in the inode, but that's hard to figure out). */ needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode); mp = tp->t_mountp; agcount = mp->m_maxagi; if (S_ISDIR(mode)) pagno = xfs_ialloc_next_ag(mp); else { pagno = XFS_INO_TO_AGNO(mp, parent); if (pagno >= agcount) pagno = 0; } ASSERT(pagno < agcount); /* * Loop through allocation groups, looking for one with a little * free space in it. Note we don't look for free inodes, exactly. * Instead, we include whether there is a need to allocate inodes * to mean that blocks must be allocated for them, * if none are currently free. */ agno = pagno; flags = XFS_ALLOC_FLAG_TRYLOCK; for (;;) { pag = xfs_perag_get(mp, agno); if (!pag->pagi_init) { if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { agbp = NULL; goto nextag; } } else agbp = NULL; if (!pag->pagi_inodeok) { xfs_ialloc_next_ag(mp); goto unlock_nextag; } /* * Is there enough free space for the file plus a block * of inodes (if we need to allocate some)? */ ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp); if (ineed && !pag->pagf_init) { if (agbp == NULL && xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { agbp = NULL; goto nextag; } (void)xfs_alloc_pagf_init(mp, tp, agno, flags); } if (!ineed || pag->pagf_init) { if (ineed && !(longest = pag->pagf_longest)) longest = pag->pagf_flcount > 0; if (!ineed || (pag->pagf_freeblks >= needspace + ineed && longest >= ineed && okalloc)) { if (agbp == NULL && xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { agbp = NULL; goto nextag; } xfs_perag_put(pag); return agbp; } } unlock_nextag: if (agbp) xfs_trans_brelse(tp, agbp); nextag: xfs_perag_put(pag); /* * No point in iterating over the rest, if we're shutting * down. */ if (XFS_FORCED_SHUTDOWN(mp)) return NULL; agno++; if (agno >= agcount) agno = 0; if (agno == pagno) { if (flags == 0) return NULL; flags = 0; } } } /* * Try to retrieve the next record to the left/right from the current one. */ STATIC int xfs_ialloc_next_rec( struct xfs_btree_cur *cur, xfs_inobt_rec_incore_t *rec, int *done, int left) { int error; int i; if (left) error = xfs_btree_decrement(cur, 0, &i); else error = xfs_btree_increment(cur, 0, &i); if (error) return error; *done = !i; if (i) { error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } return 0; } STATIC int xfs_ialloc_get_rec( struct xfs_btree_cur *cur, xfs_agino_t agino, xfs_inobt_rec_incore_t *rec, int *done, int left) { int error; int i; error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i); if (error) return error; *done = !i; if (i) { error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } return 0; } /* * Visible inode allocation functions. */ /* * Allocate an inode on disk. * Mode is used to tell whether the new inode will need space, and whether * it is a directory. * * The arguments IO_agbp and alloc_done are defined to work within * the constraint of one allocation per transaction. * xfs_dialloc() is designed to be called twice if it has to do an * allocation to make more free inodes. On the first call, * IO_agbp should be set to NULL. If an inode is available, * i.e., xfs_dialloc() did not need to do an allocation, an inode * number is returned. In this case, IO_agbp would be set to the * current ag_buf and alloc_done set to false. * If an allocation needed to be done, xfs_dialloc would return * the current ag_buf in IO_agbp and set alloc_done to true. * The caller should then commit the current transaction, allocate a new * transaction, and call xfs_dialloc() again, passing in the previous * value of IO_agbp. IO_agbp should be held across the transactions. * Since the agbp is locked across the two calls, the second call is * guaranteed to have a free inode available. * * Once we successfully pick an inode its number is returned and the * on-disk data structures are updated. The inode itself is not read * in, since doing so would break ordering constraints with xfs_reclaim. */ int xfs_dialloc( xfs_trans_t *tp, /* transaction pointer */ xfs_ino_t parent, /* parent inode (directory) */ mode_t mode, /* mode bits for new inode */ int okalloc, /* ok to allocate more space */ xfs_buf_t **IO_agbp, /* in/out ag header's buffer */ boolean_t *alloc_done, /* true if we needed to replenish inode freelist */ xfs_ino_t *inop) /* inode number allocated */ { xfs_agnumber_t agcount; /* number of allocation groups */ xfs_buf_t *agbp; /* allocation group header's buffer */ xfs_agnumber_t agno; /* allocation group number */ xfs_agi_t *agi; /* allocation group header structure */ xfs_btree_cur_t *cur; /* inode allocation btree cursor */ int error; /* error return value */ int i; /* result code */ int ialloced; /* inode allocation status */ int noroom = 0; /* no space for inode blk allocation */ xfs_ino_t ino; /* fs-relative inode to be returned */ /* REFERENCED */ int j; /* result code */ xfs_mount_t *mp; /* file system mount structure */ int offset; /* index of inode in chunk */ xfs_agino_t pagino; /* parent's AG relative inode # */ xfs_agnumber_t pagno; /* parent's AG number */ xfs_inobt_rec_incore_t rec; /* inode allocation record */ xfs_agnumber_t tagno; /* testing allocation group number */ xfs_btree_cur_t *tcur; /* temp cursor */ xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ struct xfs_perag *pag; if (*IO_agbp == NULL) { /* * We do not have an agbp, so select an initial allocation * group for inode allocation. */ agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc); /* * Couldn't find an allocation group satisfying the * criteria, give up. */ if (!agbp) { *inop = NULLFSINO; return 0; } agi = XFS_BUF_TO_AGI(agbp); ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); } else { /* * Continue where we left off before. In this case, we * know that the allocation group has free inodes. */ agbp = *IO_agbp; agi = XFS_BUF_TO_AGI(agbp); ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); ASSERT(be32_to_cpu(agi->agi_freecount) > 0); } mp = tp->t_mountp; agcount = mp->m_sb.sb_agcount; agno = be32_to_cpu(agi->agi_seqno); tagno = agno; pagno = XFS_INO_TO_AGNO(mp, parent); pagino = XFS_INO_TO_AGINO(mp, parent); /* * If we have already hit the ceiling of inode blocks then clear * okalloc so we scan all available agi structures for a free * inode. */ if (mp->m_maxicount && mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { noroom = 1; okalloc = 0; } /* * Loop until we find an allocation group that either has free inodes * or in which we can allocate some inodes. Iterate through the * allocation groups upward, wrapping at the end. */ *alloc_done = B_FALSE; while (!agi->agi_freecount) { /* * Don't do anything if we're not supposed to allocate * any blocks, just go on to the next ag. */ if (okalloc) { /* * Try to allocate some new inodes in the allocation * group. */ if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) { xfs_trans_brelse(tp, agbp); if (error == ENOSPC) { *inop = NULLFSINO; return 0; } else return error; } if (ialloced) { /* * We successfully allocated some inodes, return * the current context to the caller so that it * can commit the current transaction and call * us again where we left off. */ ASSERT(be32_to_cpu(agi->agi_freecount) > 0); *alloc_done = B_TRUE; *IO_agbp = agbp; *inop = NULLFSINO; return 0; } } /* * If it failed, give up on this ag. */ xfs_trans_brelse(tp, agbp); /* * Go on to the next ag: get its ag header. */ nextag: if (++tagno == agcount) tagno = 0; if (tagno == agno) { *inop = NULLFSINO; return noroom ? ENOSPC : 0; } pag = xfs_perag_get(mp, tagno); if (pag->pagi_inodeok == 0) { xfs_perag_put(pag); goto nextag; } error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); xfs_perag_put(pag); if (error) goto nextag; agi = XFS_BUF_TO_AGI(agbp); ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); } /* * Here with an allocation group that has a free inode. * Reset agno since we may have chosen a new ag in the * loop above. */ agno = tagno; *IO_agbp = NULL; pag = xfs_perag_get(mp, agno); restart_pagno: cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); /* * If pagino is 0 (this is the root inode allocation) use newino. * This must work because we've just allocated some. */ if (!pagino) pagino = be32_to_cpu(agi->agi_newino); error = xfs_check_agi_freecount(cur, agi); if (error) goto error0; /* * If in the same AG as the parent, try to get near the parent. */ if (pagno == agno) { int doneleft; /* done, to the left */ int doneright; /* done, to the right */ int searchdistance = 10; error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); error = xfs_inobt_get_rec(cur, &rec, &j); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if (rec.ir_freecount > 0) { /* * Found a free inode in the same chunk * as the parent, done. */ goto alloc_inode; } /* * In the same AG as parent, but parent's chunk is full. */ /* duplicate the cursor, search left & right simultaneously */ error = xfs_btree_dup_cursor(cur, &tcur); if (error) goto error0; /* * Skip to last blocks looked up if same parent inode. */ if (pagino != NULLAGINO && pag->pagl_pagino == pagino && pag->pagl_leftrec != NULLAGINO && pag->pagl_rightrec != NULLAGINO) { error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec, &trec, &doneleft, 1); if (error) goto error1; error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec, &rec, &doneright, 0); if (error) goto error1; } else { /* search left with tcur, back up 1 record */ error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1); if (error) goto error1; /* search right with cur, go forward 1 record. */ error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0); if (error) goto error1; } /* * Loop until we find an inode chunk with a free inode. */ while (!doneleft || !doneright) { int useleft; /* using left inode chunk this time */ if (!--searchdistance) { /* * Not in range - save last search * location and allocate a new inode */ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); pag->pagl_leftrec = trec.ir_startino; pag->pagl_rightrec = rec.ir_startino; pag->pagl_pagino = pagino; goto newino; } /* figure out the closer block if both are valid. */ if (!doneleft && !doneright) { useleft = pagino - (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) < rec.ir_startino - pagino; } else { useleft = !doneleft; } /* free inodes to the left? */ if (useleft && trec.ir_freecount) { rec = trec; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); cur = tcur; pag->pagl_leftrec = trec.ir_startino; pag->pagl_rightrec = rec.ir_startino; pag->pagl_pagino = pagino; goto alloc_inode; } /* free inodes to the right? */ if (!useleft && rec.ir_freecount) { xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); pag->pagl_leftrec = trec.ir_startino; pag->pagl_rightrec = rec.ir_startino; pag->pagl_pagino = pagino; goto alloc_inode; } /* get next record to check */ if (useleft) { error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1); } else { error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0); } if (error) goto error1; } /* * We've reached the end of the btree. because * we are only searching a small chunk of the * btree each search, there is obviously free * inodes closer to the parent inode than we * are now. restart the search again. */ pag->pagl_pagino = NULLAGINO; pag->pagl_leftrec = NULLAGINO; pag->pagl_rightrec = NULLAGINO; xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); goto restart_pagno; } /* * In a different AG from the parent. * See if the most recently allocated block has any free. */ newino: if (be32_to_cpu(agi->agi_newino) != NULLAGINO) { error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), XFS_LOOKUP_EQ, &i); if (error) goto error0; if (i == 1) { error = xfs_inobt_get_rec(cur, &rec, &j); if (error) goto error0; if (j == 1 && rec.ir_freecount > 0) { /* * The last chunk allocated in the group * still has a free inode. */ goto alloc_inode; } } } /* * None left in the last group, search the whole AG */ error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); for (;;) { error = xfs_inobt_get_rec(cur, &rec, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if (rec.ir_freecount > 0) break; error = xfs_btree_increment(cur, 0, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); } alloc_inode: offset = xfs_ialloc_find_free(&rec.ir_free); ASSERT(offset >= 0); ASSERT(offset < XFS_INODES_PER_CHUNK); ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % XFS_INODES_PER_CHUNK) == 0); ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset); rec.ir_free &= ~XFS_INOBT_MASK(offset); rec.ir_freecount--; error = xfs_inobt_update(cur, &rec); if (error) goto error0; be32_add_cpu(&agi->agi_freecount, -1); xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); pag->pagi_freecount--; error = xfs_check_agi_freecount(cur, agi); if (error) goto error0; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); xfs_perag_put(pag); *inop = ino; return 0; error1: xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); error0: xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); xfs_perag_put(pag); return error; } STATIC int xfs_imap_lookup( struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agino_t agino, xfs_agblock_t agbno, xfs_agblock_t *chunk_agbno, xfs_agblock_t *offset_agbno, int flags) { struct xfs_inobt_rec_incore rec; struct xfs_btree_cur *cur; struct xfs_buf *agbp; int error; int i; error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); if (error) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " "xfs_ialloc_read_agi() returned " "error %d, agno %d", error, agno); return error; } /* * Lookup the inode record for the given agino. If the record cannot be * found, then it's an invalid inode number and we should abort. Once * we have a record, we need to ensure it contains the inode number * we are looking up. */ cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); if (!error) { if (i) error = xfs_inobt_get_rec(cur, &rec, &i); if (!error && i == 0) error = EINVAL; } xfs_trans_brelse(tp, agbp); xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); if (error) return error; /* check that the returned record contains the required inode */ if (rec.ir_startino > agino || rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) return EINVAL; /* for untrusted inodes check it is allocated first */ if ((flags & XFS_IGET_UNTRUSTED) && (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) return EINVAL; *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino); *offset_agbno = agbno - *chunk_agbno; return 0; } /* * Return the location of the inode in imap, for mapping it into a buffer. */ int xfs_imap( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ uint flags) /* flags for inode btree lookup */ { xfs_agblock_t agbno; /* block number of inode in the alloc group */ xfs_agino_t agino; /* inode number within alloc group */ xfs_agnumber_t agno; /* allocation group number */ int blks_per_cluster; /* num blocks per inode cluster */ xfs_agblock_t chunk_agbno; /* first block in inode chunk */ xfs_agblock_t cluster_agbno; /* first block in inode cluster */ int error; /* error code */ int offset; /* index of inode in its buffer */ xfs_agblock_t offset_agbno; /* blks from chunk start to inode */ ASSERT(ino != NULLFSINO); /* * Split up the inode number into its parts. */ agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || ino != XFS_AGINO_TO_INO(mp, agno, agino)) { #ifdef DEBUG /* * Don't output diagnostic information for untrusted inodes * as they can be invalid without implying corruption. */ if (flags & XFS_IGET_UNTRUSTED) return XFS_ERROR(EINVAL); if (agno >= mp->m_sb.sb_agcount) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: agno (%d) >= " "mp->m_sb.sb_agcount (%d)", agno, mp->m_sb.sb_agcount); } if (agbno >= mp->m_sb.sb_agblocks) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: agbno (0x%llx) >= " "mp->m_sb.sb_agblocks (0x%lx)", (unsigned long long) agbno, (unsigned long) mp->m_sb.sb_agblocks); } if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: ino (0x%llx) != " "XFS_AGINO_TO_INO(mp, agno, agino) " "(0x%llx)", ino, XFS_AGINO_TO_INO(mp, agno, agino)); } xfs_stack_trace(); #endif /* DEBUG */ return XFS_ERROR(EINVAL); } blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; /* * For bulkstat and handle lookups, we have an untrusted inode number * that we have to verify is valid. We cannot do this just by reading * the inode buffer as it may have been unlinked and removed leaving * inodes in stale state on disk. Hence we have to do a btree lookup * in all cases where an untrusted inode number is passed. */ if (flags & XFS_IGET_UNTRUSTED) { error = xfs_imap_lookup(mp, tp, agno, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) return error; goto out_map; } /* * If the inode cluster size is the same as the blocksize or * smaller we get to the buffer by simple arithmetics. */ if (XFS_INODE_CLUSTER_SIZE(mp) <= mp->m_sb.sb_blocksize) { offset = XFS_INO_TO_OFFSET(mp, ino); ASSERT(offset < mp->m_sb.sb_inopblock); imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno); imap->im_len = XFS_FSB_TO_BB(mp, 1); imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); return 0; } /* * If the inode chunks are aligned then use simple maths to * find the location. Otherwise we have to do a btree * lookup to find the location. */ if (mp->m_inoalign_mask) { offset_agbno = agbno & mp->m_inoalign_mask; chunk_agbno = agbno - offset_agbno; } else { error = xfs_imap_lookup(mp, tp, agno, agino, agbno, &chunk_agbno, &offset_agbno, flags); if (error) return error; } out_map: ASSERT(agbno >= chunk_agbno); cluster_agbno = chunk_agbno + ((offset_agbno / blks_per_cluster) * blks_per_cluster); offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + XFS_INO_TO_OFFSET(mp, ino); imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno); imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); /* * If the inode number maps to a block outside the bounds * of the file system then return NULL rather than calling * read_buf and panicing when we get an error from the * driver. */ if ((imap->im_blkno + imap->im_len) > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", (unsigned long long) imap->im_blkno, (unsigned long long) imap->im_len, XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); return XFS_ERROR(EINVAL); } return 0; } /* * Compute and fill in value of m_in_maxlevels. */ void xfs_ialloc_compute_maxlevels( xfs_mount_t *mp) /* file system mount structure */ { int level; uint maxblocks; uint maxleafents; int minleafrecs; int minnoderecs; maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; minleafrecs = mp->m_alloc_mnr[0]; minnoderecs = mp->m_alloc_mnr[1]; maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; for (level = 1; maxblocks > 1; level++) maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; mp->m_in_maxlevels = level; } /* * Log specified fields for the ag hdr (inode section) */ void xfs_ialloc_log_agi( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *bp, /* allocation group header buffer */ int fields) /* bitmask of fields to log */ { int first; /* first byte number */ int last; /* last byte number */ static const short offsets[] = { /* field starting offsets */ /* keep in sync with bit definitions */ offsetof(xfs_agi_t, agi_magicnum), offsetof(xfs_agi_t, agi_versionnum), offsetof(xfs_agi_t, agi_seqno), offsetof(xfs_agi_t, agi_length), offsetof(xfs_agi_t, agi_count), offsetof(xfs_agi_t, agi_root), offsetof(xfs_agi_t, agi_level), offsetof(xfs_agi_t, agi_freecount), offsetof(xfs_agi_t, agi_newino), offsetof(xfs_agi_t, agi_dirino), offsetof(xfs_agi_t, agi_unlinked), sizeof(xfs_agi_t) }; #ifdef DEBUG xfs_agi_t *agi; /* allocation group header */ agi = XFS_BUF_TO_AGI(bp); ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); #endif /* * Compute byte offsets for the first and last fields. */ xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last); /* * Log the allocation group inode header buffer. */ xfs_trans_log_buf(tp, bp, first, last); } #ifdef DEBUG STATIC void xfs_check_agi_unlinked( struct xfs_agi *agi) { int i; for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) ASSERT(agi->agi_unlinked[i]); } #else #define xfs_check_agi_unlinked(agi) #endif /* * Read in the allocation group header (inode allocation section) */ int xfs_read_agi( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ struct xfs_buf **bpp) /* allocation group hdr buf */ { struct xfs_agi *agi; /* allocation group header */ int agi_ok; /* agi is consistent */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0, bpp); if (error) return error; ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp)); agi = XFS_BUF_TO_AGI(*bpp); /* * Validate the magic number of the agi block. */ agi_ok = be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) && be32_to_cpu(agi->agi_seqno) == agno; if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, XFS_RANDOM_IALLOC_READ_AGI))) { XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW, mp, agi); xfs_trans_brelse(tp, *bpp); return XFS_ERROR(EFSCORRUPTED); } XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGI, XFS_AGI_REF); xfs_check_agi_unlinked(agi); return 0; } int xfs_ialloc_read_agi( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ struct xfs_buf **bpp) /* allocation group hdr buf */ { struct xfs_agi *agi; /* allocation group header */ struct xfs_perag *pag; /* per allocation group data */ int error; error = xfs_read_agi(mp, tp, agno, bpp); if (error) return error; agi = XFS_BUF_TO_AGI(*bpp); pag = xfs_perag_get(mp, agno); if (!pag->pagi_init) { pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); pag->pagi_count = be32_to_cpu(agi->agi_count); pag->pagi_init = 1; } /* * It's possible for these to be out of sync if * we are in the middle of a forced shutdown. */ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || XFS_FORCED_SHUTDOWN(mp)); xfs_perag_put(pag); return 0; } /* * Read in the agi to initialise the per-ag data in the mount structure */ int xfs_ialloc_pagi_init( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ xfs_agnumber_t agno) /* allocation group number */ { xfs_buf_t *bp = NULL; int error; error = xfs_ialloc_read_agi(mp, tp, agno, &bp); if (error) return error; if (bp) xfs_trans_brelse(tp, bp); return 0; } xfsprogs-3.1.9ubuntu2/libxfs/util.c0000664000000000000000000004743711650373061014245 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include /* * Change the requested timestamp in the given inode. * * This was once shared with the kernel, but has diverged to the point * where it's no longer worth the hassle of maintaining common code. */ void libxfs_trans_ichgtime( struct xfs_trans *tp, struct xfs_inode *ip, int flags) { struct timespec tv; struct timeval stv; gettimeofday(&stv, (struct timezone *)0); tv.tv_sec = stv.tv_sec; tv.tv_nsec = stv.tv_usec * 1000; if (flags & XFS_ICHGTIME_MOD) { ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; } if (flags & XFS_ICHGTIME_CHG) { ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; } } /* * Given a mount structure and an inode number, return a pointer * to a newly allocated in-core inode coresponding to the given * inode number. * * Initialize the inode's attributes and extent pointers if it * already has them (it will not if the inode has no links). * * NOTE: this has slightly different behaviour to the kernel in * that this version requires the already allocated *ip being * passed in while the kernel version does the allocation and * returns it in **ip. */ int libxfs_iread( xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, xfs_inode_t *ip, xfs_daddr_t bno) { xfs_buf_t *bp; xfs_dinode_t *dip; int error; ip->i_ino = ino; ip->i_mount = mp; /* * Fill in the location information in the in-core inode. */ error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0); if (error) return error; /* * Get pointers to the on-disk inode and the buffer containing it. */ error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, XBF_LOCK, 0); if (error) return error; dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); /* * If we got something that isn't an inode it means someone * (nfs or dmi) has a stale handle. */ if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC) { xfs_trans_brelse(tp, bp); return EINVAL; } /* * If the on-disk inode is already linked to a directory * entry, copy all of the inode into the in-core inode. * xfs_iformat() handles copying in the inode format * specific information. * Otherwise, just get the truly permanent information. */ if (dip->di_mode) { xfs_dinode_from_disk(&ip->i_d, dip); error = xfs_iformat(ip, dip); if (error) { xfs_trans_brelse(tp, bp); return error; } } else { ip->i_d.di_magic = be16_to_cpu(dip->di_magic); ip->i_d.di_version = dip->di_version; ip->i_d.di_gen = be32_to_cpu(dip->di_gen); ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); /* * Make sure to pull in the mode here as well in * case the inode is released without being used. * This ensures that xfs_inactive() will see that * the inode is already free and not try to mess * with the uninitialized part of it. */ ip->i_d.di_mode = 0; /* * Initialize the per-fork minima and maxima for a new * inode here. xfs_iformat will do it for old inodes. */ ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); } /* * The inode format changed when we moved the link count and * made it 32 bits long. If this is an old format inode, * convert it in memory to look like a new one. If it gets * flushed to disk we will convert back before flushing or * logging it. We zero out the new projid_lo/hi field and the old link * count field. We'll handle clearing the pad field (the remains * of the old uuid field) when we actually convert the inode to * the new format. We don't change the version number so that we * can distinguish this from a real new format inode. */ if (ip->i_d.di_version == 1) { ip->i_d.di_nlink = ip->i_d.di_onlink; ip->i_d.di_onlink = 0; xfs_set_projid(&ip->i_d, 0); } ip->i_delayed_blks = 0; ip->i_size = ip->i_d.di_size; /* * Use xfs_trans_brelse() to release the buffer containing the * on-disk inode, because it was acquired with xfs_trans_read_buf() * in xfs_itobp() above. If tp is NULL, this is just a normal * brelse(). If we're within a transaction, then xfs_trans_brelse() * will only release the buffer if it is not dirty within the * transaction. It will be OK to release the buffer in this case, * because inodes on disk are never destroyed and we will be * locking the new in-core inode before putting it in the hash * table where other processes can find it. Thus we don't have * to worry about the inode being changed just because we released * the buffer. */ xfs_trans_brelse(tp, bp); return 0; } /* * Allocate an inode on disk and return a copy of its in-core version. * Set mode, nlink, and rdev appropriately within the inode. * The uid and gid for the inode are set according to the contents of * the given cred structure. * * This was once shared with the kernel, but has diverged to the point * where it's no longer worth the hassle of maintaining common code. */ int libxfs_ialloc( xfs_trans_t *tp, xfs_inode_t *pip, mode_t mode, nlink_t nlink, xfs_dev_t rdev, struct cred *cr, struct fsxattr *fsx, int okalloc, xfs_buf_t **ialloc_context, boolean_t *call_again, xfs_inode_t **ipp) { xfs_ino_t ino; xfs_inode_t *ip; uint flags; int error; /* * Call the space management code to pick * the on-disk inode to be allocated. */ error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, ialloc_context, call_again, &ino); if (error != 0) return error; if (*call_again || ino == NULLFSINO) { *ipp = NULL; return 0; } ASSERT(*ialloc_context == NULL); error = xfs_trans_iget(tp->t_mountp, tp, ino, 0, 0, &ip); if (error != 0) return error; ASSERT(ip != NULL); ip->i_d.di_mode = (__uint16_t)mode; ip->i_d.di_onlink = 0; ip->i_d.di_nlink = nlink; ASSERT(ip->i_d.di_nlink == nlink); ip->i_d.di_uid = cr->cr_uid; ip->i_d.di_gid = cr->cr_gid; xfs_set_projid(&ip->i_d, pip ? 0 : fsx->fsx_projid); memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); /* * If the superblock version is up to where we support new format * inodes and this is currently an old format inode, then change * the inode version number now. This way we only do the conversion * here rather than here and in the flush/logging code. */ if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) && ip->i_d.di_version == 1) { ip->i_d.di_version = 2; /* * old link count, projid_lo/hi field, pad field * already zeroed */ } if (pip && (pip->i_d.di_mode & S_ISGID)) { ip->i_d.di_gid = pip->i_d.di_gid; if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) ip->i_d.di_mode |= S_ISGID; } ip->i_d.di_size = 0; ip->i_d.di_nextents = 0; ASSERT(ip->i_d.di_nblocks == 0); xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_MOD); /* * di_gen will have been taken care of in xfs_iread. */ ip->i_d.di_extsize = pip ? 0 : fsx->fsx_extsize; ip->i_d.di_dmevmask = 0; ip->i_d.di_dmstate = 0; ip->i_d.di_flags = pip ? 0 : fsx->fsx_xflags; flags = XFS_ILOG_CORE; switch (mode & S_IFMT) { case S_IFIFO: case S_IFSOCK: /* doesn't make sense to set an rdev for these */ rdev = 0; case S_IFCHR: case S_IFBLK: ip->i_d.di_format = XFS_DINODE_FMT_DEV; ip->i_df.if_u2.if_rdev = rdev; flags |= XFS_ILOG_DEV; break; case S_IFREG: case S_IFDIR: if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { uint di_flags = 0; if ((mode & S_IFMT) == S_IFDIR) { if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_RTINHERIT; if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { di_flags |= XFS_DIFLAG_EXTSZINHERIT; ip->i_d.di_extsize = pip->i_d.di_extsize; } } else { if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { di_flags |= XFS_DIFLAG_REALTIME; } if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { di_flags |= XFS_DIFLAG_EXTSIZE; ip->i_d.di_extsize = pip->i_d.di_extsize; } } if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) di_flags |= XFS_DIFLAG_PROJINHERIT; ip->i_d.di_flags |= di_flags; } /* FALLTHROUGH */ case S_IFLNK: ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_df.if_flags = XFS_IFEXTENTS; ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; ip->i_df.if_u1.if_extents = NULL; break; default: ASSERT(0); } /* Attribute fork settings for new inode. */ ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_anextents = 0; /* * Log the new values stuffed into the inode. */ xfs_trans_log_inode(tp, ip, flags); *ipp = ip; return 0; } void libxfs_iprint( xfs_inode_t *ip) { xfs_icdinode_t *dip; xfs_bmbt_rec_host_t *ep; xfs_extnum_t i; xfs_extnum_t nextents; printf("Inode %lx\n", (unsigned long)ip); printf(" i_ino %llx\n", (unsigned long long)ip->i_ino); if (ip->i_df.if_flags & XFS_IFEXTENTS) printf("EXTENTS "); printf("\n"); printf(" i_df.if_bytes %d\n", ip->i_df.if_bytes); printf(" i_df.if_u1.if_extents/if_data %lx\n", (unsigned long)ip->i_df.if_u1.if_extents); if (ip->i_df.if_flags & XFS_IFEXTENTS) { nextents = ip->i_df.if_bytes / (uint)sizeof(*ep); for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents; i++, ep++) { xfs_bmbt_irec_t rec; xfs_bmbt_get_all(ep, &rec); printf("\t%d: startoff %llu, startblock 0x%llx," " blockcount %llu, state %d\n", i, (unsigned long long)rec.br_startoff, (unsigned long long)rec.br_startblock, (unsigned long long)rec.br_blockcount, (int)rec.br_state); } } printf(" i_df.if_broot %lx\n", (unsigned long)ip->i_df.if_broot); printf(" i_df.if_broot_bytes %x\n", ip->i_df.if_broot_bytes); dip = &ip->i_d; printf("\nOn disk portion\n"); printf(" di_magic %x\n", dip->di_magic); printf(" di_mode %o\n", dip->di_mode); printf(" di_version %x\n", (uint)dip->di_version); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: printf(" Inline inode\n"); break; case XFS_DINODE_FMT_EXTENTS: printf(" Extents inode\n"); break; case XFS_DINODE_FMT_BTREE: printf(" B-tree inode\n"); break; default: printf(" Other inode\n"); break; } printf(" di_nlink %x\n", dip->di_nlink); printf(" di_uid %d\n", dip->di_uid); printf(" di_gid %d\n", dip->di_gid); printf(" di_nextents %d\n", dip->di_nextents); printf(" di_size %llu\n", (unsigned long long)dip->di_size); printf(" di_gen %x\n", dip->di_gen); printf(" di_extsize %d\n", dip->di_extsize); printf(" di_flags %x\n", dip->di_flags); printf(" di_nblocks %llu\n", (unsigned long long)dip->di_nblocks); } /* * Writes a modified inode's changes out to the inode's on disk home. * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel. */ int libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp) { xfs_inode_log_item_t *iip; xfs_dinode_t *dip; xfs_mount_t *mp; ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || ip->i_d.di_nextents > ip->i_df.if_ext_max); iip = ip->i_itemp; mp = ip->i_mount; /* set *dip = inode's place in the buffer */ dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); ASSERT(ip->i_d.di_magic == XFS_DINODE_MAGIC); if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) || (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) ); } else if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { ASSERT( (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS) || (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) || (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) ); } ASSERT(ip->i_d.di_nextents+ip->i_d.di_anextents <= ip->i_d.di_nblocks); ASSERT(ip->i_d.di_forkoff <= mp->m_sb.sb_inodesize); /* * Copy the dirty parts of the inode into the on-disk * inode. We always copy out the core of the inode, * because if the inode is dirty at all the core must * be. */ xfs_dinode_to_disk(dip, &ip->i_d); /* * If this is really an old format inode and the superblock version * has not been updated to support only new format inodes, then * convert back to the old inode format. If the superblock version * has been updated, then make the conversion permanent. */ ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); if (ip->i_d.di_version == 1) { if (!xfs_sb_version_hasnlink(&mp->m_sb)) { /* * Convert it back. */ ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); dip->di_onlink = cpu_to_be16(ip->i_d.di_nlink); } else { /* * The superblock version has already been bumped, * so just make the conversion to the new inode * format permanent. */ ip->i_d.di_version = 2; dip->di_version = 2; ip->i_d.di_onlink = 0; dip->di_onlink = 0; memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); memset(&(dip->di_pad[0]), 0, sizeof(dip->di_pad)); ASSERT(xfs_get_projid(ip->i_d) == 0); } } xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp); if (XFS_IFORK_Q(ip)) xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp); return 0; } /* * Utility routine common used to apply a delta to a field in the * in-core superblock. * Switch on the field indicated and apply the delta to that field. * Fields are not allowed to dip below zero, so if the delta would * do this do not apply it and return EINVAL. * * Originally derived from xfs_mod_incore_sb_unlocked(). */ int libxfs_mod_incore_sb( xfs_mount_t *mp, xfs_sb_field_t field, int64_t delta, int rsvd) { long long lcounter; /* long counter for 64 bit fields */ switch (field) { case XFS_SBS_FDBLOCKS: lcounter = (long long)mp->m_sb.sb_fdblocks; lcounter += delta; if (lcounter < 0) return XFS_ERROR(ENOSPC); mp->m_sb.sb_fdblocks = lcounter; return 0; default: ASSERT(0); return XFS_ERROR(EINVAL); } } int libxfs_bmap_finish( xfs_trans_t **tp, xfs_bmap_free_t *flist, int *committed) { xfs_bmap_free_item_t *free; /* free extent list item */ xfs_bmap_free_item_t *next; /* next item on free list */ int error; if (flist->xbf_count == 0) { *committed = 0; return 0; } for (free = flist->xbf_first; free != NULL; free = next) { next = free->xbfi_next; if ((error = xfs_free_extent(*tp, free->xbfi_startblock, free->xbfi_blockcount))) return error; xfs_bmap_del_free(flist, NULL, free); } *committed = 0; return 0; } /* * This routine allocates disk space for the given file. * Originally derived from xfs_alloc_file_space(). */ int libxfs_alloc_file_space( xfs_inode_t *ip, xfs_off_t offset, xfs_off_t len, int alloc_type, int attr_flags) { xfs_mount_t *mp; xfs_off_t count; xfs_filblks_t datablocks; xfs_filblks_t allocated_fsb; xfs_filblks_t allocatesize_fsb; xfs_fsblock_t firstfsb; xfs_bmap_free_t free_list; xfs_bmbt_irec_t *imapp; xfs_bmbt_irec_t imaps[1]; int reccount; uint resblks; xfs_fileoff_t startoffset_fsb; xfs_trans_t *tp; int xfs_bmapi_flags; int committed; int error; if (len <= 0) return EINVAL; count = len; error = 0; imapp = &imaps[0]; reccount = 1; xfs_bmapi_flags = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0); mp = ip->i_mount; startoffset_fsb = XFS_B_TO_FSBT(mp, offset); allocatesize_fsb = XFS_B_TO_FSB(mp, count); /* allocate file space until done or until there is an error */ while (allocatesize_fsb && !error) { datablocks = allocatesize_fsb; tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); resblks = (uint)XFS_DIOSTRAT_SPACE_RES(mp, datablocks); error = xfs_trans_reserve(tp, resblks, 0, 0, 0, 0); if (error) break; xfs_trans_ijoin(tp, ip, 0); xfs_trans_ihold(tp, ip); xfs_bmap_init(&free_list, &firstfsb); error = xfs_bmapi(tp, ip, startoffset_fsb, allocatesize_fsb, xfs_bmapi_flags, &firstfsb, 0, imapp, &reccount, &free_list); if (error) break; /* complete the transaction */ error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) break; error = xfs_trans_commit(tp, 0); if (error) break; allocated_fsb = imapp->br_blockcount; if (reccount == 0) return ENOSPC; startoffset_fsb += allocated_fsb; allocatesize_fsb -= allocated_fsb; } return error; } unsigned int libxfs_log2_roundup(unsigned int i) { unsigned int rval; for (rval = 0; rval < NBBY * sizeof(i); rval++) { if ((1 << rval) >= i) break; } return rval; } /* * Get a buffer for the dir/attr block, fill in the contents. * Don't check magic number, the caller will (it's xfs_repair). * * Originally from xfs_da_btree.c in the kernel, but only used * in userspace so it now resides here. */ int libxfs_da_read_bufr( xfs_trans_t *trans, xfs_inode_t *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dabuf_t **bpp, int whichfork) { return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 2, (inst_t *)__return_address); } /* * Hold dabuf at transaction commit. * * Originally from xfs_da_btree.c in the kernel, but only used * in userspace so it now resides here. */ void libxfs_da_bhold(xfs_trans_t *tp, xfs_dabuf_t *dabuf) { int i; for (i = 0; i < dabuf->nbuf; i++) xfs_trans_bhold(tp, dabuf->bps[i]); } /* * Join dabuf to transaction. * * Originally from xfs_da_btree.c in the kernel, but only used * in userspace so it now resides here. */ void libxfs_da_bjoin(xfs_trans_t *tp, xfs_dabuf_t *dabuf) { int i; for (i = 0; i < dabuf->nbuf; i++) xfs_trans_bjoin(tp, dabuf->bps[i]); } /* * Wrapper around call to libxfs_ialloc. Takes care of committing and * allocating a new transaction as needed. * * Originally there were two copies of this code - one in mkfs, the * other in repair - now there is just the one. */ int libxfs_inode_alloc( xfs_trans_t **tp, xfs_inode_t *pip, mode_t mode, nlink_t nlink, xfs_dev_t rdev, struct cred *cr, struct fsxattr *fsx, xfs_inode_t **ipp) { boolean_t call_again; int i; xfs_buf_t *ialloc_context; xfs_inode_t *ip; xfs_trans_t *ntp; int error; call_again = B_FALSE; ialloc_context = (xfs_buf_t *)0; error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx, 1, &ialloc_context, &call_again, &ip); if (error) return error; if (call_again) { xfs_trans_bhold(*tp, ialloc_context); ntp = xfs_trans_dup(*tp); xfs_trans_commit(*tp, 0); *tp = ntp; if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) { fprintf(stderr, _("%s: cannot reserve space: %s\n"), progname, strerror(i)); exit(1); } xfs_trans_bjoin(*tp, ialloc_context); error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx, 1, &ialloc_context, &call_again, &ip); if (!ip) error = ENOSPC; if (error) return error; } if (!ip) error = ENOSPC; *ipp = ip; return error; } /* * Userspace versions of common diagnostic routines (varargs fun). */ void libxfs_fs_repair_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, " This is a bug.\n"); fprintf(stderr, "Please capture the filesystem metadata with " "xfs_metadump and\nreport it to xfs@oss.sgi.com.\n"); va_end(ap); } void libxfs_fs_cmn_err(int level, xfs_mount_t *mp, char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fputs("\n", stderr); va_end(ap); } void cmn_err(int level, char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fputs("\n", stderr); va_end(ap); } xfsprogs-3.1.9ubuntu2/libxfs/Makefile0000664000000000000000000000223511650373061014547 0ustar # # Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTLIBRARY = libxfs.la LT_CURRENT = 0 LT_REVISION = 0 LT_AGE = 0 HFILES = xfs.h init.h CFILES = cache.c init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ xfs_alloc.c xfs_ialloc.c xfs_inode.c xfs_btree.c xfs_alloc_btree.c \ xfs_ialloc_btree.c xfs_bmap_btree.c xfs_da_btree.c \ xfs_dir2.c xfs_dir2_leaf.c xfs_attr_leaf.c xfs_dir2_block.c \ xfs_dir2_node.c xfs_dir2_data.c xfs_dir2_sf.c xfs_bmap.c \ xfs_mount.c xfs_rtalloc.c xfs_trans.c xfs_attr.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c LSRCFILES = $(shell echo $(PCFILES) | sed -e "s/$(PKG_PLATFORM).c//g") # # Tracing flags: # -DIO_DEBUG reads and writes of buffers # -DMEM_DEBUG all zone memory use # -DLI_DEBUG log item (ino/buf) manipulation # -DXACT_DEBUG transaction state changes # #LCFLAGS += FCFLAGS = -I. LTLIBS = $(LIBPTHREAD) $(LIBRT) # don't try linking xfs_repair with a debug libxfs. DEBUG = -DNDEBUG default: ltdepend $(LTLIBRARY) include $(BUILDRULES) install: default install-dev: default install-qa: default -include .ltdep xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_node.c0000664000000000000000000016567711650373061016024 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Function declarations. */ static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp); static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index); #ifdef DEBUG static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp); #else #define xfs_dir2_leafn_check(dp, bp) #endif static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s, int start_s, xfs_dabuf_t *bp_d, int start_d, int count); static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2); static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp, int index, xfs_da_state_blk_t *dblk, int *rval); static int xfs_dir2_node_addname_int(xfs_da_args_t *args, xfs_da_state_blk_t *fblk); /* * Log entries from a freespace block. */ STATIC void xfs_dir2_free_log_bests( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* freespace buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { xfs_dir2_free_t *free; /* freespace structure */ free = bp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&free->bests[first] - (char *)free), (uint)((char *)&free->bests[last] - (char *)free + sizeof(free->bests[0]) - 1)); } /* * Log header from a freespace block. */ static void xfs_dir2_free_log_header( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* freespace buffer */ { xfs_dir2_free_t *free; /* freespace structure */ free = bp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); } /* * Convert a leaf-format directory to a node-format directory. * We need to change the magic number of the leaf block, and copy * the freespace table out of the leaf block into its own block. */ int /* error */ xfs_dir2_leaf_to_node( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *lbp) /* leaf buffer */ { xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ xfs_dabuf_t *fbp; /* freespace buffer */ xfs_dir2_db_t fdb; /* freespace block number */ xfs_dir2_free_t *free; /* freespace structure */ __be16 *from; /* pointer to freespace entry */ int i; /* leaf freespace index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ int n; /* count of live freespc ents */ xfs_dir2_data_off_t off; /* freespace entry value */ __be16 *to; /* pointer to freespace entry */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leaf_to_node(args); dp = args->dp; mp = dp->i_mount; tp = args->trans; /* * Add a freespace block to the directory. */ if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) { return error; } ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); /* * Get the buffer for the new freespace block. */ if ((error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, XFS_DATA_FORK))) { return error; } ASSERT(fbp != NULL); free = fbp->data; leaf = lbp->data; ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * Initialize the freespace block header. */ free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); free->hdr.firstdb = 0; ASSERT(be32_to_cpu(ltp->bestcount) <= (uint)dp->i_d.di_size / mp->m_dirblksize); free->hdr.nvalid = ltp->bestcount; /* * Copy freespace entries from the leaf block to the new block. * Count active entries. */ for (i = n = 0, from = xfs_dir2_leaf_bests_p(ltp), to = free->bests; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { if ((off = be16_to_cpu(*from)) != NULLDATAOFF) n++; *to = cpu_to_be16(off); } free->hdr.nused = cpu_to_be32(n); leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); /* * Log everything. */ xfs_dir2_leaf_log_header(tp, lbp); xfs_dir2_free_log_header(tp, fbp); xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1); xfs_da_buf_done(fbp); xfs_dir2_leafn_check(dp, lbp); return 0; } /* * Add a leaf entry to a leaf block in a node-form directory. * The other work necessary is done from the caller. */ static int /* error */ xfs_dir2_leafn_add( xfs_dabuf_t *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int index) /* insertion pt for new entry */ { int compact; /* compacting stale leaves */ xfs_inode_t *dp; /* incore directory inode */ int highstale; /* next stale entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ int lfloghigh; /* high leaf entry logging */ int lfloglow; /* low leaf entry logging */ int lowstale; /* previous stale entry */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leafn_add(args, index); dp = args->dp; mp = dp->i_mount; tp = args->trans; leaf = bp->data; /* * Quick check just to make sure we are not going to index * into other peoples memory */ if (index < 0) return XFS_ERROR(EFSCORRUPTED); /* * If there are already the maximum number of leaf entries in * the block, if there are no stale entries it won't fit. * Caller will do a split. If there are stale entries we'll do * a compact. */ if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) { if (!leaf->hdr.stale) return XFS_ERROR(ENOSPC); compact = be16_to_cpu(leaf->hdr.stale) > 1; } else compact = 0; ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval); ASSERT(index == be16_to_cpu(leaf->hdr.count) || be32_to_cpu(leaf->ents[index].hashval) >= args->hashval); if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; /* * Compact out all but one stale leaf entry. Leaves behind * the entry closest to index. */ if (compact) { xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale, &lfloglow, &lfloghigh); } /* * Set impossible logging indices for this case. */ else if (leaf->hdr.stale) { lfloglow = be16_to_cpu(leaf->hdr.count); lfloghigh = -1; } /* * No stale entries, just insert a space for the new entry. */ if (!leaf->hdr.stale) { lep = &leaf->ents[index]; if (index < be16_to_cpu(leaf->hdr.count)) memmove(lep + 1, lep, (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); lfloglow = index; lfloghigh = be16_to_cpu(leaf->hdr.count); be16_add_cpu(&leaf->hdr.count, 1); } /* * There are stale entries. We'll use one for the new entry. */ else { /* * If we didn't do a compact then we need to figure out * which stale entry will be used. */ if (compact == 0) { /* * Find first stale entry before our insertion point. */ for (lowstale = index - 1; lowstale >= 0 && be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; /* * Find next stale entry after insertion point. * Stop looking if the answer would be worse than * lowstale already found. */ for (highstale = index; highstale < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale - 1 >= highstale - index); highstale++) continue; } /* * Using the low stale entry. * Shift entries up toward the stale slot. */ if (lowstale >= 0 && (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale - 1 < highstale - index)) { ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == XFS_DIR2_NULL_DATAPTR); ASSERT(index - lowstale - 1 >= 0); if (index - lowstale - 1 > 0) memmove(&leaf->ents[lowstale], &leaf->ents[lowstale + 1], (index - lowstale - 1) * sizeof(*lep)); lep = &leaf->ents[index - 1]; lfloglow = MIN(lowstale, lfloglow); lfloghigh = MAX(index - 1, lfloghigh); } /* * Using the high stale entry. * Shift entries down toward the stale slot. */ else { ASSERT(be32_to_cpu(leaf->ents[highstale].address) == XFS_DIR2_NULL_DATAPTR); ASSERT(highstale - index >= 0); if (highstale - index > 0) memmove(&leaf->ents[index + 1], &leaf->ents[index], (highstale - index) * sizeof(*lep)); lep = &leaf->ents[index]; lfloglow = MIN(index, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } be16_add_cpu(&leaf->hdr.stale, -1); } /* * Insert the new entry, log everything. */ lep->hashval = cpu_to_be32(args->hashval); lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, args->blkno, args->index)); xfs_dir2_leaf_log_header(tp, bp); xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); xfs_dir2_leafn_check(dp, bp); return 0; } #ifdef DEBUG /* * Check internal consistency of a leafn block. */ void xfs_dir2_leafn_check( xfs_inode_t *dp, /* incore directory inode */ xfs_dabuf_t *bp) /* leaf buffer */ { int i; /* leaf index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_mount_t *mp; /* filesystem mount point */ int stale; /* count of stale leaves */ leaf = bp->data; mp = dp->i_mount; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if (i + 1 < be16_to_cpu(leaf->hdr.count)) { ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= be32_to_cpu(leaf->ents[i + 1].hashval)); } if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); } #endif /* DEBUG */ /* * Return the last hash value in the leaf. * Stale entries are ok. */ xfs_dahash_t /* hash value */ xfs_dir2_leafn_lasthash( xfs_dabuf_t *bp, /* leaf buffer */ int *count) /* count of entries in leaf */ { xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); if (count) *count = be16_to_cpu(leaf->hdr.count); if (!leaf->hdr.count) return 0; return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval); } /* * Look up a leaf entry for space to add a name in a node-format leaf block. * The extrablk in state is a freespace block. */ STATIC int xfs_dir2_leafn_lookup_for_addname( xfs_dabuf_t *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_db_t curfdb = -1; /* current free block number */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ int fi; /* free entry index */ xfs_dir2_free_t *free = NULL; /* free block structure */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int length; /* length of new data entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_dir2_db_t newfdb; /* new free block number */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; tp = args->trans; mp = dp->i_mount; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); #ifdef __KERNEL__ ASSERT(be16_to_cpu(leaf->hdr.count) > 0); #endif xfs_dir2_leafn_check(dp, bp); /* * Look up the hash value in the leaf entries. */ index = xfs_dir2_leaf_search_hash(args, bp); /* * Do we have a buffer coming in? */ if (state->extravalid) { /* If so, it's a free block buffer, get the block number. */ curbp = state->extrablk.bp; curfdb = state->extrablk.blkno; free = curbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); } length = xfs_dir2_data_entsize(args->namelen); /* * Loop over leaf entries with the right hash value. */ for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* * Skip stale leaf entries. */ if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Pull the data block number from the entry. */ newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); /* * For addname, we're looking for a place to put the new entry. * We want to use a data block with an entry of equal * hash value to ours if there is one with room. * * If this block isn't the data block we already have * in hand, take a look at it. */ if (newdb != curdb) { curdb = newdb; /* * Convert the data block to the free block * holding its freespace information. */ newfdb = xfs_dir2_db_to_fdb(mp, newdb); /* * If it's not the one we have in hand, read it in. */ if (newfdb != curfdb) { /* * If we had one before, drop it. */ if (curbp) xfs_da_brelse(tp, curbp); /* * Read the free block. */ error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, newfdb), -1, &curbp, XFS_DATA_FORK); if (error) return error; free = curbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); ASSERT((be32_to_cpu(free->hdr.firstdb) % XFS_DIR2_MAX_FREE_BESTS(mp)) == 0); ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb); ASSERT(curdb < be32_to_cpu(free->hdr.firstdb) + be32_to_cpu(free->hdr.nvalid)); } /* * Get the index for our entry. */ fi = xfs_dir2_db_to_fdindex(mp, curdb); /* * If it has room, return it. */ if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", XFS_ERRLEVEL_LOW, mp); if (curfdb != newfdb) xfs_da_brelse(tp, curbp); return XFS_ERROR(EFSCORRUPTED); } curfdb = newfdb; if (be16_to_cpu(free->bests[fi]) >= length) goto out; } } /* Didn't find any space */ fi = -1; out: ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); if (curbp) { /* Giving back a free block. */ state->extravalid = 1; state->extrablk.bp = curbp; state->extrablk.index = fi; state->extrablk.blkno = curfdb; state->extrablk.magic = XFS_DIR2_FREE_MAGIC; } else { state->extravalid = 0; } /* * Return the index, that will be the insertion point. */ *indexp = index; return XFS_ERROR(ENOENT); } /* * Look up a leaf entry in a node-format leaf block. * The extrablk in state a data block. */ STATIC int xfs_dir2_leafn_lookup_for_entry( xfs_dabuf_t *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ enum xfs_dacmp cmp; /* comparison result */ dp = args->dp; tp = args->trans; mp = dp->i_mount; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); #ifdef __KERNEL__ ASSERT(be16_to_cpu(leaf->hdr.count) > 0); #endif xfs_dir2_leafn_check(dp, bp); /* * Look up the hash value in the leaf entries. */ index = xfs_dir2_leaf_search_hash(args, bp); /* * Do we have a buffer coming in? */ if (state->extravalid) { curbp = state->extrablk.bp; curdb = state->extrablk.blkno; } /* * Loop over leaf entries with the right hash value. */ for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* * Skip stale leaf entries. */ if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Pull the data block number from the entry. */ newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); /* * Not adding a new entry, so we really want to find * the name given to us. * * If it's a different data block, go get it. */ if (newdb != curdb) { /* * If we had a block before that we aren't saving * for a CI name, drop it */ if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || curdb != state->extrablk.blkno)) xfs_da_brelse(tp, curbp); /* * If needing the block that is saved with a CI match, * use it otherwise read in the new data block. */ if (args->cmpresult != XFS_CMP_DIFFERENT && newdb == state->extrablk.blkno) { ASSERT(state->extravalid); curbp = state->extrablk.bp; } else { error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, newdb), -1, &curbp, XFS_DATA_FORK); if (error) return error; } xfs_dir2_data_check(dp, curbp); curdb = newdb; } /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *)((char *)curbp->data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* * Compare the entry and if it's an exact match, return * EEXIST immediately. If it's the first case-insensitive * match, store the block & inode number and continue looking. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { /* If there is a CI match block, drop it */ if (args->cmpresult != XFS_CMP_DIFFERENT && curdb != state->extrablk.blkno) xfs_da_brelse(tp, state->extrablk.bp); args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); *indexp = index; state->extravalid = 1; state->extrablk.bp = curbp; state->extrablk.blkno = curdb; state->extrablk.index = (int)((char *)dep - (char *)curbp->data); state->extrablk.magic = XFS_DIR2_DATA_MAGIC; if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); } } ASSERT(index == be16_to_cpu(leaf->hdr.count) || (args->op_flags & XFS_DA_OP_OKNOENT)); if (curbp) { if (args->cmpresult == XFS_CMP_DIFFERENT) { /* Giving back last used data block. */ state->extravalid = 1; state->extrablk.bp = curbp; state->extrablk.index = -1; state->extrablk.blkno = curdb; state->extrablk.magic = XFS_DIR2_DATA_MAGIC; } else { /* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp) xfs_da_brelse(tp, curbp); } } else { state->extravalid = 0; } *indexp = index; return XFS_ERROR(ENOENT); } /* * Look up a leaf entry in a node-format leaf block. * If this is an addname then the extrablk in state is a freespace block, * otherwise it's a data block. */ int xfs_dir2_leafn_lookup_int( xfs_dabuf_t *bp, /* leaf buffer */ xfs_da_args_t *args, /* operation arguments */ int *indexp, /* out: leaf entry index */ xfs_da_state_t *state) /* state to fill in */ { if (args->op_flags & XFS_DA_OP_ADDNAME) return xfs_dir2_leafn_lookup_for_addname(bp, args, indexp, state); return xfs_dir2_leafn_lookup_for_entry(bp, args, indexp, state); } /* * Move count leaf entries from source to destination leaf. * Log entries and headers. Stale entries are preserved. */ static void xfs_dir2_leafn_moveents( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *bp_s, /* source leaf buffer */ int start_s, /* source leaf index */ xfs_dabuf_t *bp_d, /* destination leaf buffer */ int start_d, /* destination leaf index */ int count) /* count of leaves to copy */ { xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */ xfs_dir2_leaf_t *leaf_s; /* source leaf structure */ int stale; /* count stale leaves copied */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); /* * Silently return if nothing to do. */ if (count == 0) { return; } tp = args->trans; leaf_s = bp_s->data; leaf_d = bp_d->data; /* * If the destination index is not the end of the current * destination leaf entries, open up a hole in the destination * to hold the new entries. */ if (start_d < be16_to_cpu(leaf_d->hdr.count)) { memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d], (be16_to_cpu(leaf_d->hdr.count) - start_d) * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count, count + be16_to_cpu(leaf_d->hdr.count) - 1); } /* * If the source has stale leaves, count the ones in the copy range * so we can update the header correctly. */ if (leaf_s->hdr.stale) { int i; /* temp leaf index */ for (i = start_s, stale = 0; i < start_s + count; i++) { if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } } else stale = 0; /* * Copy the leaf entries from source to destination. */ memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s], count * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); /* * If there are source entries after the ones we copied, * delete the ones we copied by sliding the next ones down. */ if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) { memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count], count * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); } /* * Update the headers and log them. */ be16_add_cpu(&leaf_s->hdr.count, -(count)); be16_add_cpu(&leaf_s->hdr.stale, -(stale)); be16_add_cpu(&leaf_d->hdr.count, count); be16_add_cpu(&leaf_d->hdr.stale, stale); xfs_dir2_leaf_log_header(tp, bp_s); xfs_dir2_leaf_log_header(tp, bp_d); xfs_dir2_leafn_check(args->dp, bp_s); xfs_dir2_leafn_check(args->dp, bp_d); } /* * Determine the sort order of two leaf blocks. * Returns 1 if both are valid and leaf2 should be before leaf1, else 0. */ int /* sort order */ xfs_dir2_leafn_order( xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */ xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */ { xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ leaf1 = leaf1_bp->data; leaf2 = leaf2_bp->data; ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); if (be16_to_cpu(leaf1->hdr.count) > 0 && be16_to_cpu(leaf2->hdr.count) > 0 && (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) || be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) < be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval))) return 1; return 0; } /* * Rebalance leaf entries between two leaf blocks. * This is actually only called when the second block is new, * though the code deals with the general case. * A new entry will be inserted in one of the blocks, and that * entry is taken into account when balancing. */ static void xfs_dir2_leafn_rebalance( xfs_da_state_t *state, /* btree cursor */ xfs_da_state_blk_t *blk1, /* first btree block */ xfs_da_state_blk_t *blk2) /* second btree block */ { xfs_da_args_t *args; /* operation arguments */ int count; /* count (& direction) leaves */ int isleft; /* new goes in left leaf */ xfs_dir2_leaf_t *leaf1; /* first leaf structure */ xfs_dir2_leaf_t *leaf2; /* second leaf structure */ int mid; /* midpoint leaf index */ #ifdef DEBUG int oldstale; /* old count of stale leaves */ #endif int oldsum; /* old total leaf count */ int swap; /* swapped leaf blocks */ args = state->args; /* * If the block order is wrong, swap the arguments. */ if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) { xfs_da_state_blk_t *tmp; /* temp for block swap */ tmp = blk1; blk1 = blk2; blk2 = tmp; } leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); #ifdef DEBUG oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); #endif mid = oldsum >> 1; /* * If the old leaf count was odd then the new one will be even, * so we need to divide the new count evenly. */ if (oldsum & 1) { xfs_dahash_t midhash; /* middle entry hash value */ if (mid >= be16_to_cpu(leaf1->hdr.count)) midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval); else midhash = be32_to_cpu(leaf1->ents[mid].hashval); isleft = args->hashval <= midhash; } /* * If the old count is even then the new count is odd, so there's * no preferred side for the new entry. * Pick the left one. */ else isleft = 1; /* * Calculate moved entry count. Positive means left-to-right, * negative means right-to-left. Then move the entries. */ count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0); if (count > 0) xfs_dir2_leafn_moveents(args, blk1->bp, be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count); else if (count < 0) xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp, be16_to_cpu(leaf1->hdr.count), count); ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum); ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale); /* * Mark whether we're inserting into the old or new leaf. */ if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count)) state->inleaf = swap; else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count)) state->inleaf = !swap; else state->inleaf = swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count)); /* * Adjust the expected index for insertion. */ if (!state->inleaf) blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); /* * Finally sanity check just to make sure we are not returning a * negative index */ if(blk2->index < 0) { state->inleaf = 1; blk2->index = 0; cmn_err(CE_ALERT, "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: " "blk1->index %d\n", blk1->index); } } /* * Remove an entry from a node directory. * This removes the leaf entry and the data entry, * and updates the free block if necessary. */ static int /* error */ xfs_dir2_leafn_remove( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *bp, /* leaf buffer */ int index, /* leaf entry index */ xfs_da_state_blk_t *dblk, /* data block */ int *rval) /* resulting block needs join */ { xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_db_t db; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ int longest; /* longest data free entry */ int off; /* data block entry offset */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leafn_remove(args, index); dp = args->dp; tp = args->trans; mp = dp->i_mount; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * Point to the entry we're removing. */ lep = &leaf->ents[index]; /* * Extract the data block and offset from the entry. */ db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); ASSERT(dblk->blkno == db); off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); ASSERT(dblk->index == off); /* * Kill the leaf entry by marking it stale. * Log the leaf block changes. */ be16_add_cpu(&leaf->hdr.stale, 1); xfs_dir2_leaf_log_header(tp, bp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_leaf_log_ents(tp, bp, index, index); /* * Make the data entry free. Keep track of the longest freespace * in the data block in case it changes. */ dbp = dblk->bp; data = dbp->data; dep = (xfs_dir2_data_entry_t *)((char *)data + off); longest = be16_to_cpu(data->hdr.bestfree[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(tp, dbp, off, xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * Rescan the data block freespaces for bestfree. * Log the data block header if needed. */ if (needscan) xfs_dir2_data_freescan(mp, data, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); xfs_dir2_data_check(dp, dbp); /* * If the longest data block freespace changes, need to update * the corresponding freeblock entry. */ if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) { int error; /* error return value */ xfs_dabuf_t *fbp; /* freeblock buffer */ xfs_dir2_db_t fdb; /* freeblock block number */ int findex; /* index in freeblock entries */ xfs_dir2_free_t *free; /* freeblock structure */ int logfree; /* need to log free entry */ /* * Convert the data block number to a free block, * read in the free block. */ fdb = xfs_dir2_db_to_fdb(mp, db); if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, XFS_DATA_FORK))) { return error; } free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); ASSERT(be32_to_cpu(free->hdr.firstdb) == XFS_DIR2_MAX_FREE_BESTS(mp) * (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); /* * Calculate which entry we need to fix. */ findex = xfs_dir2_db_to_fdindex(mp, db); longest = be16_to_cpu(data->hdr.bestfree[0].length); /* * If the data block is now empty we can get rid of it * (usually). */ if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) { /* * Try to punch out the data block. */ error = xfs_dir2_shrink_inode(args, db, dbp); if (error == 0) { dblk->bp = NULL; data = NULL; } /* * We can get ENOSPC if there's no space reservation. * In this case just drop the buffer and some one else * will eventually get rid of the empty block. */ else if (error == ENOSPC && args->total == 0) xfs_da_buf_done(dbp); else return error; } /* * If we got rid of the data block, we can eliminate that entry * in the free block. */ if (data == NULL) { /* * One less used entry in the free table. */ be32_add_cpu(&free->hdr.nused, -1); xfs_dir2_free_log_header(tp, fbp); /* * If this was the last entry in the table, we can * trim the table size back. There might be other * entries at the end referring to non-existent * data blocks, get those too. */ if (findex == be32_to_cpu(free->hdr.nvalid) - 1) { int i; /* free entry index */ for (i = findex - 1; i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF; i--) continue; free->hdr.nvalid = cpu_to_be32(i + 1); logfree = 0; } /* * Not the last entry, just punch it out. */ else { free->bests[findex] = cpu_to_be16(NULLDATAOFF); logfree = 1; } /* * If there are no useful entries left in the block, * get rid of the block if we can. */ if (!free->hdr.nused) { error = xfs_dir2_shrink_inode(args, fdb, fbp); if (error == 0) { fbp = NULL; logfree = 0; } else if (error != ENOSPC || args->total != 0) return error; /* * It's possible to get ENOSPC if there is no * space reservation. In this case some one * else will eventually get rid of this block. */ } } /* * Data block is not empty, just set the free entry to * the new value. */ else { free->bests[findex] = cpu_to_be16(longest); logfree = 1; } /* * Log the free entry that changed, unless we got rid of it. */ if (logfree) xfs_dir2_free_log_bests(tp, fbp, findex, findex); /* * Drop the buffer if we still have it. */ if (fbp) xfs_da_buf_done(fbp); } xfs_dir2_leafn_check(dp, bp); /* * Return indication of whether this leaf block is empty enough * to justify trying to join it with a neighbor. */ *rval = ((uint)sizeof(leaf->hdr) + (uint)sizeof(leaf->ents[0]) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) < mp->m_dir_magicpct; return 0; } /* * Split the leaf entries in the old block into old and new blocks. */ int /* error */ xfs_dir2_leafn_split( xfs_da_state_t *state, /* btree cursor */ xfs_da_state_blk_t *oldblk, /* original block */ xfs_da_state_blk_t *newblk) /* newly created block */ { xfs_da_args_t *args; /* operation arguments */ xfs_dablk_t blkno; /* new leaf block number */ int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ /* * Allocate space for a new leaf node. */ args = state->args; mp = args->dp->i_mount; ASSERT(args != NULL); ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC); error = xfs_da_grow_inode(args, &blkno); if (error) { return error; } /* * Initialize the new leaf block. */ error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno), &newblk->bp, XFS_DIR2_LEAFN_MAGIC); if (error) { return error; } newblk->blkno = blkno; newblk->magic = XFS_DIR2_LEAFN_MAGIC; /* * Rebalance the entries across the two leaves, link the new * block into the leaves. */ xfs_dir2_leafn_rebalance(state, oldblk, newblk); error = xfs_da_blk_link(state, oldblk, newblk); if (error) { return error; } /* * Insert the new entry in the correct block. */ if (state->inleaf) error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index); else error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index); /* * Update last hashval in each block since we added the name. */ oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); xfs_dir2_leafn_check(args->dp, oldblk->bp); xfs_dir2_leafn_check(args->dp, newblk->bp); return error; } /* * Check a leaf block and its neighbors to see if the block should be * collapsed into one or the other neighbor. Always keep the block * with the smaller block number. * If the current block is over 50% full, don't try to join it, return 0. * If the block is empty, fill in the state structure and return 2. * If it can be collapsed, fill in the state structure and return 1. * If nothing can be done, return 0. */ int /* error */ xfs_dir2_leafn_toosmall( xfs_da_state_t *state, /* btree cursor */ int *action) /* resulting action to take */ { xfs_da_state_blk_t *blk; /* leaf block */ xfs_dablk_t blkno; /* leaf block number */ xfs_dabuf_t *bp; /* leaf buffer */ int bytes; /* bytes in use */ int count; /* leaf live entry count */ int error; /* error return value */ int forward; /* sibling block direction */ int i; /* sibling counter */ xfs_da_blkinfo_t *info; /* leaf block header */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int rval; /* result from path_shift */ /* * Check for the degenerate case of the block being over 50% full. * If so, it's not worth even looking to see if we might be able * to coalesce with a sibling. */ blk = &state->path.blk[state->path.active - 1]; info = blk->bp->data; ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC); leaf = (xfs_dir2_leaf_t *)info; count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); if (bytes > (state->blocksize >> 1)) { /* * Blk over 50%, don't try to join. */ *action = 0; return 0; } /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { /* * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &rval); if (error) return error; *action = rval ? 2 : 0; return 0; } /* * Examine each sibling block to see if we can coalesce with * at least 25% free space to spare. We need to figure out * whether to merge with the forward or the backward block. * We prefer coalescing with the lower numbered sibling so as * to shrink a directory over time. */ forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back); for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back); if (blkno == 0) continue; /* * Read the sibling leaf block. */ if ((error = xfs_da_read_buf(state->args->trans, state->args->dp, blkno, -1, &bp, XFS_DATA_FORK))) { return error; } ASSERT(bp != NULL); /* * Count bytes in the two blocks combined. */ leaf = (xfs_dir2_leaf_t *)info; count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes = state->blocksize - (state->blocksize >> 2); leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); bytes -= count * (uint)sizeof(leaf->ents[0]); /* * Fits with at least 25% to spare. */ if (bytes >= 0) break; xfs_da_brelse(state->args->trans, bp); } /* * Didn't like either block, give up. */ if (i >= 2) { *action = 0; return 0; } /* * Done with the sibling leaf block here, drop the dabuf * so path_shift can get it. */ xfs_da_buf_done(bp); /* * Make altpath point to the block we want to keep (the lower * numbered block) and path point to the block we want to drop. */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) error = xfs_da_path_shift(state, &state->altpath, forward, 0, &rval); else error = xfs_da_path_shift(state, &state->path, forward, 0, &rval); if (error) { return error; } *action = rval ? 0 : 1; return 0; } /* * Move all the leaf entries from drop_blk to save_blk. * This is done as part of a join operation. */ void xfs_dir2_leafn_unbalance( xfs_da_state_t *state, /* cursor */ xfs_da_state_blk_t *drop_blk, /* dead block */ xfs_da_state_blk_t *save_blk) /* surviving block */ { xfs_da_args_t *args; /* operation arguments */ xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */ xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */ args = state->args; ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); drop_leaf = drop_blk->bp->data; save_leaf = save_blk->bp->data; ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * If there are any stale leaf entries, take this opportunity * to purge them. */ if (drop_leaf->hdr.stale) xfs_dir2_leaf_compact(args, drop_blk->bp); if (save_leaf->hdr.stale) xfs_dir2_leaf_compact(args, save_blk->bp); /* * Move the entries from drop to the appropriate end of save. */ drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval); if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0, be16_to_cpu(drop_leaf->hdr.count)); else xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count)); save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval); xfs_dir2_leafn_check(args->dp, save_blk->bp); } /* * Top-level node form directory addname routine. */ int /* error */ xfs_dir2_node_addname( xfs_da_args_t *args) /* operation arguments */ { xfs_da_state_blk_t *blk; /* leaf block for insert */ int error; /* error return value */ int rval; /* sub-return value */ xfs_da_state_t *state; /* btree cursor */ trace_xfs_dir2_node_addname(args); /* * Allocate and initialize the state (btree cursor). */ state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_dirblksize; state->node_ents = state->mp->m_dir_node_ents; /* * Look up the name. We're not supposed to find it, but * this gives us the insertion point. */ error = xfs_da_node_lookup_int(state, &rval); if (error) rval = error; if (rval != ENOENT) { goto done; } /* * Add the data entry to a data block. * Extravalid is set to a freeblock found by lookup. */ rval = xfs_dir2_node_addname_int(args, state->extravalid ? &state->extrablk : NULL); if (rval) { goto done; } blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); /* * Add the new leaf entry. */ rval = xfs_dir2_leafn_add(blk->bp, args, blk->index); if (rval == 0) { /* * It worked, fix the hash values up the btree. */ if (!(args->op_flags & XFS_DA_OP_JUSTCHECK)) xfs_da_fixhashpath(state, &state->path); } else { /* * It didn't work, we need to split the leaf block. */ if (args->total == 0) { ASSERT(rval == ENOSPC); goto done; } /* * Split the leaf block and insert the new entry. */ rval = xfs_da_split(state); } done: xfs_da_state_free(state); return rval; } /* * Add the data entry for a node-format directory name addition. * The leaf entry is added in xfs_dir2_leafn_add. * We may enter with a freespace block that the lookup found. */ static int /* error */ xfs_dir2_node_addname_int( xfs_da_args_t *args, /* operation arguments */ xfs_da_state_blk_t *fblk) /* optional freespace block */ { xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_db_t dbno; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ int error; /* error return value */ xfs_dir2_db_t fbno; /* freespace block number */ xfs_dabuf_t *fbp; /* freespace buffer */ int findex; /* freespace entry index */ xfs_dir2_free_t *free=NULL; /* freespace block structure */ xfs_dir2_db_t ifbno; /* initial freespace block no */ xfs_dir2_db_t lastfbno=0; /* highest freespace block no */ int length; /* length of the new entry */ int logfree; /* need to log free entry */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ __be16 *tagp; /* data entry tag pointer */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; mp = dp->i_mount; tp = args->trans; length = xfs_dir2_data_entsize(args->namelen); /* * If we came in with a freespace block that means that lookup * found an entry with our hash value. This is the freespace * block for that data entry. */ if (fblk) { fbp = fblk->bp; /* * Remember initial freespace block number. */ ifbno = fblk->blkno; free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); findex = fblk->index; /* * This means the free entry showed that the data block had * space for our entry, so we remembered it. * Use that data block. */ if (findex >= 0) { ASSERT(findex < be32_to_cpu(free->hdr.nvalid)); ASSERT(be16_to_cpu(free->bests[findex]) != NULLDATAOFF); ASSERT(be16_to_cpu(free->bests[findex]) >= length); dbno = be32_to_cpu(free->hdr.firstdb) + findex; } /* * The data block looked at didn't have enough room. * We'll start at the beginning of the freespace entries. */ else { dbno = -1; findex = 0; } } /* * Didn't come in with a freespace block, so don't have a data block. */ else { ifbno = dbno = -1; fbp = NULL; findex = 0; } /* * If we don't have a data block yet, we're going to scan the * freespace blocks looking for one. Figure out what the * highest freespace block number is. */ if (dbno == -1) { xfs_fileoff_t fo; /* freespace block number */ if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) return error; lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); fbno = ifbno; } /* * While we haven't identified a data block, search the freeblock * data for a good data block. If we find a null freeblock entry, * indicating a hole in the data blocks, remember that. */ while (dbno == -1) { /* * If we don't have a freeblock in hand, get the next one. */ if (fbp == NULL) { /* * Happens the first time through unless lookup gave * us a freespace block to start with. */ if (++fbno == 0) fbno = XFS_DIR2_FREE_FIRSTDB(mp); /* * If it's ifbno we already looked at it. */ if (fbno == ifbno) fbno++; /* * If it's off the end we're done. */ if (fbno >= lastfbno) break; /* * Read the block. There can be holes in the * freespace blocks, so this might not succeed. * This should be really rare, so there's no reason * to avoid it. */ if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { return error; } if (unlikely(fbp == NULL)) { continue; } free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); findex = 0; } /* * Look at the current free entry. Is it good enough? */ if (be16_to_cpu(free->bests[findex]) != NULLDATAOFF && be16_to_cpu(free->bests[findex]) >= length) dbno = be32_to_cpu(free->hdr.firstdb) + findex; else { /* * Are we done with the freeblock? */ if (++findex == be32_to_cpu(free->hdr.nvalid)) { /* * Drop the block. */ xfs_da_brelse(tp, fbp); fbp = NULL; if (fblk && fblk->bp) fblk->bp = NULL; } } } /* * If we don't have a data block, we need to allocate one and make * the freespace entries refer to it. */ if (unlikely(dbno == -1)) { /* * Not allowed to allocate, return failure. */ if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) { /* * Drop the freespace buffer unless it came from our * caller. */ if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return XFS_ERROR(ENOSPC); } /* * Allocate and initialize the new data block. */ if (unlikely((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &dbno)) || (error = xfs_dir2_data_init(args, dbno, &dbp)))) { /* * Drop the freespace buffer unless it came from our * caller. */ if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return error; } /* * If (somehow) we have a freespace block, get rid of it. */ if (fbp) xfs_da_brelse(tp, fbp); if (fblk && fblk->bp) fblk->bp = NULL; /* * Get the freespace block corresponding to the data block * that was just allocated. */ fbno = xfs_dir2_db_to_fdb(mp, dbno); if (unlikely(error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { xfs_da_buf_done(dbp); return error; } /* * If there wasn't a freespace block, the read will * return a NULL fbp. Allocate and initialize a new one. */ if( fbp == NULL ) { if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fbno))) { return error; } if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { cmn_err(CE_ALERT, "xfs_dir2_node_addname_int: dir ino " "%llu needed freesp block %lld for\n" " data block %lld, got %lld\n" " ifbno %llu lastfbno %d\n", (unsigned long long)dp->i_ino, (long long)xfs_dir2_db_to_fdb(mp, dbno), (long long)dbno, (long long)fbno, (unsigned long long)ifbno, lastfbno); if (fblk) { cmn_err(CE_ALERT, " fblk 0x%p blkno %llu " "index %d magic 0x%x\n", fblk, (unsigned long long)fblk->blkno, fblk->index, fblk->magic); } else { cmn_err(CE_ALERT, " ... fblk is NULL\n"); } XFS_ERROR_REPORT("xfs_dir2_node_addname_int", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } /* * Get a buffer for the new block. */ if ((error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), -1, &fbp, XFS_DATA_FORK))) { return error; } ASSERT(fbp != NULL); /* * Initialize the new block to be empty, and remember * its first slot as our empty slot. */ free = fbp->data; free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); free->hdr.firstdb = cpu_to_be32( (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * XFS_DIR2_MAX_FREE_BESTS(mp)); free->hdr.nvalid = 0; free->hdr.nused = 0; } else { free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); } /* * Set the freespace block index from the data block number. */ findex = xfs_dir2_db_to_fdindex(mp, dbno); /* * If it's after the end of the current entries in the * freespace block, extend that table. */ if (findex >= be32_to_cpu(free->hdr.nvalid)) { ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp)); free->hdr.nvalid = cpu_to_be32(findex + 1); /* * Tag new entry so nused will go up. */ free->bests[findex] = cpu_to_be16(NULLDATAOFF); } /* * If this entry was for an empty data block * (this should always be true) then update the header. */ if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { be32_add_cpu(&free->hdr.nused, 1); xfs_dir2_free_log_header(tp, fbp); } /* * Update the real value in the table. * We haven't allocated the data entry yet so this will * change again. */ data = dbp->data; free->bests[findex] = data->hdr.bestfree[0].length; logfree = 1; } /* * We had a data block so we don't have to make a new one. */ else { /* * If just checking, we succeeded. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) { if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return 0; } /* * Read the data block in. */ if (unlikely( error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), -1, &dbp, XFS_DATA_FORK))) { if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return error; } data = dbp->data; logfree = 0; } ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length); /* * Point to the existing unused space. */ dup = (xfs_dir2_data_unused_t *) ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); needscan = needlog = 0; /* * Mark the first part of the unused space, inuse for us. */ xfs_dir2_data_use_free(tp, dbp, dup, (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, &needlog, &needscan); /* * Fill in the new entry and log it. */ dep = (xfs_dir2_data_entry_t *)dup; dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)data); xfs_dir2_data_log_entry(tp, dbp, dep); /* * Rescan the block for bestfree if needed. */ if (needscan) xfs_dir2_data_freescan(mp, data, &needlog); /* * Log the data block header if needed. */ if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * If the freespace entry is now wrong, update it. */ if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) { free->bests[findex] = data->hdr.bestfree[0].length; logfree = 1; } /* * Log the freespace entry if needed. */ if (logfree) xfs_dir2_free_log_bests(tp, fbp, findex, findex); /* * If the caller didn't hand us the freespace block, drop it. */ if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); /* * Return the data block and offset in args, then drop the data block. */ args->blkno = (xfs_dablk_t)dbno; args->index = be16_to_cpu(*tagp); xfs_da_buf_done(dbp); return 0; } /* * Lookup an entry in a node-format directory. * All the real work happens in xfs_da_node_lookup_int. * The only real output is the inode number of the entry. */ int /* error */ xfs_dir2_node_lookup( xfs_da_args_t *args) /* operation arguments */ { int error; /* error return value */ int i; /* btree level */ int rval; /* operation return value */ xfs_da_state_t *state; /* btree cursor */ trace_xfs_dir2_node_lookup(args); /* * Allocate and initialize the btree cursor. */ state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_dirblksize; state->node_ents = state->mp->m_dir_node_ents; /* * Fill in the path to the entry in the cursor. */ error = xfs_da_node_lookup_int(state, &rval); if (error) rval = error; else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { /* If a CI match, dup the actual name and return EEXIST */ xfs_dir2_data_entry_t *dep; dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp-> data + state->extrablk.index); rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); } /* * Release the btree blocks and leaf block. */ for (i = 0; i < state->path.active; i++) { xfs_da_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } /* * Release the data block if we have it. */ if (state->extravalid && state->extrablk.bp) { xfs_da_brelse(args->trans, state->extrablk.bp); state->extrablk.bp = NULL; } xfs_da_state_free(state); return rval; } /* * Remove an entry from a node-format directory. */ int /* error */ xfs_dir2_node_removename( xfs_da_args_t *args) /* operation arguments */ { xfs_da_state_blk_t *blk; /* leaf block */ int error; /* error return value */ int rval; /* operation return value */ xfs_da_state_t *state; /* btree cursor */ trace_xfs_dir2_node_removename(args); /* * Allocate and initialize the btree cursor. */ state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_dirblksize; state->node_ents = state->mp->m_dir_node_ents; /* * Look up the entry we're deleting, set up the cursor. */ error = xfs_da_node_lookup_int(state, &rval); if (error) rval = error; /* * Didn't find it, upper layer screwed up. */ if (rval != EEXIST) { xfs_da_state_free(state); return rval; } blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(state->extravalid); /* * Remove the leaf and data entries. * Extrablk refers to the data block. */ error = xfs_dir2_leafn_remove(args, blk->bp, blk->index, &state->extrablk, &rval); if (error) return error; /* * Fix the hash values up the btree. */ xfs_da_fixhashpath(state, &state->path); /* * If we need to join leaf blocks, do it. */ if (rval && state->path.active > 1) error = xfs_da_join(state); /* * If no errors so far, try conversion to leaf format. */ if (!error) error = xfs_dir2_node_to_leaf(state); xfs_da_state_free(state); return error; } /* * Replace an entry's inode number in a node-format directory. */ int /* error */ xfs_dir2_node_replace( xfs_da_args_t *args) /* operation arguments */ { xfs_da_state_blk_t *blk; /* leaf block */ xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_data_entry_t *dep; /* data entry changed */ int error; /* error return value */ int i; /* btree level */ xfs_ino_t inum; /* new inode number */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */ int rval; /* internal return value */ xfs_da_state_t *state; /* btree cursor */ trace_xfs_dir2_node_replace(args); /* * Allocate and initialize the btree cursor. */ state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_dirblksize; state->node_ents = state->mp->m_dir_node_ents; inum = args->inumber; /* * Lookup the entry to change in the btree. */ error = xfs_da_node_lookup_int(state, &rval); if (error) { rval = error; } /* * It should be found, since the vnodeops layer has looked it up * and locked it. But paranoia is good. */ if (rval == EEXIST) { /* * Find the leaf entry. */ blk = &state->path.blk[state->path.active - 1]; ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); leaf = blk->bp->data; lep = &leaf->ents[blk->index]; ASSERT(state->extravalid); /* * Point to the data entry. */ data = state->extrablk.bp->data; ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); dep = (xfs_dir2_data_entry_t *) ((char *)data + xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); ASSERT(inum != be64_to_cpu(dep->inumber)); /* * Fill in the new inode number and log the entry. */ dep->inumber = cpu_to_be64(inum); xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); rval = 0; } /* * Didn't find it, and we're holding a data block. Drop it. */ else if (state->extravalid) { xfs_da_brelse(args->trans, state->extrablk.bp); state->extrablk.bp = NULL; } /* * Release all the buffers in the cursor. */ for (i = 0; i < state->path.active; i++) { xfs_da_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } xfs_da_state_free(state); return rval; } /* * Trim off a trailing empty freespace block. * Return (in rvalp) 1 if we did it, 0 if not. */ int /* error */ xfs_dir2_node_trim_free( xfs_da_args_t *args, /* operation arguments */ xfs_fileoff_t fo, /* free block number */ int *rvalp) /* out: did something */ { xfs_dabuf_t *bp; /* freespace buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dir2_free_t *free; /* freespace structure */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; mp = dp->i_mount; tp = args->trans; /* * Read the freespace block. */ if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp, XFS_DATA_FORK))) { return error; } /* * There can be holes in freespace. If fo is a hole, there's * nothing to do. */ if (bp == NULL) { return 0; } free = bp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); /* * If there are used entries, there's nothing to do. */ if (be32_to_cpu(free->hdr.nused) > 0) { xfs_da_brelse(tp, bp); *rvalp = 0; return 0; } /* * Blow the block away. */ if ((error = xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), bp))) { /* * Can't fail with ENOSPC since that only happens with no * space reservation, when breaking up an extent into two * pieces. This is the last block of an extent. */ ASSERT(error != ENOSPC); xfs_da_brelse(tp, bp); return error; } /* * Return that we succeeded. */ *rvalp = 1; return 0; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_leaf.c0000664000000000000000000012562711650373061015775 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Local function declarations. */ #ifdef DEBUG static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); #else #define xfs_dir2_leaf_check(dp, bp) #endif static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, int *indexp, xfs_dabuf_t **dbpp); static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, int first, int last); static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); /* * Convert a block form directory to a leaf form directory. */ int /* error */ xfs_dir2_block_to_leaf( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *dbp) /* input block's buffer */ { __be16 *bestsp; /* leaf's bestsp entries */ xfs_dablk_t blkno; /* leaf block's bno */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ xfs_dir2_block_tail_t *btp; /* block's tail */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dabuf_t *lbp; /* leaf block's buffer */ xfs_dir2_db_t ldb; /* leaf block's bno */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log block header */ int needscan; /* need to rescan bestfree */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_block_to_leaf(args); dp = args->dp; mp = dp->i_mount; tp = args->trans; /* * Add the leaf block to the inode. * This interface will only put blocks in the leaf/node range. * Since that's empty now, we'll get the root (block 0 in range). */ if ((error = xfs_da_grow_inode(args, &blkno))) { return error; } ldb = xfs_dir2_da_to_db(mp, blkno); ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); /* * Initialize the leaf block, get a buffer for it. */ if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) { return error; } ASSERT(lbp != NULL); leaf = lbp->data; block = dbp->data; xfs_dir2_data_check(dp, dbp); btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Set the counts in the leaf header. */ leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count)); leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale)); /* * Could compact these but I think we always do the conversion * after squeezing out stale entries. */ memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1); needscan = 0; needlog = 1; /* * Make the space formerly occupied by the leaf entries and block * tail be free. */ xfs_dir2_data_make_free(tp, dbp, (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - (char *)blp), &needlog, &needscan); /* * Fix up the block header, make it a data block. */ block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); if (needscan) xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); /* * Set up leaf tail and bests table. */ ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = cpu_to_be32(1); bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp[0] = block->hdr.bestfree[0].length; /* * Log the data header and leaf bests table. */ if (needlog) xfs_dir2_data_log_header(tp, dbp); xfs_dir2_leaf_check(dp, lbp); xfs_dir2_data_check(dp, dbp); xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); xfs_da_buf_done(lbp); return 0; } /* * Add an entry to a leaf form directory. */ int /* error */ xfs_dir2_leaf_addname( xfs_da_args_t *args) /* operation arguments */ { __be16 *bestsp; /* freespace table in leaf */ int compact; /* need to compact leaves */ xfs_dir2_data_t *data; /* data block structure */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* data unused entry */ int error; /* error return value */ int grown; /* allocated new data block */ int highstale; /* index of next stale leaf */ int i; /* temporary, index */ int index; /* leaf table position */ xfs_dabuf_t *lbp; /* leaf's buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int length; /* length of new entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ int lfloglow; /* low leaf logging index */ int lfloghigh; /* high leaf logging index */ int lowstale; /* index of prev stale leaf */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ xfs_mount_t *mp; /* filesystem mount point */ int needbytes; /* leaf block bytes needed */ int needlog; /* need to log data header */ int needscan; /* need to rescan data free */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t use_block; /* data block number */ trace_xfs_dir2_leaf_addname(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; /* * Read the leaf block. */ error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, XFS_DATA_FORK); if (error) { return error; } ASSERT(lbp != NULL); /* * Look up the entry by hash value and name. * We know it's not there, our caller has already done a lookup. * So the index is of the entry to insert in front of. * But if there are dup hash values the index is of the first of those. */ index = xfs_dir2_leaf_search_hash(args, lbp); leaf = lbp->data; ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); length = xfs_dir2_data_entsize(args->namelen); /* * See if there are any entries with the same hash value * and space in their block for the new entry. * This is good because it puts multiple same-hash value entries * in a data block, improving the lookup of those entries. */ for (use_block = -1, lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; index++, lep++) { if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); ASSERT(i < be32_to_cpu(ltp->bestcount)); ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; break; } } /* * Didn't find a block yet, linear search all the data blocks. */ if (use_block == -1) { for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { /* * Remember a block we see that's missing. */ if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1) use_block = i; else if (be16_to_cpu(bestsp[i]) >= length) { use_block = i; break; } } } /* * How many bytes do we need in the leaf block? */ needbytes = (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); /* * Now kill use_block if it refers to a missing block, so we * can use it as an indication of allocation needed. */ if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF) use_block = -1; /* * If we don't have enough free bytes but we can make enough * by compacting out stale entries, we'll do that. */ if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < needbytes && be16_to_cpu(leaf->hdr.stale) > 1) { compact = 1; } /* * Otherwise if we don't have enough free bytes we need to * convert to node form. */ else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu( leaf->hdr.count)] < needbytes) { /* * Just checking or no space reservation, give up. */ if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) { xfs_da_brelse(tp, lbp); return XFS_ERROR(ENOSPC); } /* * Convert to node form. */ error = xfs_dir2_leaf_to_node(args, lbp); xfs_da_buf_done(lbp); if (error) return error; /* * Then add the new entry. */ return xfs_dir2_node_addname(args); } /* * Otherwise it will fit without compaction. */ else compact = 0; /* * If just checking, then it will fit unless we needed to allocate * a new data block. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) { xfs_da_brelse(tp, lbp); return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; } /* * If no allocations are allowed, return now before we've * changed anything. */ if (args->total == 0 && use_block == -1) { xfs_da_brelse(tp, lbp); return XFS_ERROR(ENOSPC); } /* * Need to compact the leaf entries, removing stale ones. * Leave one stale entry behind - the one closest to our * insertion index - and we'll shift that one to our insertion * point later. */ if (compact) { xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale, &lfloglow, &lfloghigh); } /* * There are stale entries, so we'll need log-low and log-high * impossibly bad values later. */ else if (be16_to_cpu(leaf->hdr.stale)) { lfloglow = be16_to_cpu(leaf->hdr.count); lfloghigh = -1; } /* * If there was no data block space found, we need to allocate * a new one. */ if (use_block == -1) { /* * Add the new data block. */ if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &use_block))) { xfs_da_brelse(tp, lbp); return error; } /* * Initialize the block. */ if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { xfs_da_brelse(tp, lbp); return error; } /* * If we're adding a new data block on the end we need to * extend the bests table. Copy it up one entry. */ if (use_block >= be32_to_cpu(ltp->bestcount)) { bestsp--; memmove(&bestsp[0], &bestsp[1], be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); be32_add_cpu(<p->bestcount, 1); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } /* * If we're filling in a previously empty block just log it. */ else xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); data = dbp->data; bestsp[use_block] = data->hdr.bestfree[0].length; grown = 1; } /* * Already had space in some data block. * Just read that one in. */ else { if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), -1, &dbp, XFS_DATA_FORK))) { xfs_da_brelse(tp, lbp); return error; } data = dbp->data; grown = 0; } xfs_dir2_data_check(dp, dbp); /* * Point to the biggest freespace in our data block. */ dup = (xfs_dir2_data_unused_t *) ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); ASSERT(be16_to_cpu(dup->length) >= length); needscan = needlog = 0; /* * Mark the initial part of our freespace in use for the new entry. */ xfs_dir2_data_use_free(tp, dbp, dup, (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, &needlog, &needscan); /* * Initialize our new entry (at last). */ dep = (xfs_dir2_data_entry_t *)dup; dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)data); /* * Need to scan fix up the bestfree table. */ if (needscan) xfs_dir2_data_freescan(mp, data, &needlog); /* * Need to log the data block's header. */ if (needlog) xfs_dir2_data_log_header(tp, dbp); xfs_dir2_data_log_entry(tp, dbp, dep); /* * If the bests table needs to be changed, do it. * Log the change unless we've already done that. */ if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { bestsp[use_block] = data->hdr.bestfree[0].length; if (!grown) xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); } /* * Now we need to make room to insert the leaf entry. * If there are no stale entries, we just insert a hole at index. */ if (!leaf->hdr.stale) { /* * lep is still good as the index leaf entry. */ if (index < be16_to_cpu(leaf->hdr.count)) memmove(lep + 1, lep, (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); /* * Record low and high logging indices for the leaf. */ lfloglow = index; lfloghigh = be16_to_cpu(leaf->hdr.count); be16_add_cpu(&leaf->hdr.count, 1); } /* * There are stale entries. * We will use one of them for the new entry. * It's probably not at the right location, so we'll have to * shift some up or down first. */ else { /* * If we didn't compact before, we need to find the nearest * stale entries before and after our insertion point. */ if (compact == 0) { /* * Find the first stale entry before the insertion * point, if any. */ for (lowstale = index - 1; lowstale >= 0 && be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; /* * Find the next stale entry at or after the insertion * point, if any. Stop if we go so far that the * lowstale entry would be better. */ for (highstale = index; highstale < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale - 1 >= highstale - index); highstale++) continue; } /* * If the low one is better, use it. */ if (lowstale >= 0 && (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale - 1 < highstale - index)) { ASSERT(index - lowstale - 1 >= 0); ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == XFS_DIR2_NULL_DATAPTR); /* * Copy entries up to cover the stale entry * and make room for the new entry. */ if (index - lowstale - 1 > 0) memmove(&leaf->ents[lowstale], &leaf->ents[lowstale + 1], (index - lowstale - 1) * sizeof(*lep)); lep = &leaf->ents[index - 1]; lfloglow = MIN(lowstale, lfloglow); lfloghigh = MAX(index - 1, lfloghigh); } /* * The high one is better, so use that one. */ else { ASSERT(highstale - index >= 0); ASSERT(be32_to_cpu(leaf->ents[highstale].address) == XFS_DIR2_NULL_DATAPTR); /* * Copy entries down to cover the stale entry * and make room for the new entry. */ if (highstale - index > 0) memmove(&leaf->ents[index + 1], &leaf->ents[index], (highstale - index) * sizeof(*lep)); lep = &leaf->ents[index]; lfloglow = MIN(index, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } be16_add_cpu(&leaf->hdr.stale, -1); } /* * Fill in the new leaf entry. */ lep->hashval = cpu_to_be32(args->hashval); lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block, be16_to_cpu(*tagp))); /* * Log the leaf fields and give up the buffers. */ xfs_dir2_leaf_log_header(tp, lbp); xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); xfs_dir2_leaf_check(dp, lbp); xfs_da_buf_done(lbp); xfs_dir2_data_check(dp, dbp); xfs_da_buf_done(dbp); return 0; } #ifdef DEBUG /* * Check the internal consistency of a leaf1 block. * Pop an assert if something is wrong. */ STATIC void xfs_dir2_leaf_check( xfs_inode_t *dp, /* incore directory inode */ xfs_dabuf_t *bp) /* leaf's buffer */ { int i; /* leaf index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ xfs_mount_t *mp; /* filesystem mount point */ int stale; /* count of stale leaves */ leaf = bp->data; mp = dp->i_mount; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); /* * This value is not restrictive enough. * Should factor in the size of the bests table as well. * We can deduce a value for that from di_size. */ ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * Leaves and bests don't overlap. */ ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= (char *)xfs_dir2_leaf_bests_p(ltp)); /* * Check hash value order, count stale entries. */ for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if (i + 1 < be16_to_cpu(leaf->hdr.count)) ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= be32_to_cpu(leaf->ents[i + 1].hashval)); if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; } ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); } #endif /* DEBUG */ /* * Compact out any stale entries in the leaf. * Log the header and changed leaf entries, if any. */ void xfs_dir2_leaf_compact( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *bp) /* leaf buffer */ { int from; /* source leaf index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int loglow; /* first leaf entry to log */ int to; /* target leaf index */ leaf = bp->data; if (!leaf->hdr.stale) { return; } /* * Compress out the stale entries in place. */ for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Only actually copy the entries that are different. */ if (from > to) { if (loglow == -1) loglow = to; leaf->ents[to] = leaf->ents[from]; } to++; } /* * Update and log the header, log the leaf entries. */ ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); leaf->hdr.stale = 0; xfs_dir2_leaf_log_header(args->trans, bp); if (loglow != -1) xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1); } /* * Compact the leaf entries, removing stale ones. * Leave one stale entry behind - the one closest to our * insertion index - and the caller will shift that one to our insertion * point later. * Return new insertion index, where the remaining stale entry is, * and leaf logging indices. */ void xfs_dir2_leaf_compact_x1( xfs_dabuf_t *bp, /* leaf buffer */ int *indexp, /* insertion index */ int *lowstalep, /* out: stale entry before us */ int *highstalep, /* out: stale entry after us */ int *lowlogp, /* out: low log index */ int *highlogp) /* out: high log index */ { int from; /* source copy index */ int highstale; /* stale entry at/after index */ int index; /* insertion index */ int keepstale; /* source index of kept stale */ xfs_dir2_leaf_t *leaf; /* leaf structure */ int lowstale; /* stale entry before index */ int newindex=0; /* new insertion index */ int to; /* destination copy index */ leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); index = *indexp; /* * Find the first stale entry before our index, if any. */ for (lowstale = index - 1; lowstale >= 0 && be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; /* * Find the first stale entry at or after our index, if any. * Stop if the answer would be worse than lowstale. */ for (highstale = index; highstale < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || index - lowstale > highstale - index); highstale++) continue; /* * Pick the better of lowstale and highstale. */ if (lowstale >= 0 && (highstale == be16_to_cpu(leaf->hdr.count) || index - lowstale <= highstale - index)) keepstale = lowstale; else keepstale = highstale; /* * Copy the entries in place, removing all the stale entries * except keepstale. */ for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { /* * Notice the new value of index. */ if (index == from) newindex = to; if (from != keepstale && be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) { if (from == to) *lowlogp = to; continue; } /* * Record the new keepstale value for the insertion. */ if (from == keepstale) lowstale = highstale = to; /* * Copy only the entries that have moved. */ if (from > to) leaf->ents[to] = leaf->ents[from]; to++; } ASSERT(from > to); /* * If the insertion point was past the last entry, * set the new insertion point accordingly. */ if (index == from) newindex = to; *indexp = newindex; /* * Adjust the leaf header values. */ be16_add_cpu(&leaf->hdr.count, -(from - to)); leaf->hdr.stale = cpu_to_be16(1); /* * Remember the low/high stale value only in the "right" * direction. */ if (lowstale >= newindex) lowstale = -1; else highstale = be16_to_cpu(leaf->hdr.count); *highlogp = be16_to_cpu(leaf->hdr.count) - 1; *lowstalep = lowstale; *highstalep = highstale; } /* * Initialize a new leaf block, leaf1 or leafn magic accepted. */ int xfs_dir2_leaf_init( xfs_da_args_t *args, /* operation arguments */ xfs_dir2_db_t bno, /* directory block number */ xfs_dabuf_t **bpp, /* out: leaf buffer */ int magic) /* magic number for block */ { xfs_dabuf_t *bp; /* leaf buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; ASSERT(dp != NULL); tp = args->trans; mp = dp->i_mount; ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && bno < XFS_DIR2_FREE_FIRSTDB(mp)); /* * Get the buffer for the block. */ error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, XFS_DATA_FORK); if (error) { return error; } ASSERT(bp != NULL); leaf = bp->data; /* * Initialize the header. */ leaf->hdr.info.magic = cpu_to_be16(magic); leaf->hdr.info.forw = 0; leaf->hdr.info.back = 0; leaf->hdr.count = 0; leaf->hdr.stale = 0; xfs_dir2_leaf_log_header(tp, bp); /* * If it's a leaf-format directory initialize the tail. * In this case our caller has the real bests table to copy into * the block. */ if (magic == XFS_DIR2_LEAF1_MAGIC) { ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = 0; xfs_dir2_leaf_log_tail(tp, bp); } *bpp = bp; return 0; } /* * Log the bests entries indicated from a leaf1 block. */ static void xfs_dir2_leaf_log_bests( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* leaf buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { __be16 *firstb; /* pointer to first entry */ __be16 *lastb; /* pointer to last entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); firstb = xfs_dir2_leaf_bests_p(ltp) + first; lastb = xfs_dir2_leaf_bests_p(ltp) + last; xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); } /* * Log the leaf entries indicated from a leaf1 or leafn block. */ void xfs_dir2_leaf_log_ents( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* leaf buffer */ int first, /* first entry to log */ int last) /* last entry to log */ { xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); firstlep = &leaf->ents[first]; lastlep = &leaf->ents[last]; xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); } /* * Log the header of the leaf1 or leafn block. */ void xfs_dir2_leaf_log_header( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* leaf buffer */ { xfs_dir2_leaf_t *leaf; /* leaf structure */ leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), (uint)(sizeof(leaf->hdr) - 1)); } /* * Log the tail of the leaf1 block. */ STATIC void xfs_dir2_leaf_log_tail( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* leaf buffer */ { xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ mp = tp->t_mountp; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), (uint)(mp->m_dirblksize - 1)); } /* * Look up the entry referred to by args in the leaf format directory. * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which * is also used by the node-format code. */ int xfs_dir2_leaf_lookup( xfs_da_args_t *args) /* operation arguments */ { xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* found entry index */ xfs_dabuf_t *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leaf_lookup(args); /* * Look up name in the leaf block, returning both buffers and index. */ if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { return error; } tp = args->trans; dp = args->dp; xfs_dir2_leaf_check(dp, lbp); leaf = lbp->data; /* * Get to the leaf entry and contained data entry address. */ lep = &leaf->ents[index]; /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *) ((char *)dbp->data + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); /* * Return the found inode number & CI name if appropriate */ args->inumber = be64_to_cpu(dep->inumber); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_da_brelse(tp, dbp); xfs_da_brelse(tp, lbp); return XFS_ERROR(error); } /* * Look up name/hash in the leaf block. * Fill in indexp with the found index, and dbpp with the data buffer. * If not found dbpp will be NULL, and ENOENT comes back. * lbpp will always be filled in with the leaf buffer unless there's an error. */ static int /* error */ xfs_dir2_leaf_lookup_int( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t **lbpp, /* out: leaf buffer */ int *indexp, /* out: index in leaf block */ xfs_dabuf_t **dbpp) /* out: data buffer */ { xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dabuf_t *dbp = NULL; /* data buffer */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* index in leaf block */ xfs_dabuf_t *lbp; /* leaf buffer */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ dp = args->dp; tp = args->trans; mp = dp->i_mount; /* * Read the leaf block into the buffer. */ error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp, XFS_DATA_FORK); if (error) return error; *lbpp = lbp; leaf = lbp->data; xfs_dir2_leaf_check(dp, lbp); /* * Look for the first leaf entry with our hash value. */ index = xfs_dir2_leaf_search_hash(args, lbp); /* * Loop over all the entries with the right hash value * looking to match the name. */ for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; lep++, index++) { /* * Skip over stale leaf entries. */ if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) continue; /* * Get the new data block number. */ newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); /* * If it's not the same as the old data block number, * need to pitch the old one and read the new one. */ if (newdb != curdb) { if (dbp) xfs_da_brelse(tp, dbp); error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, newdb), -1, &dbp, XFS_DATA_FORK); if (error) { xfs_da_brelse(tp, lbp); return error; } xfs_dir2_data_check(dp, dbp); curdb = newdb; } /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *)((char *)dbp->data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* * Compare name and if it's an exact match, return the index * and buffer. If it's the first case-insensitive match, store * the index and buffer and continue looking for an exact match. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; *indexp = index; /* case exact match: return the current buffer. */ if (cmp == XFS_CMP_EXACT) { *dbpp = dbp; return 0; } cidb = curdb; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); /* * Here, we can only be doing a lookup (not a rename or remove). * If a case-insensitive match was found earlier, re-read the * appropriate data block if required and return it. */ if (args->cmpresult == XFS_CMP_CASE) { ASSERT(cidb != -1); if (cidb != curdb) { xfs_da_brelse(tp, dbp); error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, cidb), -1, &dbp, XFS_DATA_FORK); if (error) { xfs_da_brelse(tp, lbp); return error; } } *dbpp = dbp; return 0; } /* * No match found, return ENOENT. */ ASSERT(cidb == -1); if (dbp) xfs_da_brelse(tp, dbp); xfs_da_brelse(tp, lbp); return XFS_ERROR(ENOENT); } /* * Remove an entry from a leaf format directory. */ int /* error */ xfs_dir2_leaf_removename( xfs_da_args_t *args) /* operation arguments */ { __be16 *bestsp; /* leaf block best freespace */ xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_db_t db; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry structure */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dir2_db_t i; /* temporary data block # */ int index; /* index into leaf entries */ xfs_dabuf_t *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ xfs_dir2_data_off_t oldbest; /* old value of best free */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leaf_removename(args); /* * Lookup the leaf entry, get the leaf and data blocks read in. */ if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { return error; } dp = args->dp; tp = args->trans; mp = dp->i_mount; leaf = lbp->data; data = dbp->data; xfs_dir2_data_check(dp, dbp); /* * Point to the leaf entry, use that to point to the data entry. */ lep = &leaf->ents[index]; db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *) ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); needscan = needlog = 0; oldbest = be16_to_cpu(data->hdr.bestfree[0].length); ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); ASSERT(be16_to_cpu(bestsp[db]) == oldbest); /* * Mark the former data entry unused. */ xfs_dir2_data_make_free(tp, dbp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * We just mark the leaf entry stale by putting a null in it. */ be16_add_cpu(&leaf->hdr.stale, 1); xfs_dir2_leaf_log_header(tp, lbp); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_leaf_log_ents(tp, lbp, index, index); /* * Scan the freespace in the data block again if necessary, * log the data block header if necessary. */ if (needscan) xfs_dir2_data_freescan(mp, data, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * If the longest freespace in the data block has changed, * put the new value in the bests table and log that. */ if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { bestsp[db] = data->hdr.bestfree[0].length; xfs_dir2_leaf_log_bests(tp, lbp, db, db); } xfs_dir2_data_check(dp, dbp); /* * If the data block is now empty then get rid of the data block. */ if (be16_to_cpu(data->hdr.bestfree[0].length) == mp->m_dirblksize - (uint)sizeof(data->hdr)) { ASSERT(db != mp->m_dirdatablk); if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { /* * Nope, can't get rid of it because it caused * allocation of a bmap btree block to do so. * Just go on, returning success, leaving the * empty block in place. */ if (error == ENOSPC && args->total == 0) { xfs_da_buf_done(dbp); error = 0; } xfs_dir2_leaf_check(dp, lbp); xfs_da_buf_done(lbp); return error; } dbp = NULL; /* * If this is the last data block then compact the * bests table by getting rid of entries. */ if (db == be32_to_cpu(ltp->bestcount) - 1) { /* * Look for the last active entry (i). */ for (i = db - 1; i > 0; i--) { if (be16_to_cpu(bestsp[i]) != NULLDATAOFF) break; } /* * Copy the table down so inactive entries at the * end are removed. */ memmove(&bestsp[db - i], bestsp, (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); be32_add_cpu(<p->bestcount, -(db - i)); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); } else bestsp[db] = cpu_to_be16(NULLDATAOFF); } /* * If the data block was not the first one, drop it. */ else if (db != mp->m_dirdatablk && dbp != NULL) { xfs_da_buf_done(dbp); dbp = NULL; } xfs_dir2_leaf_check(dp, lbp); /* * See if we can convert to block form. */ return xfs_dir2_leaf_to_block(args, lbp, dbp); } /* * Replace the inode number in a leaf format directory entry. */ int /* error */ xfs_dir2_leaf_replace( xfs_da_args_t *args) /* operation arguments */ { xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ int index; /* index of leaf entry */ xfs_dabuf_t *lbp; /* leaf buffer */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leaf_replace(args); /* * Look up the entry. */ if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { return error; } dp = args->dp; leaf = lbp->data; /* * Point to the leaf entry, get data address from it. */ lep = &leaf->ents[index]; /* * Point to the data entry. */ dep = (xfs_dir2_data_entry_t *) ((char *)dbp->data + xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); ASSERT(args->inumber != be64_to_cpu(dep->inumber)); /* * Put the new inode number in, log it. */ dep->inumber = cpu_to_be64(args->inumber); tp = args->trans; xfs_dir2_data_log_entry(tp, dbp, dep); xfs_da_buf_done(dbp); xfs_dir2_leaf_check(dp, lbp); xfs_da_brelse(tp, lbp); return 0; } /* * Return index in the leaf block (lbp) which is either the first * one with this hash value, or if there are none, the insert point * for that hash value. */ int /* index value */ xfs_dir2_leaf_search_hash( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *lbp) /* leaf buffer */ { xfs_dahash_t hash=0; /* hash from this entry */ xfs_dahash_t hashwant; /* hash value looking for */ int high; /* high leaf index */ int low; /* low leaf index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ int mid=0; /* current leaf index */ leaf = lbp->data; #ifndef __KERNEL__ if (!leaf->hdr.count) return 0; #endif /* * Note, the table cannot be empty, so we have to go through the loop. * Binary search the leaf entries looking for our hash value. */ for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1, hashwant = args->hashval; low <= high; ) { mid = (low + high) >> 1; if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant) break; if (hash < hashwant) low = mid + 1; else high = mid - 1; } /* * Found one, back up through all the equal hash values. */ if (hash == hashwant) { while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) { mid--; } } /* * Need to point to an entry higher than ours. */ else if (hash < hashwant) mid++; return mid; } /* * Trim off a trailing data block. We know it's empty since the leaf * freespace table says so. */ int /* error */ xfs_dir2_leaf_trim_data( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *lbp, /* leaf buffer */ xfs_dir2_db_t db) /* data block number */ { __be16 *bestsp; /* leaf bests table */ #ifdef DEBUG xfs_dir2_data_t *data; /* data block structure */ #endif xfs_dabuf_t *dbp; /* data block buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ dp = args->dp; mp = dp->i_mount; tp = args->trans; /* * Read the offending data block. We need its buffer. */ if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, XFS_DATA_FORK))) { return error; } #ifdef DEBUG data = dbp->data; ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); #endif /* this seems to be an error * data is only valid if DEBUG is defined? * RMC 09/08/1999 */ leaf = lbp->data; ltp = xfs_dir2_leaf_tail_p(mp, leaf); ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == mp->m_dirblksize - (uint)sizeof(data->hdr)); ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); /* * Get rid of the data block. */ if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { ASSERT(error != ENOSPC); xfs_da_brelse(tp, dbp); return error; } /* * Eliminate the last bests entry from the table. */ bestsp = xfs_dir2_leaf_bests_p(ltp); be32_add_cpu(<p->bestcount, -1); memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); return 0; } /* * Convert node form directory to leaf form directory. * The root of the node form dir needs to already be a LEAFN block. * Just return if we can't do anything. */ int /* error */ xfs_dir2_node_to_leaf( xfs_da_state_t *state) /* directory operation state */ { xfs_da_args_t *args; /* operation arguments */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return code */ xfs_dabuf_t *fbp; /* buffer for freespace block */ xfs_fileoff_t fo; /* freespace file offset */ xfs_dir2_free_t *free; /* freespace structure */ xfs_dabuf_t *lbp; /* buffer for leaf block */ xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_mount_t *mp; /* filesystem mount point */ int rval; /* successful free trim? */ xfs_trans_t *tp; /* transaction pointer */ /* * There's more than a leaf level in the btree, so there must * be multiple leafn blocks. Give up. */ if (state->path.active > 1) return 0; args = state->args; trace_xfs_dir2_node_to_leaf(args); mp = state->mp; dp = args->dp; tp = args->trans; /* * Get the last offset in the file. */ if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) { return error; } fo -= mp->m_dirblkfsbs; /* * If there are freespace blocks other than the first one, * take this opportunity to remove trailing empty freespace blocks * that may have been left behind during no-space-reservation * operations. */ while (fo > mp->m_dirfreeblk) { if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) { return error; } if (rval) fo -= mp->m_dirblkfsbs; else return 0; } /* * Now find the block just before the freespace block. */ if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) { return error; } /* * If it's not the single leaf block, give up. */ if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) return 0; lbp = state->path.blk[0].bp; leaf = lbp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); /* * Read the freespace block. */ if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp, XFS_DATA_FORK))) { return error; } free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); ASSERT(!free->hdr.firstdb); /* * Now see if the leafn and free data will fit in a leaf1. * If not, release the buffer and give up. */ if ((uint)sizeof(leaf->hdr) + (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) + (uint)sizeof(leaf->tail) > mp->m_dirblksize) { xfs_da_brelse(tp, fbp); return 0; } /* * If the leaf has any stale entries in it, compress them out. * The compact routine will log the header. */ if (be16_to_cpu(leaf->hdr.stale)) xfs_dir2_leaf_compact(args, lbp); else xfs_dir2_leaf_log_header(tp, lbp); leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); /* * Set up the leaf tail from the freespace block. */ ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = free->hdr.nvalid; /* * Set up the leaf bests table. */ memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_check(dp, lbp); /* * Get rid of the freespace block. */ error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp); if (error) { /* * This can't fail here because it can only happen when * punching out the middle of an extent, and this is an * isolated block. */ ASSERT(error != ENOSPC); return error; } fbp = NULL; /* * Now see if we can convert the single-leaf directory * down to a block form directory. * This routine always kills the dabuf for the leaf, so * eliminate it from the path. */ error = xfs_dir2_leaf_to_block(args, lbp, NULL); state->path.blk[0].bp = NULL; return error; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2.c0000664000000000000000000004021411650373061014772 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2}; /* * ASCII case-insensitive (ie. A-Z) support for directories that was * used in IRIX. */ STATIC xfs_dahash_t xfs_ascii_ci_hashname( struct xfs_name *name) { xfs_dahash_t hash; int i; for (i = 0, hash = 0; i < name->len; i++) hash = tolower(name->name[i]) ^ rol32(hash, 7); return hash; } STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, const unsigned char *name, int len) { enum xfs_dacmp result; int i; if (args->namelen != len) return XFS_CMP_DIFFERENT; result = XFS_CMP_EXACT; for (i = 0; i < len; i++) { if (args->name[i] == name[i]) continue; if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; result = XFS_CMP_CASE; } return result; } static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, .compname = xfs_ascii_ci_compname, }; void xfs_dir_mount( xfs_mount_t *mp) { ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= XFS_MAX_BLOCKSIZE); mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog; mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp)); mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp)); mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_node_ents = (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; if (xfs_sb_version_hasasciici(&mp->m_sb)) mp->m_dirnameops = &xfs_ascii_ci_nameops; else mp->m_dirnameops = &xfs_default_nameops; } /* * Return 1 if directory contains only "." and "..". */ int xfs_dir_isempty( xfs_inode_t *dp) { xfs_dir2_sf_t *sfp; ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); if (dp->i_d.di_size == 0) /* might happen during shutdown. */ return 1; if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) return 0; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; return !sfp->hdr.count; } /* * Validate a given inode number. */ int xfs_dir_ino_validate( xfs_mount_t *mp, xfs_ino_t ino) { xfs_agblock_t agblkno; xfs_agino_t agino; xfs_agnumber_t agno; int ino_ok; int ioff; agno = XFS_INO_TO_AGNO(mp, ino); agblkno = XFS_INO_TO_AGBNO(mp, ino); ioff = XFS_INO_TO_OFFSET(mp, ino); agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); ino_ok = agno < mp->m_sb.sb_agcount && agblkno < mp->m_sb.sb_agblocks && agblkno != 0 && ioff < (1 << mp->m_sb.sb_inopblog) && XFS_AGINO_TO_INO(mp, agno, agino) == ino; if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, XFS_RANDOM_DIR_INO_VALIDATE))) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", (unsigned long long) ino); XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; } /* * Initialize a directory with its "." and ".." entries. */ int xfs_dir_init( xfs_trans_t *tp, xfs_inode_t *dp, xfs_inode_t *pdp) { xfs_da_args_t args; int error; memset((char *)&args, 0, sizeof(args)); args.dp = dp; args.trans = tp; ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) return error; return xfs_dir2_sf_create(&args, pdp->i_ino); } /* Enter a name in a directory. */ int xfs_dir_createname( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; XFS_STATS_INC(xs_dir_create); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_addname(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_addname(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_addname(&args); else rval = xfs_dir2_node_addname(&args); return rval; } /* * If doing a CI lookup and case-insensitive match, dup actual name into * args.value. Return EEXIST for success (ie. name found) or an error. */ int xfs_dir_cilookup_result( struct xfs_da_args *args, const unsigned char *name, int len) { if (args->cmpresult == XFS_CMP_DIFFERENT) return ENOENT; if (args->cmpresult != XFS_CMP_CASE || !(args->op_flags & XFS_DA_OP_CILOOKUP)) return EEXIST; args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); if (!args->value) return ENOMEM; memcpy(args->value, name, len); args->valuelen = len; return EEXIST; } /* * Lookup a name in a directory, give back the inode number. * If ci_name is not NULL, returns the actual name in ci_name if it differs * to name, or ci_name->name is set to NULL for an exact match. */ int xfs_dir_lookup( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, xfs_ino_t *inum, /* out: inode number */ struct xfs_name *ci_name) /* out: actual name if CI match */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_lookup); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args.op_flags |= XFS_DA_OP_CILOOKUP; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_lookup(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_lookup(&args); else rval = xfs_dir2_node_lookup(&args); if (rval == EEXIST) rval = 0; if (!rval) { *inum = args.inumber; if (ci_name) { ci_name->name = args.value; ci_name->len = args.valuelen; } } return rval; } /* * Remove an entry from a directory. */ int xfs_dir_removename( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_remove); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); return rval; } /* * Replace the inode number of a directory entry. */ int xfs_dir_replace( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, /* name of entry to replace */ xfs_ino_t inum, /* new inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) return rval; memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_replace(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_replace(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_replace(&args); else rval = xfs_dir2_node_replace(&args); return rval; } /* * Utility routines. */ /* * Add a block to the directory. * This routine is for data and free blocks, not leaf/node blocks * which are handled by xfs_da_grow_inode. */ int xfs_dir2_grow_inode( xfs_da_args_t *args, int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ xfs_dir2_db_t *dbp) /* out: block number added */ { xfs_fileoff_t bno; /* directory offset of new block */ int count; /* count of filesystem blocks */ xfs_inode_t *dp; /* incore directory inode */ int error; int got; /* blocks actually mapped */ int i; xfs_bmbt_irec_t map; /* single structure for bmap */ int mapi; /* mapping index */ xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ xfs_mount_t *mp; int nmap; /* number of bmap entries */ xfs_trans_t *tp; xfs_drfsbno_t nblks; trace_xfs_dir2_grow_inode(args, space); dp = args->dp; tp = args->trans; mp = dp->i_mount; nblks = dp->i_d.di_nblocks; /* * Set lowest possible block in the space requested. */ bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); count = mp->m_dirblkfsbs; /* * Find the first hole for our block. */ if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) return error; nmap = 1; ASSERT(args->firstblock != NULL); /* * Try mapping the new block contiguously (one extent). */ if ((error = xfs_bmapi(tp, dp, bno, count, XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, args->flist))) return error; ASSERT(nmap <= 1); if (nmap == 1) { mapp = ↦ mapi = 1; } /* * Didn't work and this is a multiple-fsb directory block. * Try again with contiguous flag turned on. */ else if (nmap == 0 && count > 1) { xfs_fileoff_t b; /* current file offset */ /* * Space for maximum number of mappings. */ mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); /* * Iterate until we get to the end of our block. */ for (b = bno, mapi = 0; b < bno + count; ) { int c; /* current fsb count */ /* * Can't map more than MAX_NMAP at once. */ nmap = MIN(XFS_BMAP_MAX_NMAP, count); c = (int)(bno + count - b); if ((error = xfs_bmapi(tp, dp, b, c, XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, args->firstblock, args->total, &mapp[mapi], &nmap, args->flist))) { kmem_free(mapp); return error; } if (nmap < 1) break; /* * Add this bunch into our table, go to the next offset. */ mapi += nmap; b = mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount; } } /* * Didn't work. */ else { mapi = 0; mapp = NULL; } /* * See how many fsb's we got. */ for (i = 0, got = 0; i < mapi; i++) got += mapp[i].br_blockcount; /* * Didn't get enough fsb's, or the first/last block's are wrong. */ if (got != count || mapp[0].br_startoff != bno || mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != bno + count) { if (mapp != &map) kmem_free(mapp); return XFS_ERROR(ENOSPC); } /* * Done with the temporary mapping table. */ if (mapp != &map) kmem_free(mapp); /* account for newly allocated blocks in reserved blocks total */ args->total -= dp->i_d.di_nblocks - nblks; *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); /* * Update file's size if this is the data space and it grew. */ if (space == XFS_DIR2_DATA_SPACE) { xfs_fsize_t size; /* directory file (data) size */ size = XFS_FSB_TO_B(mp, bno + count); if (size > dp->i_d.di_size) { dp->i_d.di_size = size; xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); } } return 0; } /* * See if the directory is a single-block form directory. */ int xfs_dir2_isblock( xfs_trans_t *tp, xfs_inode_t *dp, int *vp) /* out: 1 is block, 0 is not block */ { xfs_fileoff_t last; /* last file offset */ xfs_mount_t *mp; int rval; mp = dp->i_mount; if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) return rval; rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); *vp = rval; return 0; } /* * See if the directory is a single-leaf form directory. */ int xfs_dir2_isleaf( xfs_trans_t *tp, xfs_inode_t *dp, int *vp) /* out: 1 is leaf, 0 is not leaf */ { xfs_fileoff_t last; /* last file offset */ xfs_mount_t *mp; int rval; mp = dp->i_mount; if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) return rval; *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); return 0; } /* * Remove the given block from the directory. * This routine is used for data and free blocks, leaf/node are done * by xfs_da_shrink_inode. */ int xfs_dir2_shrink_inode( xfs_da_args_t *args, xfs_dir2_db_t db, xfs_dabuf_t *bp) { xfs_fileoff_t bno; /* directory file offset */ xfs_dablk_t da; /* directory file offset */ int done; /* bunmap is finished */ xfs_inode_t *dp; int error; xfs_mount_t *mp; xfs_trans_t *tp; trace_xfs_dir2_shrink_inode(args, db); dp = args->dp; mp = dp->i_mount; tp = args->trans; da = xfs_dir2_db_to_da(mp, db); /* * Unmap the fsblock(s). */ if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, &done))) { /* * ENOSPC actually can happen if we're in a removename with * no space reservation, and the resulting block removal * would cause a bmap btree split or conversion from extents * to btree. This can only happen for un-fragmented * directory blocks, since you need to be punching out * the middle of an extent. * In this case we need to leave the block in the file, * and not binval it. * So the block has to be in a consistent empty state * and appropriately logged. * We don't free up the buffer, the caller can tell it * hasn't happened since it got an error back. */ return error; } ASSERT(done); /* * Invalidate the buffer from the transaction. */ xfs_da_binval(tp, bp); /* * If it's not a data block, we're done. */ if (db >= XFS_DIR2_LEAF_FIRSTDB(mp)) return 0; /* * If the block isn't the last one in the directory, we're done. */ if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(mp, db + 1, 0)) return 0; bno = da; if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { /* * This can't really happen unless there's kernel corruption. */ return error; } if (db == mp->m_dirdatablk) ASSERT(bno == 0); else ASSERT(bno > 0); /* * Set the size to the new last block. */ dp->i_d.di_size = XFS_FSB_TO_B(mp, bno); xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); return 0; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_trans.c0000664000000000000000000005051211650373061015263 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * Copyright (C) 2010 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include kmem_zone_t *xfs_trans_zone; kmem_zone_t *xfs_log_item_desc_zone; /* * Various log reservation values. * * These are based on the size of the file system block because that is what * most transactions manipulate. Each adds in an additional 128 bytes per * item logged to try to account for the overhead of the transaction mechanism. * * Note: Most of the reservations underestimate the number of allocation * groups into which they could free extents in the xfs_bmap_finish() call. * This is because the number in the worst case is quite high and quite * unusual. In order to fix this we need to change xfs_bmap_finish() to free * extents in only a single AG at a time. This will require changes to the * EFI code as well, however, so that the EFI for the extents not freed is * logged again in each transaction. See SGI PV #261917. * * Reservation functions here avoid a huge stack in xfs_trans_init due to * register overflow from temporaries in the calculations. */ /* * In a write transaction we can allocate a maximum of 2 * extents. This gives: * the inode getting the new extents: inode size * the inode's bmap btree: max depth * block size * the agfs of the ags from which the extents are allocated: 2 * sector * the superblock free block counter: sector size * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size * And the bmap_finish transaction can free bmap blocks in a join: * the agfs of the ags containing the blocks: 2 * sector size * the agfls of the ags containing the blocks: 2 * sector size * the super block free block counter: sector size * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_write_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + 2 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 2) + 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2))), (2 * mp->m_sb.sb_sectsize + 2 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 2) + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } /* * In truncating a file we free up to two extents at once. We can modify: * the inode being truncated: inode size * the inode's bmap btree: (max depth + 1) * block size * And the bmap_finish transaction can free the blocks and bmap blocks: * the agf for each of the ags: 4 * sector size * the agfl for each of the ags: 4 * sector size * the super block to reflect the freed blocks: sector size * worst case split in allocation btrees per extent assuming 4 extents: * 4 exts * 2 trees * (2 * max depth - 1) * block size * the inode btree: max depth * blocksize * the allocation btrees: 2 trees * (max depth - 1) * block size */ STATIC uint xfs_calc_itruncate_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), (4 * mp->m_sb.sb_sectsize + 4 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 4) + 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) + 128 * 5 + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } /* * In renaming a files we can modify: * the four inodes involved: 4 * inode size * the two directory btrees: 2 * (max depth + v2) * dir block size * the two directory bmap btrees: 2 * max depth * block size * And the bmap_finish transaction can free dir and bmap blocks (two sets * of bmap blocks) giving: * the agf for the ags in which the blocks live: 3 * sector size * the agfl for the ags in which the blocks live: 3 * sector size * the superblock for the free block count: sector size * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_rename_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((4 * mp->m_sb.sb_inodesize + 2 * XFS_DIROP_LOG_RES(mp) + 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))), (3 * mp->m_sb.sb_sectsize + 3 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 3) + 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))); } /* * For creating a link to an inode: * the parent directory inode: inode size * the linked inode: inode size * the directory btree could split: (max depth + v2) * dir block size * the directory bmap btree could join or split: (max depth + v2) * blocksize * And the bmap_finish transaction can free some bmap blocks giving: * the agf for the ag in which the blocks live: sector size * the agfl for the ag in which the blocks live: sector size * the superblock for the free block count: sector size * the allocation btrees: 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_link_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + mp->m_sb.sb_inodesize + XFS_DIROP_LOG_RES(mp) + 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), (mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } /* * For removing a directory entry we can modify: * the parent directory inode: inode size * the removed inode: inode size * the directory btree could join: (max depth + v2) * dir block size * the directory bmap btree could join or split: (max depth + v2) * blocksize * And the bmap_finish transaction can free the dir and bmap blocks giving: * the agf for the ag in which the blocks live: 2 * sector size * the agfl for the ag in which the blocks live: 2 * sector size * the superblock for the free block count: sector size * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_remove_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + mp->m_sb.sb_inodesize + XFS_DIROP_LOG_RES(mp) + 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), (2 * mp->m_sb.sb_sectsize + 2 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 2) + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } /* * For symlink we can modify: * the parent directory inode: inode size * the new inode: inode size * the inode btree entry: 1 block * the directory btree: (max depth + v2) * dir block size * the directory inode's bmap btree: (max depth + v2) * block size * the blocks for the symlink: 1 kB * Or in the first xact we allocate some inodes giving: * the agi and agf of the ag getting the new inodes: 2 * sectorsize * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize * the inode btree: max depth * blocksize * the allocation btrees: 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_symlink_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + mp->m_sb.sb_inodesize + XFS_FSB_TO_B(mp, 1) + XFS_DIROP_LOG_RES(mp) + 1024 + 128 * (4 + XFS_DIROP_LOG_COUNT(mp))), (2 * mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } /* * For create we can modify: * the parent directory inode: inode size * the new inode: inode size * the inode btree entry: block size * the superblock for the nlink flag: sector size * the directory btree: (max depth + v2) * dir block size * the directory inode's bmap btree: (max depth + v2) * block size * Or in the first xact we allocate some inodes giving: * the agi and agf of the ag getting the new inodes: 2 * sectorsize * the superblock for the nlink flag: sector size * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize * the inode btree: max depth * blocksize * the allocation btrees: 2 trees * (max depth - 1) * block size */ STATIC uint xfs_calc_create_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + mp->m_sb.sb_inodesize + mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, 1) + XFS_DIROP_LOG_RES(mp) + 128 * (3 + XFS_DIROP_LOG_COUNT(mp))), (3 * mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } /* * Making a new directory is the same as creating a new file. */ STATIC uint xfs_calc_mkdir_reservation( struct xfs_mount *mp) { return xfs_calc_create_reservation(mp); } /* * In freeing an inode we can modify: * the inode being freed: inode size * the super block free inode counter: sector size * the agi hash list and counters: sector size * the inode btree entry: block size * the on disk inode before ours in the agi hash list: inode cluster size * the inode btree: max depth * blocksize * the allocation btrees: 2 trees * (max depth - 1) * block size */ STATIC uint xfs_calc_ifree_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + mp->m_sb.sb_inodesize + mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, 1) + MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), XFS_INODE_CLUSTER_SIZE(mp)) + 128 * 5 + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } /* * When only changing the inode we log the inode and possibly the superblock * We also add a bit of slop for the transaction stuff. */ STATIC uint xfs_calc_ichange_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + mp->m_sb.sb_inodesize + mp->m_sb.sb_sectsize + 512; } /* * Growing the data section of the filesystem. * superblock * agi and agf * allocation btrees */ STATIC uint xfs_calc_growdata_reservation( struct xfs_mount *mp) { return mp->m_sb.sb_sectsize * 3 + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } /* * Growing the rt section of the filesystem. * In the first set of transactions (ALLOC) we allocate space to the * bitmap or summary files. * superblock: sector size * agf of the ag from which the extent is allocated: sector size * bmap btree for bitmap/summary inode: max depth * blocksize * bitmap/summary inode: inode size * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize */ STATIC uint xfs_calc_growrtalloc_reservation( struct xfs_mount *mp) { return 2 * mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + mp->m_sb.sb_inodesize + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } /* * Growing the rt section of the filesystem. * In the second set of transactions (ZERO) we zero the new metadata blocks. * one bitmap/summary block: blocksize */ STATIC uint xfs_calc_growrtzero_reservation( struct xfs_mount *mp) { return mp->m_sb.sb_blocksize + 128; } /* * Growing the rt section of the filesystem. * In the third set of transactions (FREE) we update metadata without * allocating any new blocks. * superblock: sector size * bitmap inode: inode size * summary inode: inode size * one bitmap block: blocksize * summary blocks: new summary size */ STATIC uint xfs_calc_growrtfree_reservation( struct xfs_mount *mp) { return mp->m_sb.sb_sectsize + 2 * mp->m_sb.sb_inodesize + mp->m_sb.sb_blocksize + mp->m_rsumsize + 128 * 5; } /* * Logging the inode modification timestamp on a synchronous write. * inode */ STATIC uint xfs_calc_swrite_reservation( struct xfs_mount *mp) { return mp->m_sb.sb_inodesize + 128; } /* * Logging the inode mode bits when writing a setuid/setgid file * inode */ STATIC uint xfs_calc_writeid_reservation(xfs_mount_t *mp) { return mp->m_sb.sb_inodesize + 128; } /* * Converting the inode from non-attributed to attributed. * the inode being converted: inode size * agf block and superblock (for block allocation) * the new block (directory sized) * bmap blocks for the new directory block * allocation btrees */ STATIC uint xfs_calc_addafork_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + mp->m_sb.sb_inodesize + mp->m_sb.sb_sectsize * 2 + mp->m_dirblksize + XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + XFS_ALLOCFREE_LOG_RES(mp, 1) + 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } /* * Removing the attribute fork of a file * the inode being truncated: inode size * the inode's bmap btree: max depth * block size * And the bmap_finish transaction can free the blocks and bmap blocks: * the agf for each of the ags: 4 * sector size * the agfl for each of the ags: 4 * sector size * the super block to reflect the freed blocks: sector size * worst case split in allocation btrees per extent assuming 4 extents: * 4 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_attrinval_reservation( struct xfs_mount *mp) { return MAX((mp->m_sb.sb_inodesize + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))), (4 * mp->m_sb.sb_sectsize + 4 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 4) + 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))); } /* * Setting an attribute. * the inode getting the attribute * the superblock for allocations * the agfs extents are allocated from * the attribute btree * max depth * the inode allocation btree * Since attribute transaction space is dependent on the size of the attribute, * the calculation is done partially at mount time and partially at runtime. */ STATIC uint xfs_calc_attrset_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + mp->m_sb.sb_inodesize + mp->m_sb.sb_sectsize + XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + 128 * (2 + XFS_DA_NODE_MAXDEPTH); } /* * Removing an attribute. * the inode: inode size * the attribute btree could join: max depth * block size * the inode bmap btree could join or split: max depth * block size * And the bmap_finish transaction can free the attr blocks freed giving: * the agf for the ag in which the blocks live: 2 * sector size * the agfl for the ag in which the blocks live: 2 * sector size * the superblock for the free block count: sector size * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint xfs_calc_attrrm_reservation( struct xfs_mount *mp) { return XFS_DQUOT_LOGRES(mp) + MAX((mp->m_sb.sb_inodesize + XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + 128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), (2 * mp->m_sb.sb_sectsize + 2 * mp->m_sb.sb_sectsize + mp->m_sb.sb_sectsize + XFS_ALLOCFREE_LOG_RES(mp, 2) + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } /* * Clearing a bad agino number in an agi hash bucket. */ STATIC uint xfs_calc_clear_agi_bucket_reservation( struct xfs_mount *mp) { return mp->m_sb.sb_sectsize + 128; } /* * Initialize the precomputed transaction reservation values * in the mount structure. */ void xfs_trans_init( struct xfs_mount *mp) { struct xfs_trans_reservations *resp = &mp->m_reservations; resp->tr_write = xfs_calc_write_reservation(mp); resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); resp->tr_rename = xfs_calc_rename_reservation(mp); resp->tr_link = xfs_calc_link_reservation(mp); resp->tr_remove = xfs_calc_remove_reservation(mp); resp->tr_symlink = xfs_calc_symlink_reservation(mp); resp->tr_create = xfs_calc_create_reservation(mp); resp->tr_mkdir = xfs_calc_mkdir_reservation(mp); resp->tr_ifree = xfs_calc_ifree_reservation(mp); resp->tr_ichange = xfs_calc_ichange_reservation(mp); resp->tr_growdata = xfs_calc_growdata_reservation(mp); resp->tr_swrite = xfs_calc_swrite_reservation(mp); resp->tr_writeid = xfs_calc_writeid_reservation(mp); resp->tr_addafork = xfs_calc_addafork_reservation(mp); resp->tr_attrinval = xfs_calc_attrinval_reservation(mp); resp->tr_attrset = xfs_calc_attrset_reservation(mp); resp->tr_attrrm = xfs_calc_attrrm_reservation(mp); resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp); resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp); resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp); resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp); } /* * Add the given log item to the transaction's list of log items. * * The log item will now point to its new descriptor with its li_desc field. */ void xfs_trans_add_item( struct xfs_trans *tp, struct xfs_log_item *lip) { struct xfs_log_item_desc *lidp; ASSERT(lip->li_mountp = tp->t_mountp); ASSERT(lip->li_ailp = tp->t_mountp->m_ail); lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS); lidp->lid_item = lip; lidp->lid_flags = 0; lidp->lid_size = 0; list_add_tail(&lidp->lid_trans, &tp->t_items); lip->li_desc = lidp; } STATIC void xfs_trans_free_item_desc( struct xfs_log_item_desc *lidp) { list_del_init(&lidp->lid_trans); kmem_zone_free(xfs_log_item_desc_zone, lidp); } /* * Unlink and free the given descriptor. */ void xfs_trans_del_item( struct xfs_log_item *lip) { xfs_trans_free_item_desc(lip->li_desc); lip->li_desc = NULL; } /* * Roll from one trans in the sequence of PERMANENT transactions to * the next: permanent transactions are only flushed out when * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon * as possible to let chunks of it go to the log. So we commit the * chunk we've been working on and get a new transaction to continue. */ int xfs_trans_roll( struct xfs_trans **tpp, struct xfs_inode *dp) { struct xfs_trans *trans; unsigned int logres, count; int error; /* * Ensure that the inode is always logged. */ trans = *tpp; xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); /* * Copy the critical parameters from one trans to the next. */ logres = trans->t_log_res; count = trans->t_log_count; *tpp = xfs_trans_dup(trans); /* * Commit the current transaction. * If this commit failed, then it'd just unlock those items that * are not marked ihold. That also means that a filesystem shutdown * is in progress. The caller takes the responsibility to cancel * the duplicate transaction that gets returned. */ error = xfs_trans_commit(trans, 0); if (error) return (error); trans = *tpp; /* * Reserve space in the log for th next transaction. * This also pushes items in the "AIL", the list of logged items, * out to disk if they are taking up space at the tail of the log * that we want to use. This requires that either nothing be locked * across this call, or that anything that is locked be logged in * the prior and the next transactions. */ error = xfs_trans_reserve(trans, 0, logres, 0, XFS_TRANS_PERM_LOG_RES, count); /* * Ensure that the inode is in the new transaction and locked. */ if (error) return error; xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(trans, dp); return 0; } xfsprogs-3.1.9ubuntu2/libxfs/rdwr.c0000664000000000000000000004416712062210562014235 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #define BDSTRAT_SIZE (256 * 1024) #define min(x, y) ((x) < (y) ? (x) : (y)) #define IO_BCOMPARE_CHECK void libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len) { xfs_off_t start_offset, end_offset, offset; ssize_t zsize, bytes; char *z; int fd; zsize = min(BDSTRAT_SIZE, BBTOB(len)); if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) { fprintf(stderr, _("%s: %s can't memalign %d bytes: %s\n"), progname, __FUNCTION__, (int)zsize, strerror(errno)); exit(1); } memset(z, 0, zsize); fd = libxfs_device_to_fd(dev); start_offset = LIBXFS_BBTOOFF64(start); if ((lseek64(fd, start_offset, SEEK_SET)) < 0) { fprintf(stderr, _("%s: %s seek to offset %llu failed: %s\n"), progname, __FUNCTION__, (unsigned long long)start_offset, strerror(errno)); exit(1); } end_offset = LIBXFS_BBTOOFF64(start + len) - start_offset; for (offset = 0; offset < end_offset; ) { bytes = min((ssize_t)(end_offset - offset), zsize); if ((bytes = write(fd, z, bytes)) < 0) { fprintf(stderr, _("%s: %s write failed: %s\n"), progname, __FUNCTION__, strerror(errno)); exit(1); } else if (bytes == 0) { fprintf(stderr, _("%s: %s not progressing?\n"), progname, __FUNCTION__); exit(1); } offset += bytes; } free(z); } static void unmount_record(void *p) { xlog_op_header_t *op = (xlog_op_header_t *)p; /* the data section must be 32 bit size aligned */ struct { __uint16_t magic; __uint16_t pad1; __uint32_t pad2; /* may as well make it 64 bits */ } magic = { XLOG_UNMOUNT_TYPE, 0, 0 }; memset(p, 0, BBSIZE); op->oh_tid = cpu_to_be32(1); op->oh_len = cpu_to_be32(sizeof(magic)); op->oh_clientid = XFS_LOG; op->oh_flags = XLOG_UNMOUNT_TRANS; op->oh_res2 = 0; /* and the data for this op */ memcpy((char *)p + sizeof(xlog_op_header_t), &magic, sizeof(magic)); } static xfs_caddr_t next(xfs_caddr_t ptr, int offset, void *private) { xfs_buf_t *buf = (xfs_buf_t *)private; if (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset) abort(); return ptr + offset; } int libxfs_log_clear( dev_t device, xfs_daddr_t start, uint length, uuid_t *fs_uuid, int version, int sunit, int fmt) { xfs_buf_t *bp; int len; if (!device || !fs_uuid) return -EINVAL; /* first zero the log */ libxfs_device_zero(device, start, length); /* then write a log record header */ len = ((version == 2) && sunit) ? BTOBB(sunit) : 2; len = MAX(len, 2); bp = libxfs_getbufr(device, start, len); libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, next, bp); bp->b_flags |= LIBXFS_B_DIRTY; libxfs_putbufr(bp); return 0; } int libxfs_log_header( xfs_caddr_t caddr, uuid_t *fs_uuid, int version, int sunit, int fmt, libxfs_get_block_t *nextfunc, void *private) { xlog_rec_header_t *head = (xlog_rec_header_t *)caddr; xfs_caddr_t p = caddr; __be32 cycle_lsn; int i, len; len = ((version == 2) && sunit) ? BTOBB(sunit) : 1; /* note that oh_tid actually contains the cycle number * and the tid is stored in h_cycle_data[0] - that's the * way things end up on disk. */ memset(p, 0, BBSIZE); head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); head->h_cycle = cpu_to_be32(1); head->h_version = cpu_to_be32(version); if (len != 1) head->h_len = cpu_to_be32(sunit - BBSIZE); else head->h_len = cpu_to_be32(20); head->h_chksum = cpu_to_be32(0); head->h_prev_block = cpu_to_be32(-1); head->h_num_logops = cpu_to_be32(1); head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0); head->h_fmt = cpu_to_be32(fmt); head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE); head->h_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t)); len = MAX(len, 2); p = nextfunc(p, BBSIZE, private); unmount_record(p); cycle_lsn = CYCLE_LSN_DISK(head->h_lsn); for (i = 2; i < len; i++) { p = nextfunc(p, BBSIZE, private); memset(p, 0, BBSIZE); *(__be32 *)p = cycle_lsn; } return BBTOB(len); } /* * Simple I/O (buffer cache) interface */ #ifdef XFS_BUF_TRACING #undef libxfs_readbuf #undef libxfs_writebuf #undef libxfs_getbuf #undef libxfs_getbuf_flags #undef libxfs_putbuf xfs_buf_t *libxfs_readbuf(dev_t, xfs_daddr_t, int, int); int libxfs_writebuf(xfs_buf_t *, int); xfs_buf_t *libxfs_getbuf(dev_t, xfs_daddr_t, int); void libxfs_putbuf (xfs_buf_t *); xfs_buf_t * libxfs_trace_readbuf(const char *func, const char *file, int line, dev_t dev, xfs_daddr_t blkno, int len, int flags) { xfs_buf_t *bp = libxfs_readbuf(dev, blkno, len, flags); if (bp){ bp->b_func = func; bp->b_file = file; bp->b_line = line; } return bp; } int libxfs_trace_writebuf(const char *func, const char *file, int line, xfs_buf_t *bp, int flags) { bp->b_func = func; bp->b_file = file; bp->b_line = line; return libxfs_writebuf(bp, flags); } xfs_buf_t * libxfs_trace_getbuf(const char *func, const char *file, int line, dev_t device, xfs_daddr_t blkno, int len) { xfs_buf_t *bp = libxfs_getbuf(device, blkno, len); bp->b_func = func; bp->b_file = file; bp->b_line = line; return bp; } xfs_buf_t * libxfs_trace_getbuf_flags(const char *func, const char *file, int line, dev_t device, xfs_daddr_t blkno, int len, unsigned long flags) { xfs_buf_t *bp = libxfs_getbuf(device, blkno, len, flags); bp->b_func = func; bp->b_file = file; bp->b_line = line; return bp; } void libxfs_trace_putbuf(const char *func, const char *file, int line, xfs_buf_t *bp) { bp->b_func = func; bp->b_file = file; bp->b_line = line; libxfs_putbuf(bp); } #endif xfs_buf_t * libxfs_getsb(xfs_mount_t *mp, int flags) { return libxfs_readbuf(mp->m_dev, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1), flags); } kmem_zone_t *xfs_buf_zone; static struct cache_mru xfs_buf_freelist = {{&xfs_buf_freelist.cm_list, &xfs_buf_freelist.cm_list}, 0, PTHREAD_MUTEX_INITIALIZER }; typedef struct { dev_t device; xfs_daddr_t blkno; unsigned int bblen; } xfs_bufkey_t; static unsigned int libxfs_bhash(cache_key_t key, unsigned int hashsize) { return (((unsigned int)((xfs_bufkey_t *)key)->blkno) >> 5) % hashsize; } static int libxfs_bcompare(struct cache_node *node, cache_key_t key) { xfs_buf_t *bp = (xfs_buf_t *)node; xfs_bufkey_t *bkey = (xfs_bufkey_t *)key; #ifdef IO_BCOMPARE_CHECK if (bp->b_dev == bkey->device && bp->b_blkno == bkey->blkno && bp->b_bcount != BBTOB(bkey->bblen)) fprintf(stderr, "%lx: Badness in key lookup (length)\n" "bp=(bno %llu, len %u bytes) key=(bno %llu, len %u bytes)\n", pthread_self(), (unsigned long long)bp->b_blkno, (int)bp->b_bcount, (unsigned long long)bkey->blkno, BBTOB(bkey->bblen)); #endif return (bp->b_dev == bkey->device && bp->b_blkno == bkey->blkno && bp->b_bcount == BBTOB(bkey->bblen)); } void libxfs_bprint(xfs_buf_t *bp) { fprintf(stderr, "Buffer 0x%p blkno=%llu bytes=%u flags=0x%x count=%u\n", bp, (unsigned long long)bp->b_blkno, (unsigned)bp->b_bcount, bp->b_flags, bp->b_node.cn_count); } static void libxfs_initbuf(xfs_buf_t *bp, dev_t device, xfs_daddr_t bno, unsigned int bytes) { bp->b_flags = 0; bp->b_blkno = bno; bp->b_bcount = bytes; bp->b_dev = device; bp->b_error = 0; if (!bp->b_addr) bp->b_addr = memalign(libxfs_device_alignment(), bytes); if (!bp->b_addr) { fprintf(stderr, _("%s: %s can't memalign %u bytes: %s\n"), progname, __FUNCTION__, bytes, strerror(errno)); exit(1); } #ifdef XFS_BUF_TRACING list_head_init(&bp->b_lock_list); #endif pthread_mutex_init(&bp->b_lock, NULL); bp->b_holder = 0; bp->b_recur = 0; } xfs_buf_t * libxfs_getbufr(dev_t device, xfs_daddr_t blkno, int bblen) { xfs_buf_t *bp; int blen = BBTOB(bblen); /* * first look for a buffer that can be used as-is, * if one cannot be found, see if there is a buffer, * and if so, free its buffer and set b_addr to NULL * before calling libxfs_initbuf. */ pthread_mutex_lock(&xfs_buf_freelist.cm_mutex); if (!list_empty(&xfs_buf_freelist.cm_list)) { list_for_each_entry(bp, &xfs_buf_freelist.cm_list, b_node.cn_mru) { if (bp->b_bcount == blen) { list_del_init(&bp->b_node.cn_mru); break; } } if (&bp->b_node.cn_mru == &xfs_buf_freelist.cm_list) { bp = list_entry(xfs_buf_freelist.cm_list.next, xfs_buf_t, b_node.cn_mru); list_del_init(&bp->b_node.cn_mru); free(bp->b_addr); bp->b_addr = NULL; } } else bp = kmem_zone_zalloc(xfs_buf_zone, 0); pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex); if (bp != NULL) libxfs_initbuf(bp, device, blkno, blen); #ifdef IO_DEBUG printf("%lx: %s: allocated %u bytes buffer, key=%llu(%llu), %p\n", pthread_self(), __FUNCTION__, blen, (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); #endif return bp; } #ifdef XFS_BUF_TRACING struct list_head lock_buf_list = {&lock_buf_list, &lock_buf_list}; int lock_buf_count = 0; #endif extern int use_xfs_buf_lock; struct xfs_buf * libxfs_getbuf_flags(dev_t device, xfs_daddr_t blkno, int len, unsigned int flags) { xfs_buf_t *bp; xfs_bufkey_t key; int miss; key.device = device; key.blkno = blkno; key.bblen = len; miss = cache_node_get(libxfs_bcache, &key, (struct cache_node **)&bp); if (!bp) return NULL; if (use_xfs_buf_lock) { int ret; ret = pthread_mutex_trylock(&bp->b_lock); if (ret) { ASSERT(ret == EAGAIN); if (flags & LIBXFS_GETBUF_TRYLOCK) goto out_put; if (pthread_equal(bp->b_holder, pthread_self())) { fprintf(stderr, _("Warning: recursive buffer locking at block %" PRIu64 " detected\n"), blkno); bp->b_recur++; return bp; } else { pthread_mutex_lock(&bp->b_lock); } } bp->b_holder = pthread_self(); } cache_node_set_priority(libxfs_bcache, (struct cache_node *)bp, cache_node_get_priority((struct cache_node *)bp) - CACHE_PREFETCH_PRIORITY); #ifdef XFS_BUF_TRACING pthread_mutex_lock(&libxfs_bcache->c_mutex); lock_buf_count++; list_add(&bp->b_lock_list, &lock_buf_list); pthread_mutex_unlock(&libxfs_bcache->c_mutex); #endif #ifdef IO_DEBUG printf("%lx %s: %s buffer %p for bno = %llu\n", pthread_self(), __FUNCTION__, miss ? "miss" : "hit", bp, (long long)LIBXFS_BBTOOFF64(blkno)); #endif return bp; out_put: cache_node_put(libxfs_bcache, (struct cache_node *)bp); return NULL; } struct xfs_buf * libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len) { return libxfs_getbuf_flags(device, blkno, len, 0); } void libxfs_putbuf(xfs_buf_t *bp) { #ifdef XFS_BUF_TRACING pthread_mutex_lock(&libxfs_bcache->c_mutex); lock_buf_count--; ASSERT(lock_buf_count >= 0); list_del_init(&bp->b_lock_list); pthread_mutex_unlock(&libxfs_bcache->c_mutex); #endif if (use_xfs_buf_lock) { if (bp->b_recur) { bp->b_recur--; } else { bp->b_holder = 0; pthread_mutex_unlock(&bp->b_lock); } } cache_node_put(libxfs_bcache, (struct cache_node *)bp); } void libxfs_purgebuf(xfs_buf_t *bp) { xfs_bufkey_t key; key.device = bp->b_dev; key.blkno = bp->b_blkno; key.bblen = bp->b_bcount >> BBSHIFT; cache_node_purge(libxfs_bcache, &key, (struct cache_node *)bp); } static struct cache_node * libxfs_balloc(cache_key_t key) { xfs_bufkey_t *bufkey = (xfs_bufkey_t *)key; return (struct cache_node *)libxfs_getbufr(bufkey->device, bufkey->blkno, bufkey->bblen); } int libxfs_readbufr(dev_t dev, xfs_daddr_t blkno, xfs_buf_t *bp, int len, int flags) { int fd = libxfs_device_to_fd(dev); int bytes = BBTOB(len); int error; int sts; ASSERT(BBTOB(len) <= bp->b_bcount); sts = pread64(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno)); if (sts < 0) { error = errno; fprintf(stderr, _("%s: read failed: %s\n"), progname, strerror(error)); if (flags & LIBXFS_EXIT_ON_FAILURE) exit(1); return error; } else if (sts != bytes) { fprintf(stderr, _("%s: error - read only %d of %d bytes\n"), progname, sts, bytes); if (flags & LIBXFS_EXIT_ON_FAILURE) exit(1); return EIO; } #ifdef IO_DEBUG printf("%lx: %s: read %u bytes, blkno=%llu(%llu), %p\n", pthread_self(), __FUNCTION__, bytes, (long long)LIBXFS_BBTOOFF64(blkno), (long long)blkno, bp); #endif if (bp->b_dev == dev && bp->b_blkno == blkno && bp->b_bcount == bytes) bp->b_flags |= LIBXFS_B_UPTODATE; return 0; } xfs_buf_t * libxfs_readbuf(dev_t dev, xfs_daddr_t blkno, int len, int flags) { xfs_buf_t *bp; int error; bp = libxfs_getbuf(dev, blkno, len); if (bp && !(bp->b_flags & (LIBXFS_B_UPTODATE|LIBXFS_B_DIRTY))) { error = libxfs_readbufr(dev, blkno, bp, len, flags); if (error) bp->b_error = error; } return bp; } int libxfs_writebufr(xfs_buf_t *bp) { int sts; int fd = libxfs_device_to_fd(bp->b_dev); int error; sts = pwrite64(fd, bp->b_addr, bp->b_bcount, LIBXFS_BBTOOFF64(bp->b_blkno)); if (sts < 0) { error = errno; fprintf(stderr, _("%s: pwrite64 failed: %s\n"), progname, strerror(error)); if (bp->b_flags & LIBXFS_B_EXIT) exit(1); return error; } else if (sts != bp->b_bcount) { fprintf(stderr, _("%s: error - wrote only %d of %d bytes\n"), progname, sts, bp->b_bcount); if (bp->b_flags & LIBXFS_B_EXIT) exit(1); return EIO; } #ifdef IO_DEBUG printf("%lx: %s: wrote %u bytes, blkno=%llu(%llu), %p\n", pthread_self(), __FUNCTION__, bp->b_bcount, (long long)LIBXFS_BBTOOFF64(bp->b_blkno), (long long)bp->b_blkno, bp); #endif bp->b_flags |= LIBXFS_B_UPTODATE; bp->b_flags &= ~(LIBXFS_B_DIRTY | LIBXFS_B_EXIT); return 0; } int libxfs_writebuf_int(xfs_buf_t *bp, int flags) { bp->b_flags |= (LIBXFS_B_DIRTY | flags); return 0; } int libxfs_writebuf(xfs_buf_t *bp, int flags) { bp->b_flags |= (LIBXFS_B_DIRTY | flags); libxfs_putbuf(bp); return 0; } void libxfs_iomove(xfs_buf_t *bp, uint boff, int len, void *data, int flags) { #ifdef IO_DEBUG if (boff + len > bp->b_bcount) { printf("Badness, iomove out of range!\n" "bp=(bno %llu, bytes %u) range=(boff %u, bytes %u)\n", (long long)bp->b_blkno, bp->b_bcount, boff, len); abort(); } #endif switch (flags) { case LIBXFS_BZERO: memset(bp->b_addr + boff, 0, len); break; case LIBXFS_BREAD: memcpy(data, bp->b_addr + boff, len); break; case LIBXFS_BWRITE: memcpy(bp->b_addr + boff, data, len); break; } } static void libxfs_brelse(struct cache_node *node) { xfs_buf_t *bp = (xfs_buf_t *)node; if (bp != NULL) { if (bp->b_flags & LIBXFS_B_DIRTY) libxfs_writebufr(bp); pthread_mutex_lock(&xfs_buf_freelist.cm_mutex); list_add(&bp->b_node.cn_mru, &xfs_buf_freelist.cm_list); pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex); } } static unsigned int libxfs_bulkrelse( struct cache *cache, struct list_head *list) { xfs_buf_t *bp; int count = 0; if (list_empty(list)) return 0 ; list_for_each_entry(bp, list, b_node.cn_mru) { if (bp->b_flags & LIBXFS_B_DIRTY) libxfs_writebufr(bp); count++; } pthread_mutex_lock(&xfs_buf_freelist.cm_mutex); __list_splice(list, &xfs_buf_freelist.cm_list); pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex); return count; } static void libxfs_bflush(struct cache_node *node) { xfs_buf_t *bp = (xfs_buf_t *)node; if ((bp != NULL) && (bp->b_flags & LIBXFS_B_DIRTY)) libxfs_writebufr(bp); } void libxfs_putbufr(xfs_buf_t *bp) { libxfs_brelse((struct cache_node *)bp); } void libxfs_bcache_purge(void) { cache_purge(libxfs_bcache); } void libxfs_bcache_flush(void) { cache_flush(libxfs_bcache); } int libxfs_bcache_overflowed(void) { return cache_overflowed(libxfs_bcache); } struct cache_operations libxfs_bcache_operations = { /* .hash */ libxfs_bhash, /* .alloc */ libxfs_balloc, /* .flush */ libxfs_bflush, /* .relse */ libxfs_brelse, /* .compare */ libxfs_bcompare, /* .bulkrelse */libxfs_bulkrelse }; /* * Inode cache interfaces */ extern kmem_zone_t *xfs_ili_zone; extern kmem_zone_t *xfs_inode_zone; static unsigned int libxfs_ihash(cache_key_t key, unsigned int hashsize) { return ((unsigned int)*(xfs_ino_t *)key) % hashsize; } static int libxfs_icompare(struct cache_node *node, cache_key_t key) { xfs_inode_t *ip = (xfs_inode_t *)node; return (ip->i_ino == *(xfs_ino_t *)key); } int libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint lock_flags, xfs_inode_t **ipp, xfs_daddr_t bno) { xfs_inode_t *ip; int error = 0; if (cache_node_get(libxfs_icache, &ino, (struct cache_node **)&ip)) { #ifdef INO_DEBUG fprintf(stderr, "%s: allocated inode, ino=%llu(%llu), %p\n", __FUNCTION__, (unsigned long long)ino, bno, ip); #endif if ((error = libxfs_iread(mp, tp, ino, ip, bno))) { cache_node_purge(libxfs_icache, &ino, (struct cache_node *)ip); ip = NULL; } } *ipp = ip; return error; } void libxfs_iput(xfs_inode_t *ip, uint lock_flags) { cache_node_put(libxfs_icache, (struct cache_node *)ip); } static struct cache_node * libxfs_ialloc(cache_key_t key) { return kmem_zone_zalloc(xfs_inode_zone, 0); } static void libxfs_idestroy(xfs_inode_t *ip) { switch (ip->i_d.di_mode & S_IFMT) { case S_IFREG: case S_IFDIR: case S_IFLNK: libxfs_idestroy_fork(ip, XFS_DATA_FORK); break; } if (ip->i_afp) libxfs_idestroy_fork(ip, XFS_ATTR_FORK); } static void libxfs_irelse(struct cache_node *node) { xfs_inode_t *ip = (xfs_inode_t *)node; if (ip != NULL) { if (ip->i_itemp) kmem_zone_free(xfs_ili_zone, ip->i_itemp); ip->i_itemp = NULL; libxfs_idestroy(ip); kmem_zone_free(xfs_inode_zone, ip); ip = NULL; } } void libxfs_icache_purge(void) { cache_purge(libxfs_icache); } struct cache_operations libxfs_icache_operations = { /* .hash */ libxfs_ihash, /* .alloc */ libxfs_ialloc, /* .flush */ NULL, /* .relse */ libxfs_irelse, /* .compare */ libxfs_icompare, /* .bulkrelse */ NULL }; xfsprogs-3.1.9ubuntu2/libxfs/trans.c0000664000000000000000000004256211650373061014411 0ustar /* * Copyright (c) 2000-2001,2005-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Simple transaction interface */ xfs_trans_t * libxfs_trans_alloc( xfs_mount_t *mp, int type) { xfs_trans_t *ptr; if ((ptr = calloc(sizeof(xfs_trans_t), 1)) == NULL) { fprintf(stderr, _("%s: xact calloc failed (%d bytes): %s\n"), progname, (int)sizeof(xfs_trans_t), strerror(errno)); exit(1); } ptr->t_mountp = mp; ptr->t_type = type; INIT_LIST_HEAD(&ptr->t_items); #ifdef XACT_DEBUG fprintf(stderr, "allocated new transaction %p\n", ptr); #endif return ptr; } xfs_trans_t * libxfs_trans_dup( xfs_trans_t *tp) { xfs_trans_t *ptr; ptr = libxfs_trans_alloc(tp->t_mountp, tp->t_type); #ifdef XACT_DEBUG fprintf(stderr, "duplicated transaction %p (new=%p)\n", tp, ptr); #endif return ptr; } int libxfs_trans_reserve( xfs_trans_t *tp, uint blocks, uint logspace, uint rtextents, uint flags, uint logcount) { xfs_sb_t *mpsb = &tp->t_mountp->m_sb; /* * Attempt to reserve the needed disk blocks by decrementing * the number needed from the number available. This will * fail if the count would go below zero. */ if (blocks > 0) { if (mpsb->sb_fdblocks < blocks) return ENOSPC; } /* user space, don't need log/RT stuff (preserve the API though) */ return 0; } void libxfs_trans_cancel( xfs_trans_t *tp, int flags) { #ifdef XACT_DEBUG xfs_trans_t *otp = tp; #endif if (tp != NULL) { xfs_trans_free_items(tp, flags); free(tp); tp = NULL; } #ifdef XACT_DEBUG fprintf(stderr, "## cancelled transaction %p\n", otp); #endif } int libxfs_trans_iget( xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint flags, uint lock_flags, xfs_inode_t **ipp) { int error; xfs_inode_t *ip; xfs_inode_log_item_t *iip; if (tp == NULL) return libxfs_iget(mp, tp, ino, lock_flags, ipp, 0); error = libxfs_iget(mp, tp, ino, lock_flags, &ip, 0); if (error) return error; ASSERT(ip != NULL); if (ip->i_itemp == NULL) xfs_inode_item_init(ip, mp); iip = ip->i_itemp; xfs_trans_add_item(tp, (xfs_log_item_t *)(iip)); /* initialize i_transp so we can find it incore */ ip->i_transp = tp; *ipp = ip; return 0; } void libxfs_trans_iput( xfs_trans_t *tp, xfs_inode_t *ip, uint lock_flags) { xfs_inode_log_item_t *iip; if (tp == NULL) { libxfs_iput(ip, lock_flags); return; } ASSERT(ip->i_transp == tp); iip = ip->i_itemp; ASSERT(iip != NULL); xfs_trans_del_item(&iip->ili_item); libxfs_iput(ip, lock_flags); } void libxfs_trans_ijoin( xfs_trans_t *tp, xfs_inode_t *ip, uint lock_flags) { xfs_inode_log_item_t *iip; ASSERT(ip->i_transp == NULL); if (ip->i_itemp == NULL) xfs_inode_item_init(ip, ip->i_mount); iip = ip->i_itemp; ASSERT(iip->ili_flags == 0); ASSERT(iip->ili_inode != NULL); xfs_trans_add_item(tp, (xfs_log_item_t *)(iip)); ip->i_transp = tp; #ifdef XACT_DEBUG fprintf(stderr, "ijoin'd inode %llu, transaction %p\n", ip->i_ino, tp); #endif } void libxfs_trans_ijoin_ref( xfs_trans_t *tp, xfs_inode_t *ip, int lock_flags) { ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); xfs_trans_ijoin(tp, ip, lock_flags); ip->i_itemp->ili_lock_flags = lock_flags; #ifdef XACT_DEBUG fprintf(stderr, "ijoin_ref'd inode %llu, transaction %p\n", ip->i_ino, tp); #endif } void libxfs_trans_ihold( xfs_trans_t *tp, xfs_inode_t *ip) { ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); ip->i_itemp->ili_lock_flags = 1; #ifdef XACT_DEBUG fprintf(stderr, "ihold'd inode %llu, transaction %p\n", ip->i_ino, tp); #endif } void libxfs_trans_inode_alloc_buf( xfs_trans_t *tp, xfs_buf_t *bp) { xfs_buf_log_item_t *bip; ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; } /* * This is called to mark the fields indicated in fieldmask as needing * to be logged when the transaction is committed. The inode must * already be associated with the given transaction. * * The values for fieldmask are defined in xfs_inode_item.h. We always * log all of the core inode if any of it has changed, and we always log * all of the inline data/extents/b-tree root if any of them has changed. */ void xfs_trans_log_inode( xfs_trans_t *tp, xfs_inode_t *ip, uint flags) { ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); #ifdef XACT_DEBUG fprintf(stderr, "dirtied inode %llu, transaction %p\n", ip->i_ino, tp); #endif tp->t_flags |= XFS_TRANS_DIRTY; ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY; /* * Always OR in the bits from the ili_last_fields field. * This is to coordinate with the xfs_iflush() and xfs_iflush_done() * routines in the eventual clearing of the ilf_fields bits. * See the big comment in xfs_iflush() for an explanation of * this coordination mechanism. */ flags |= ip->i_itemp->ili_last_fields; ip->i_itemp->ili_format.ilf_fields |= flags; } /* * This is called to mark bytes first through last inclusive of the given * buffer as needing to be logged when the transaction is committed. * The buffer must already be associated with the given transaction. * * First and last are numbers relative to the beginning of this buffer, * so the first byte in the buffer is numbered 0 regardless of the * value of b_blkno. */ void libxfs_trans_log_buf( xfs_trans_t *tp, xfs_buf_t *bp, uint first, uint last) { xfs_buf_log_item_t *bip; ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp))); #ifdef XACT_DEBUG fprintf(stderr, "dirtied buffer %p, transaction %p\n", bp, tp); #endif bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); tp->t_flags |= XFS_TRANS_DIRTY; bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; xfs_buf_item_log(bip, first, last); } void libxfs_trans_brelse( xfs_trans_t *tp, xfs_buf_t *bp) { xfs_buf_log_item_t *bip; #ifdef XACT_DEBUG fprintf(stderr, "released buffer %p, transaction %p\n", bp, tp); #endif if (tp == NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL); libxfs_putbuf(bp); return; } ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); ASSERT(bip->bli_item.li_type == XFS_LI_BUF); if (bip->bli_recur > 0) { bip->bli_recur--; return; } /* If dirty/stale, can't release till transaction committed */ if (bip->bli_flags & XFS_BLI_STALE) return; if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY) return; xfs_trans_del_item(&bip->bli_item); if (bip->bli_flags & XFS_BLI_HOLD) bip->bli_flags &= ~XFS_BLI_HOLD; XFS_BUF_SET_FSPRIVATE2(bp, NULL); libxfs_putbuf(bp); } void libxfs_trans_binval( xfs_trans_t *tp, xfs_buf_t *bp) { xfs_buf_log_item_t *bip; #ifdef XACT_DEBUG fprintf(stderr, "binval'd buffer %p, transaction %p\n", bp, tp); #endif ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); if (bip->bli_flags & XFS_BLI_STALE) return; XFS_BUF_UNDELAYWRITE(bp); XFS_BUF_STALE(bp); bip->bli_flags |= XFS_BLI_STALE; bip->bli_flags &= ~XFS_BLI_DIRTY; bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF; bip->bli_format.blf_flags |= XFS_BLF_CANCEL; bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; tp->t_flags |= XFS_TRANS_DIRTY; } void libxfs_trans_bjoin( xfs_trans_t *tp, xfs_buf_t *bp) { xfs_buf_log_item_t *bip; ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL); #ifdef XACT_DEBUG fprintf(stderr, "bjoin'd buffer %p, transaction %p\n", bp, tp); #endif xfs_buf_item_init(bp, tp->t_mountp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); xfs_trans_add_item(tp, (xfs_log_item_t *)bip); XFS_BUF_SET_FSPRIVATE2(bp, tp); } void libxfs_trans_bhold( xfs_trans_t *tp, xfs_buf_t *bp) { xfs_buf_log_item_t *bip; ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); #ifdef XACT_DEBUG fprintf(stderr, "bhold'd buffer %p, transaction %p\n", bp, tp); #endif bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); bip->bli_flags |= XFS_BLI_HOLD; } xfs_buf_t * libxfs_trans_get_buf( xfs_trans_t *tp, dev_t dev, xfs_daddr_t d, int len, uint f) { xfs_buf_t *bp; xfs_buf_log_item_t *bip; xfs_buftarg_t bdev; if (tp == NULL) return libxfs_getbuf(dev, d, len); bdev.dev = dev; bp = xfs_trans_buf_item_match(tp, &bdev, d, len); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); ASSERT(bip != NULL); bip->bli_recur++; return bp; } bp = libxfs_getbuf(dev, d, len); if (bp == NULL) return NULL; #ifdef XACT_DEBUG fprintf(stderr, "trans_get_buf buffer %p, transaction %p\n", bp, tp); #endif xfs_buf_item_init(bp, tp->t_mountp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); bip->bli_recur = 0; xfs_trans_add_item(tp, (xfs_log_item_t *)bip); /* initialize b_fsprivate2 so we can find it incore */ XFS_BUF_SET_FSPRIVATE2(bp, tp); return bp; } xfs_buf_t * libxfs_trans_getsb( xfs_trans_t *tp, xfs_mount_t *mp, int flags) { xfs_buf_t *bp; xfs_buf_log_item_t *bip; xfs_buftarg_t bdev; int len; if (tp == NULL) return libxfs_getsb(mp, flags); bdev.dev = mp->m_dev; len = XFS_FSS_TO_BB(mp, 1); bp = xfs_trans_buf_item_match(tp, &bdev, XFS_SB_DADDR, len); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); ASSERT(bip != NULL); bip->bli_recur++; return bp; } bp = libxfs_getsb(mp, flags); #ifdef XACT_DEBUG fprintf(stderr, "trans_get_sb buffer %p, transaction %p\n", bp, tp); #endif xfs_buf_item_init(bp, mp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); bip->bli_recur = 0; xfs_trans_add_item(tp, (xfs_log_item_t *)bip); /* initialize b_fsprivate2 so we can find it incore */ XFS_BUF_SET_FSPRIVATE2(bp, tp); return bp; } int libxfs_trans_read_buf( xfs_mount_t *mp, xfs_trans_t *tp, dev_t dev, xfs_daddr_t blkno, int len, uint flags, xfs_buf_t **bpp) { xfs_buf_t *bp; xfs_buf_log_item_t *bip; xfs_buftarg_t bdev; int error; *bpp = NULL; if (tp == NULL) { bp = libxfs_readbuf(dev, blkno, len, flags); if (!bp) { return (flags & XBF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); } if (bp->b_error) goto out_relse; goto done; } bdev.dev = dev; bp = xfs_trans_buf_item_match(tp, &bdev, blkno, len); if (bp != NULL) { ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); bip->bli_recur++; goto done; } bp = libxfs_readbuf(dev, blkno, len, flags); if (!bp) { return (flags & XBF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); } if (bp->b_error) goto out_relse; #ifdef XACT_DEBUG fprintf(stderr, "trans_read_buf buffer %p, transaction %p\n", bp, tp); #endif xfs_buf_item_init(bp, tp->t_mountp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); bip->bli_recur = 0; xfs_trans_add_item(tp, (xfs_log_item_t *)bip); /* initialise b_fsprivate2 so we can find it incore */ XFS_BUF_SET_FSPRIVATE2(bp, tp); done: *bpp = bp; return 0; out_relse: error = bp->b_error; xfs_buf_relse(bp); return error; } /* * Record the indicated change to the given field for application * to the file system's superblock when the transaction commits. * For now, just store the change in the transaction structure. * Mark the transaction structure to indicate that the superblock * needs to be updated before committing. * * Originally derived from xfs_trans_mod_sb(). */ void libxfs_trans_mod_sb( xfs_trans_t *tp, uint field, long delta) { switch (field) { case XFS_TRANS_SB_RES_FDBLOCKS: return; case XFS_TRANS_SB_FDBLOCKS: tp->t_fdblocks_delta += delta; break; case XFS_TRANS_SB_ICOUNT: ASSERT(delta > 0); tp->t_icount_delta += delta; break; case XFS_TRANS_SB_IFREE: tp->t_ifree_delta += delta; break; case XFS_TRANS_SB_FREXTENTS: tp->t_frextents_delta += delta; break; default: ASSERT(0); return; } tp->t_flags |= (XFS_TRANS_SB_DIRTY | XFS_TRANS_DIRTY); } /* * Transaction commital code follows (i.e. write to disk in libxfs) */ static void inode_item_done( xfs_inode_log_item_t *iip) { xfs_dinode_t *dip; xfs_inode_t *ip; xfs_mount_t *mp; xfs_buf_t *bp; int error; extern kmem_zone_t *xfs_ili_zone; ip = iip->ili_inode; mp = iip->ili_item.li_mountp; ASSERT(ip != NULL); if (!(iip->ili_format.ilf_fields & XFS_ILOG_ALL)) { ip->i_transp = NULL; /* disassociate from transaction */ iip->ili_flags = 0; /* reset all flags */ goto ili_done; } /* * Get the buffer containing the on-disk inode. */ error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0); if (error) { fprintf(stderr, _("%s: warning - itobp failed (%d)\n"), progname, error); goto ili_done; } XFS_BUF_SET_FSPRIVATE(bp, iip); error = libxfs_iflush_int(ip, bp); if (error) { fprintf(stderr, _("%s: warning - iflush_int failed (%d)\n"), progname, error); goto ili_done; } ip->i_transp = NULL; /* disassociate from transaction */ XFS_BUF_SET_FSPRIVATE(bp, NULL); /* remove log item */ XFS_BUF_SET_FSPRIVATE2(bp, NULL); /* remove xact ptr */ libxfs_writebuf(bp, 0); #ifdef XACT_DEBUG fprintf(stderr, "flushing dirty inode %llu, buffer %p (hold=%u)\n", ip->i_ino, bp, iip->ili_lock_flags); #endif ili_done: if (iip->ili_lock_flags) { iip->ili_lock_flags = 0; return; } else { libxfs_iput(ip, 0); } if (ip->i_itemp) kmem_zone_free(xfs_ili_zone, ip->i_itemp); else ASSERT(0); ip->i_itemp = NULL; } static void buf_item_done( xfs_buf_log_item_t *bip) { xfs_buf_t *bp; int hold; extern kmem_zone_t *xfs_buf_item_zone; bp = bip->bli_buf; ASSERT(bp != NULL); XFS_BUF_SET_FSPRIVATE(bp, NULL); /* remove log item */ XFS_BUF_SET_FSPRIVATE2(bp, NULL); /* remove xact ptr */ hold = (bip->bli_flags & XFS_BLI_HOLD); if (bip->bli_flags & XFS_BLI_DIRTY) { #ifdef XACT_DEBUG fprintf(stderr, "flushing/staling buffer %p (hold=%d)\n", bp, hold); #endif libxfs_writebuf_int(bp, 0); } if (hold) bip->bli_flags &= ~XFS_BLI_HOLD; else libxfs_putbuf(bp); /* release the buf item */ kmem_zone_free(xfs_buf_item_zone, bip); } static void trans_committed( xfs_trans_t *tp) { struct xfs_log_item_desc *lidp, *next; list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { struct xfs_log_item *lip = lidp->lid_item; xfs_trans_del_item(lip); if (lip->li_type == XFS_LI_BUF) buf_item_done((xfs_buf_log_item_t *)lip); else if (lip->li_type == XFS_LI_INODE) inode_item_done((xfs_inode_log_item_t *)lip); else { fprintf(stderr, _("%s: unrecognised log item type\n"), progname); ASSERT(0); } } } static void buf_item_unlock( xfs_buf_log_item_t *bip) { xfs_buf_t *bp = bip->bli_buf; uint hold; /* Clear the buffer's association with this transaction. */ XFS_BUF_SET_FSPRIVATE2(bip->bli_buf, NULL); hold = bip->bli_flags & XFS_BLI_HOLD; bip->bli_flags &= ~XFS_BLI_HOLD; if (!hold) libxfs_putbuf(bp); } static void inode_item_unlock( xfs_inode_log_item_t *iip) { xfs_inode_t *ip = iip->ili_inode; /* Clear the transaction pointer in the inode. */ ip->i_transp = NULL; iip->ili_flags = 0; if (!iip->ili_lock_flags) libxfs_iput(ip, 0); else iip->ili_lock_flags = 0; } /* * Unlock all of the items of a transaction and free all the descriptors * of that transaction. */ void xfs_trans_free_items( struct xfs_trans *tp, int flags) { struct xfs_log_item_desc *lidp, *next; list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { struct xfs_log_item *lip = lidp->lid_item; xfs_trans_del_item(lip); if (lip->li_type == XFS_LI_BUF) buf_item_unlock((xfs_buf_log_item_t *)lip); else if (lip->li_type == XFS_LI_INODE) inode_item_unlock((xfs_inode_log_item_t *)lip); else { fprintf(stderr, _("%s: unrecognised log item type\n"), progname); ASSERT(0); } } } /* * Commit the changes represented by this transaction */ int libxfs_trans_commit( xfs_trans_t *tp, uint flags) { xfs_sb_t *sbp; if (tp == NULL) return 0; if (!(tp->t_flags & XFS_TRANS_DIRTY)) { #ifdef XACT_DEBUG fprintf(stderr, "committed clean transaction %p\n", tp); #endif xfs_trans_free_items(tp, flags); free(tp); tp = NULL; return 0; } if (tp->t_flags & XFS_TRANS_SB_DIRTY) { sbp = &(tp->t_mountp->m_sb); if (tp->t_icount_delta) sbp->sb_icount += tp->t_icount_delta; if (tp->t_ifree_delta) sbp->sb_ifree += tp->t_ifree_delta; if (tp->t_fdblocks_delta) sbp->sb_fdblocks += tp->t_fdblocks_delta; if (tp->t_frextents_delta) sbp->sb_frextents += tp->t_frextents_delta; xfs_mod_sb(tp, XFS_SB_ALL_BITS); } #ifdef XACT_DEBUG fprintf(stderr, "committing dirty transaction %p\n", tp); #endif trans_committed(tp); /* That's it for the transaction structure. Free it. */ free(tp); tp = NULL; return 0; } xfsprogs-3.1.9ubuntu2/libxfs/irix.c0000664000000000000000000000425011140033220014205 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include int platform_has_uuid = 0; extern char *progname; extern __int64_t findsize(char *); int platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) { return 0; } int platform_check_iswritable(char *name, char *block, struct stat64 *s, int fatal) { return 1; } int platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal) { return fatal; } void platform_flush_device(int fd, dev_t device) { return; } void platform_findsizes(char *path, int fd, long long *sz, int *bsz) { struct stat64 st; if (fstat64(fd, &st) < 0) { fprintf(stderr, _("%s: cannot stat the device file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } if ((st.st_mode & S_IFMT) == S_IFREG) { *sz = (long long)(st.st_size >> 9); } else { *sz = findsize(path); } *bsz = BBSIZE; } char * platform_findrawpath(char *path) { return findrawpath(path); } char * platform_findblockpath(char *path) { return findblockpath(path); } int platform_direct_blockdev(void) { return 0; } int platform_align_blockdev(void) { return (sizeof(void *)); } int platform_nproc(void) { return sysmp(MP_NPROCS); } unsigned long platform_physmem(void) { struct rminfo ri; if (sysmp(MP_SAGET, MPSA_RMINFO, &ri, sizeof(ri)) < 0) fprintf(stderr, _("%s: can't determine memory size\n"), progname); exit(1); } return (ri.physmem >> 10) * getpagesize(); /* kilobytes */ }xfsprogs-3.1.9ubuntu2/libxfs/freebsd.c0000664000000000000000000001014111660427362014665 0ustar /* * Copyright (c) 2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include int platform_has_uuid = 1; extern char *progname; int platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) { struct stat64 st; int cnt, i; struct statfs *fsinfo; if (!s) { if (stat64(block, &st) < 0) return 0; s = &st; } /* Remember, FreeBSD can now mount char devices! -- adrian */ if (((st.st_mode & S_IFMT) != S_IFBLK) && ((st.st_mode & S_IFMT) != S_IFCHR)) return 0; if ((cnt = getmntinfo(&fsinfo, MNT_NOWAIT)) == 0) { fprintf(stderr, _("%s: %s possibly contains a mounted filesystem\n"), progname, name); return 1; } for (i = 0; i < cnt; i++) { if (strcmp (name, fsinfo[i].f_mntfromname) != 0) continue; if (verbose) fprintf(stderr, _("%s: %s contains a mounted filesystem\n"), progname, name); break; } return (i < cnt); } int platform_check_iswritable(char *name, char *block, struct stat64 *s, int fatal) { int cnt, i; struct statfs *fsinfo; if ((cnt = getmntinfo(&fsinfo, MNT_NOWAIT)) == 0) { fprintf(stderr, _("%s: %s contains a possibly writable, " "mounted filesystem\n"), progname, name); return fatal; } for (i = 0; i < cnt; i++) { if (strcmp (name, fsinfo[i].f_mntfromname) != 0) continue; if (fsinfo[i].f_flags &= MNT_RDONLY) break; } if (i == cnt) { fprintf(stderr, _("%s: %s contains a mounted and writable " "filesystem\n"), progname, name); return fatal; } return 0; } int platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal) { return fatal; } void platform_flush_device(int fd, dev_t device) { return; } void platform_findsizes(char *path, int fd, long long *sz, int *bsz) { struct stat st; __int64_t size; u_int ssize; if (fstat(fd, &st) < 0) { fprintf(stderr, _("%s: " "cannot stat the device file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } if ((st.st_mode & S_IFMT) == S_IFREG) { *sz = (long long)(st.st_size >> 9); *bsz = 512; return; } if ((st.st_mode & S_IFMT) != S_IFCHR) { fprintf(stderr, _("%s: Not a device or file: \"%s\"\n"), progname, path); exit(1); } if (ioctl(fd, DIOCGMEDIASIZE, &size) != 0) { fprintf(stderr, _("%s: DIOCGMEDIASIZE failed on \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } if (ioctl(fd, DIOCGSECTORSIZE, &ssize) != 0) { fprintf(stderr, _("%s: " "DIOCGSECTORSIZE failed on \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } *sz = (long long) (size / ssize); *bsz = (int)ssize; } char * platform_findrawpath(char *path) { return path; } char * platform_findblockpath(char *path) { return path; } int platform_direct_blockdev(void) { return 0; } int platform_align_blockdev(void) { return (sizeof(void *)); } int platform_nproc(void) { int ncpu; size_t len = sizeof(ncpu); static int mib[2] = {CTL_HW, HW_NCPU}; if (sysctl(mib, 2, &ncpu, &len, NULL, 0) < 0) ncpu = 1; return ncpu; } unsigned long platform_physmem(void) { unsigned long physmem; size_t len = sizeof(physmem); static int mib[2] = {CTL_HW, HW_PHYSMEM}; if (sysctl(mib, 2, &physmem, &len, NULL, 0) < 0) { fprintf(stderr, _("%s: can't determine memory size\n"), progname); exit(1); } return physmem >> 10; } xfsprogs-3.1.9ubuntu2/libxfs/linux.c0000664000000000000000000001143711323235441014412 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define ustat __kernel_ustat #include #include #include #undef ustat #include #include #include #include int platform_has_uuid = 1; extern char *progname; static int max_block_alignment; #ifndef BLKGETSIZE64 # define BLKGETSIZE64 _IOR(0x12,114,size_t) #endif #ifndef BLKBSZSET # define BLKBSZSET _IOW(0x12,113,size_t) #endif #ifndef BLKSSZGET # define BLKSSZGET _IO(0x12,104) #endif #ifndef RAMDISK_MAJOR #define RAMDISK_MAJOR 1 /* ramdisk major number */ #endif #define PROC_MOUNTED "/proc/mounts" int platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) { /* Pad ust; pre-2.6.28 linux copies out too much in 32bit compat mode */ struct ustat ust[2]; struct stat64 st; if (!s) { if (stat64(block, &st) < 0) return 0; if ((st.st_mode & S_IFMT) != S_IFBLK) return 0; s = &st; } if (ustat(s->st_rdev, ust) >= 0) { if (verbose) fprintf(stderr, _("%s: %s contains a mounted filesystem\n"), progname, name); return 1; } return 0; } int platform_check_iswritable(char *name, char *block, struct stat64 *s, int fatal) { int sts = 0; FILE *f; struct stat64 mst; struct mntent *mnt; char mounts[MAXPATHLEN]; strcpy(mounts, (!access(PROC_MOUNTED, R_OK)) ? PROC_MOUNTED : MOUNTED); if ((f = setmntent(mounts, "r")) == NULL) { fprintf(stderr, _("%s: %s contains a possibly writable, " "mounted filesystem\n"), progname, name); return fatal; } while ((mnt = getmntent(f)) != NULL) { if (stat64(mnt->mnt_fsname, &mst) < 0) continue; if ((mst.st_mode & S_IFMT) != S_IFBLK) continue; if (mst.st_rdev == s->st_rdev && hasmntopt(mnt, MNTOPT_RO) != NULL) break; } if (mnt == NULL) { fprintf(stderr, _("%s: %s contains a mounted and writable " "filesystem\n"), progname, name); sts = fatal; } endmntent(f); return sts; } int platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal) { int error = 0; if (major(device) != RAMDISK_MAJOR) { if ((error = ioctl(fd, BLKBSZSET, &blocksize)) < 0) { fprintf(stderr, _("%s: %s - cannot set blocksize " "%d on block device %s: %s\n"), progname, fatal ? "error": "warning", blocksize, path, strerror(errno)); } } return error; } void platform_flush_device(int fd, dev_t device) { if (major(device) != RAMDISK_MAJOR) ioctl(fd, BLKFLSBUF, 0); } void platform_findsizes(char *path, int fd, long long *sz, int *bsz) { struct stat64 st; __uint64_t size; int error; if (fstat64(fd, &st) < 0) { fprintf(stderr, _("%s: " "cannot stat the device file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } if ((st.st_mode & S_IFMT) == S_IFREG) { *sz = (long long)(st.st_size >> 9); *bsz = BBSIZE; if (BBSIZE > max_block_alignment) max_block_alignment = BBSIZE; return; } error = ioctl(fd, BLKGETSIZE64, &size); if (error >= 0) { /* BLKGETSIZE64 returns size in bytes not 512-byte blocks */ *sz = (long long)(size >> 9); } else { /* If BLKGETSIZE64 fails, try BLKGETSIZE */ unsigned long tmpsize; error = ioctl(fd, BLKGETSIZE, &tmpsize); if (error < 0) { fprintf(stderr, _("%s: can't determine device size\n"), progname); exit(1); } *sz = (long long)tmpsize; } if (ioctl(fd, BLKSSZGET, bsz) < 0) { fprintf(stderr, _("%s: warning - cannot get sector size " "from block device %s: %s\n"), progname, path, strerror(errno)); *bsz = BBSIZE; } if (*bsz > max_block_alignment) max_block_alignment = *bsz; } char * platform_findrawpath(char *path) { return path; } char * platform_findblockpath(char *path) { return path; } int platform_direct_blockdev(void) { return 1; } int platform_align_blockdev(void) { if (!max_block_alignment) return getpagesize(); return max_block_alignment; } int platform_nproc(void) { return sysconf(_SC_NPROCESSORS_ONLN); } unsigned long platform_physmem(void) { struct sysinfo si; if (sysinfo(&si) < 0) { fprintf(stderr, _("%s: can't determine memory size\n"), progname); exit(1); } return (si.totalram >> 10) * si.mem_unit; /* kilobytes */ } xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_data.c0000664000000000000000000006061211140033220015747 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #ifdef DEBUG /* * Check the consistency of the data block. * The input can also be a block-format directory. * Pop an assert if we find anything bad. */ void xfs_dir2_data_check( xfs_inode_t *dp, /* incore inode pointer */ xfs_dabuf_t *bp) /* data block's buffer */ { xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ xfs_dir2_data_free_t *bf; /* bestfree table */ xfs_dir2_block_tail_t *btp=NULL; /* block tail */ int count; /* count of entries found */ xfs_dir2_data_t *d; /* data block pointer */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_free_t *dfp; /* bestfree entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ char *endp; /* end of useful data */ int freeseen; /* mask of bestfrees seen */ xfs_dahash_t hash; /* hash of current name */ int i; /* leaf index */ int lastfree; /* last entry was unused */ xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */ xfs_mount_t *mp; /* filesystem mount point */ char *p; /* current data position */ int stale; /* count of stale leaves */ struct xfs_name name; mp = dp->i_mount; d = bp->data; ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); bf = d->hdr.bestfree; p = (char *)d->u; if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); lep = xfs_dir2_block_leaf_p(btp); endp = (char *)lep; } else endp = (char *)d + mp->m_dirblksize; count = lastfree = freeseen = 0; /* * Account for zero bestfree entries. */ if (!bf[0].length) { ASSERT(!bf[0].offset); freeseen |= 1 << 0; } if (!bf[1].length) { ASSERT(!bf[1].offset); freeseen |= 1 << 1; } if (!bf[2].length) { ASSERT(!bf[2].offset); freeseen |= 1 << 2; } ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length)); ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length)); /* * Loop over the data/unused entries. */ while (p < endp) { dup = (xfs_dir2_data_unused_t *)p; /* * If it's unused, look for the space in the bestfree table. * If we find it, account for that, else make sure it * doesn't need to be there. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ASSERT(lastfree == 0); ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == (char *)dup - (char *)d); dfp = xfs_dir2_data_freefind(d, dup); if (dfp) { i = (int)(dfp - bf); ASSERT((freeseen & (1 << i)) == 0); freeseen |= 1 << i; } else { ASSERT(be16_to_cpu(dup->length) <= be16_to_cpu(bf[2].length)); } p += be16_to_cpu(dup->length); lastfree = 1; continue; } /* * It's a real entry. Validate the fields. * If this is a block directory then make sure it's * in the leaf section of the block. * The linear search is crude but this is DEBUG code. */ dep = (xfs_dir2_data_entry_t *)p; ASSERT(dep->namelen != 0); ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == (char *)dep - (char *)d); count++; lastfree = 0; if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)d)); name.name = dep->name; name.len = dep->namelen; hash = mp->m_dirnameops->hashname(&name); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) break; } ASSERT(i < be32_to_cpu(btp->count)); } p += xfs_dir2_data_entsize(dep->namelen); } /* * Need to have seen all the entries and all the bestfree slots. */ ASSERT(freeseen == 7); if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; if (i > 0) ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval)); } ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); ASSERT(stale == be32_to_cpu(btp->stale)); } } #endif /* * Given a data block and an unused entry from that block, * return the bestfree entry if any that corresponds to it. */ xfs_dir2_data_free_t * xfs_dir2_data_freefind( xfs_dir2_data_t *d, /* data block */ xfs_dir2_data_unused_t *dup) /* data unused entry */ { xfs_dir2_data_free_t *dfp; /* bestfree entry */ xfs_dir2_data_aoff_t off; /* offset value needed */ #if defined(DEBUG) && defined(__KERNEL__) int matched; /* matched the value */ int seenzero; /* saw a 0 bestfree entry */ #endif off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d); #if defined(DEBUG) && defined(__KERNEL__) /* * Validate some consistency in the bestfree table. * Check order, non-overlapping entries, and if we find the * one we're looking for it has to be exact. */ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) { ASSERT(!dfp->length); seenzero = 1; continue; } ASSERT(seenzero == 0); if (be16_to_cpu(dfp->offset) == off) { matched = 1; ASSERT(dfp->length == dup->length); } else if (off < be16_to_cpu(dfp->offset)) ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset)); else ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); if (dfp > &d->hdr.bestfree[0]) ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); } #endif /* * If this is smaller than the smallest bestfree entry, * it can't be there since they're sorted. */ if (be16_to_cpu(dup->length) < be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; /* * Look at the three bestfree entries for our guy. */ for (dfp = &d->hdr.bestfree[0]; dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) return NULL; if (be16_to_cpu(dfp->offset) == off) return dfp; } /* * Didn't find it. This only happens if there are duplicate lengths. */ return NULL; } /* * Insert an unused-space entry into the bestfree table. */ xfs_dir2_data_free_t * /* entry inserted */ xfs_dir2_data_freeinsert( xfs_dir2_data_t *d, /* data block pointer */ xfs_dir2_data_unused_t *dup, /* unused space */ int *loghead) /* log the data header (out) */ { xfs_dir2_data_free_t *dfp; /* bestfree table pointer */ xfs_dir2_data_free_t new; /* new bestfree entry */ #ifdef __KERNEL__ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif dfp = d->hdr.bestfree; new.length = dup->length; new.offset = cpu_to_be16((char *)dup - (char *)d); /* * Insert at position 0, 1, or 2; or not at all. */ if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) { dfp[2] = dfp[1]; dfp[1] = dfp[0]; dfp[0] = new; *loghead = 1; return &dfp[0]; } if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) { dfp[2] = dfp[1]; dfp[1] = new; *loghead = 1; return &dfp[1]; } if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) { dfp[2] = new; *loghead = 1; return &dfp[2]; } return NULL; } /* * Remove a bestfree entry from the table. */ STATIC void xfs_dir2_data_freeremove( xfs_dir2_data_t *d, /* data block pointer */ xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ int *loghead) /* out: log data header */ { #ifdef __KERNEL__ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif /* * It's the first entry, slide the next 2 up. */ if (dfp == &d->hdr.bestfree[0]) { d->hdr.bestfree[0] = d->hdr.bestfree[1]; d->hdr.bestfree[1] = d->hdr.bestfree[2]; } /* * It's the second entry, slide the 3rd entry up. */ else if (dfp == &d->hdr.bestfree[1]) d->hdr.bestfree[1] = d->hdr.bestfree[2]; /* * Must be the last entry. */ else ASSERT(dfp == &d->hdr.bestfree[2]); /* * Clear the 3rd entry, must be zero now. */ d->hdr.bestfree[2].length = 0; d->hdr.bestfree[2].offset = 0; *loghead = 1; } /* * Given a data block, reconstruct its bestfree map. */ void xfs_dir2_data_freescan( xfs_mount_t *mp, /* filesystem mount point */ xfs_dir2_data_t *d, /* data block pointer */ int *loghead) /* out: log data header */ { xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* active data entry */ xfs_dir2_data_unused_t *dup; /* unused data entry */ char *endp; /* end of block's data */ char *p; /* current entry pointer */ #ifdef __KERNEL__ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); #endif /* * Start by clearing the table. */ memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree)); *loghead = 1; /* * Set up pointers. */ p = (char *)d->u; if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); endp = (char *)xfs_dir2_block_leaf_p(btp); } else endp = (char *)d + mp->m_dirblksize; /* * Loop over the block's entries. */ while (p < endp) { dup = (xfs_dir2_data_unused_t *)p; /* * If it's a free entry, insert it. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); xfs_dir2_data_freeinsert(d, dup, loghead); p += be16_to_cpu(dup->length); } /* * For active entries, check their tags and skip them. */ else { dep = (xfs_dir2_data_entry_t *)p; ASSERT((char *)dep - (char *)d == be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); p += xfs_dir2_data_entsize(dep->namelen); } } } /* * Initialize a data block at the given block number in the directory. * Give back the buffer for the created block. */ int /* error */ xfs_dir2_data_init( xfs_da_args_t *args, /* directory operation args */ xfs_dir2_db_t blkno, /* logical dir block number */ xfs_dabuf_t **bpp) /* output block buffer */ { xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_data_t *d; /* pointer to block */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ int error; /* error return value */ int i; /* bestfree index */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ int t; /* temp */ dp = args->dp; mp = dp->i_mount; tp = args->trans; /* * Get the buffer set up for the block. */ error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, XFS_DATA_FORK); if (error) { return error; } ASSERT(bp != NULL); /* * Initialize the header. */ d = bp->data; d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr)); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { d->hdr.bestfree[i].length = 0; d->hdr.bestfree[i].offset = 0; } /* * Set up an unused entry for the block's body. */ dup = &d->u[0].unused; dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); t=mp->m_dirblksize - (uint)sizeof(d->hdr); d->hdr.bestfree[0].length = cpu_to_be16(t); dup->length = cpu_to_be16(t); *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); /* * Log it and return it. */ xfs_dir2_data_log_header(tp, bp); xfs_dir2_data_log_unused(tp, bp, dup); *bpp = bp; return 0; } /* * Log an active data entry from the block. */ void xfs_dir2_data_log_entry( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* block buffer */ xfs_dir2_data_entry_t *dep) /* data entry pointer */ { xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - (char *)d - 1)); } /* * Log a data block header. */ void xfs_dir2_data_log_header( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* block buffer */ { xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), (uint)(sizeof(d->hdr) - 1)); } /* * Log a data unused entry. */ void xfs_dir2_data_log_unused( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* block buffer */ xfs_dir2_data_unused_t *dup) /* data unused pointer */ { xfs_dir2_data_t *d; /* data block pointer */ d = bp->data; ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); /* * Log the first part of the unused entry. */ xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d), (uint)((char *)&dup->length + sizeof(dup->length) - 1 - (char *)d)); /* * Log the end (tag) of the unused entry. */ xfs_da_log_buf(tp, bp, (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + sizeof(xfs_dir2_data_off_t) - 1)); } /* * Make a byte range in the data block unused. * Its current contents are unimportant. */ void xfs_dir2_data_make_free( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* block buffer */ xfs_dir2_data_aoff_t offset, /* starting byte offset */ xfs_dir2_data_aoff_t len, /* length in bytes */ int *needlogp, /* out: log header */ int *needscanp) /* out: regen bestfree */ { xfs_dir2_data_t *d; /* data block pointer */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ char *endptr; /* end of data area */ xfs_mount_t *mp; /* filesystem mount point */ int needscan; /* need to regen bestfree */ xfs_dir2_data_unused_t *newdup; /* new unused entry */ xfs_dir2_data_unused_t *postdup; /* unused entry after us */ xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ mp = tp->t_mountp; d = bp->data; /* * Figure out where the end of the data area is. */ if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC) endptr = (char *)d + mp->m_dirblksize; else { xfs_dir2_block_tail_t *btp; /* block tail */ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); endptr = (char *)xfs_dir2_block_leaf_p(btp); } /* * If this isn't the start of the block, then back up to * the previous entry and see if it's free. */ if (offset > sizeof(d->hdr)) { __be16 *tagp; /* tag just before us */ tagp = (__be16 *)((char *)d + offset) - 1; prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp)); if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) prevdup = NULL; } else prevdup = NULL; /* * If this isn't the end of the block, see if the entry after * us is free. */ if ((char *)d + offset + len < endptr) { postdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) postdup = NULL; } else postdup = NULL; ASSERT(*needscanp == 0); needscan = 0; /* * Previous and following entries are both free, * merge everything into a single free entry. */ if (prevdup && postdup) { xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ /* * See if prevdup and/or postdup are in bestfree table. */ dfp = xfs_dir2_data_freefind(d, prevdup); dfp2 = xfs_dir2_data_freefind(d, postdup); /* * We need a rescan unless there are exactly 2 free entries * namely our two. Then we know what's happening, otherwise * since the third bestfree is there, there might be more * entries. */ needscan = (d->hdr.bestfree[2].length != 0); /* * Fix up the new big freespace. */ be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(prevdup) = cpu_to_be16((char *)prevdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, prevdup); if (!needscan) { /* * Has to be the case that entries 0 and 1 are * dfp and dfp2 (don't know which is which), and * entry 2 is empty. * Remove entry 1 first then entry 0. */ ASSERT(dfp && dfp2); if (dfp == &d->hdr.bestfree[1]) { dfp = &d->hdr.bestfree[0]; ASSERT(dfp2 == dfp); dfp2 = &d->hdr.bestfree[1]; } xfs_dir2_data_freeremove(d, dfp2, needlogp); xfs_dir2_data_freeremove(d, dfp, needlogp); /* * Now insert the new entry. */ dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); ASSERT(dfp == &d->hdr.bestfree[0]); ASSERT(dfp->length == prevdup->length); ASSERT(!dfp[1].length); ASSERT(!dfp[2].length); } } /* * The entry before us is free, merge with it. */ else if (prevdup) { dfp = xfs_dir2_data_freefind(d, prevdup); be16_add_cpu(&prevdup->length, len); *xfs_dir2_data_unused_tag_p(prevdup) = cpu_to_be16((char *)prevdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, prevdup); /* * If the previous entry was in the table, the new entry * is longer, so it will be in the table too. Remove * the old one and add the new one. */ if (dfp) { xfs_dir2_data_freeremove(d, dfp, needlogp); (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(prevdup->length) > be16_to_cpu(d->hdr.bestfree[2].length); } } /* * The following entry is free, merge with it. */ else if (postdup) { dfp = xfs_dir2_data_freefind(d, postdup); newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(newdup) = cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If the following entry was in the table, the new entry * is longer, so it will be in the table too. Remove * the old one and add the new one. */ if (dfp) { xfs_dir2_data_freeremove(d, dfp, needlogp); (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(newdup->length) > be16_to_cpu(d->hdr.bestfree[2].length); } } /* * Neither neighbor is free. Make a new entry. */ else { newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len); *xfs_dir2_data_unused_tag_p(newdup) = cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); } *needscanp = needscan; } /* * Take a byte range out of an existing unused space and make it un-free. */ void xfs_dir2_data_use_free( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* data block buffer */ xfs_dir2_data_unused_t *dup, /* unused entry */ xfs_dir2_data_aoff_t offset, /* starting offset to use */ xfs_dir2_data_aoff_t len, /* length to use */ int *needlogp, /* out: need to log header */ int *needscanp) /* out: need regen bestfree */ { xfs_dir2_data_t *d; /* data block */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ int matchback; /* matches end of freespace */ int matchfront; /* matches start of freespace */ int needscan; /* need to regen bestfree */ xfs_dir2_data_unused_t *newdup; /* new unused entry */ xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ int oldlen; /* old unused entry's length */ d = bp->data; ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); ASSERT(offset >= (char *)dup - (char *)d); ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); /* * Look up the entry in the bestfree table. */ dfp = xfs_dir2_data_freefind(d, dup); oldlen = be16_to_cpu(dup->length); ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length)); /* * Check for alignment with front and back of the entry. */ matchfront = (char *)dup - (char *)d == offset; matchback = (char *)dup + oldlen - (char *)d == offset + len; ASSERT(*needscanp == 0); needscan = 0; /* * If we matched it exactly we just need to get rid of it from * the bestfree table. */ if (matchfront && matchback) { if (dfp) { needscan = (d->hdr.bestfree[2].offset != 0); if (!needscan) xfs_dir2_data_freeremove(d, dfp, needlogp); } } /* * We match the first part of the entry. * Make a new entry with the remaining freespace. */ else if (matchfront) { newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(oldlen - len); *xfs_dir2_data_unused_tag_p(newdup) = cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { xfs_dir2_data_freeremove(d, dfp, needlogp); dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ needscan = dfp == &d->hdr.bestfree[2]; } } /* * We match the last part of the entry. * Trim the allocated space off the tail of the entry. */ else if (matchback) { newdup = dup; newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { xfs_dir2_data_freeremove(d, dfp, needlogp); dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ needscan = dfp == &d->hdr.bestfree[2]; } } /* * Poking out the middle of an entry. * Make two new entries. */ else { newdup = dup; newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = cpu_to_be16((char *)newdup - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup); newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); *xfs_dir2_data_unused_tag_p(newdup2) = cpu_to_be16((char *)newdup2 - (char *)d); xfs_dir2_data_log_unused(tp, bp, newdup2); /* * If the old entry was in the table, we need to scan * if the 3rd entry was valid, since these entries * are smaller than the old one. * If we don't need to scan that means there were 1 or 2 * entries in the table, and removing the old and adding * the 2 new will work. */ if (dfp) { needscan = (d->hdr.bestfree[2].length != 0); if (!needscan) { xfs_dir2_data_freeremove(d, dfp, needlogp); (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); (void)xfs_dir2_data_freeinsert(d, newdup2, needlogp); } } } *needscanp = needscan; } xfsprogs-3.1.9ubuntu2/libxfs/darwin.c0000664000000000000000000000567711140033220014534 0ustar /* * Copyright (c) 2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include int platform_has_uuid = 1; extern char *progname; int platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) { return 0; } int platform_check_iswritable(char *name, char *block, struct stat64 *s, int fatal) { int fd, writable; if ((fd = open(block, O_RDONLY, 0)) < 0) { fprintf(stderr, _("%s: " "error opening the device special file \"%s\": %s\n"), progname, block, strerror(errno)); exit(1); } if (ioctl(fd, DKIOCISWRITABLE, &writable) < 0) { fprintf(stderr, _("%s: can't tell if \"%s\" is writable: %s\n"), progname, block, strerror(errno)); exit(1); } close(fd); return (writable == 0); } int platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal) { return fatal; } void platform_flush_device(int fd, dev_t device) { ioctl(fd, DKIOCSYNCHRONIZECACHE, NULL); } void platform_findsizes(char *path, int fd, long long *sz, int *bsz) { __uint64_t size; struct stat64 st; if (fstat64(fd, &st) < 0) { fprintf(stderr, _("%s: cannot stat the device file \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } if ((st.st_mode & S_IFMT) == S_IFREG) { *sz = (long long)(st.st_size >> 9); *bsz = BBSIZE; return; } if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size) < 0) { fprintf(stderr, _("%s: can't determine device size: %s\n"), progname, strerror(errno)); exit(1); } *sz = (long long)size; *bsz = BBSIZE; } char * platform_findrawpath(char *path) { return path; } char * platform_findblockpath(char *path) { return path; } int platform_direct_blockdev(void) { return 0; } int platform_align_blockdev(void) { return (sizeof(void *)); } int platform_nproc(void) { int ncpu; size_t len = sizeof(ncpu); static int mib[2] = {CTL_HW, HW_NCPU}; if (sysctl(mib, 2, &ncpu, &len, NULL, 0) < 0) ncpu = 1; return ncpu; } unsigned long platform_physmem(void) { unsigned long physmem; size_t len = sizeof(physmem); static int mib[2] = {CTL_HW, HW_PHYSMEM}; if (sysctl(mib, 2, &physmem, &len, NULL, 0) < 0) { fprintf(stderr, _("%s: can't determine memory size\n"), progname); exit(1); } return physmem >> 10; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap_btree.c0000664000000000000000000005426111650373061016241 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Determine the extent state. */ /* ARGSUSED */ STATIC xfs_exntst_t xfs_extent_state( xfs_filblks_t blks, int extent_flag) { if (extent_flag) { ASSERT(blks != 0); /* saved for DMIG */ return XFS_EXT_UNWRITTEN; } return XFS_EXT_NORM; } /* * Convert on-disk form of btree root to in-memory form. */ void xfs_bmdr_to_bmbt( struct xfs_mount *mp, xfs_bmdr_block_t *dblock, int dblocklen, struct xfs_btree_block *rblock, int rblocklen) { int dmxr; xfs_bmbt_key_t *fkp; __be64 *fpp; xfs_bmbt_key_t *tkp; __be64 *tpp; rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); rblock->bb_level = dblock->bb_level; ASSERT(be16_to_cpu(rblock->bb_level) > 0); rblock->bb_numrecs = dblock->bb_numrecs; rblock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); rblock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); fkp = XFS_BMDR_KEY_ADDR(dblock, 1); tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* * Convert a compressed bmap extent record to an uncompressed form. * This code must be in sync with the routines xfs_bmbt_get_startoff, * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. */ STATIC void __xfs_bmbt_get_all( __uint64_t l0, __uint64_t l1, xfs_bmbt_irec_t *s) { int ext_flag; xfs_exntst_t st; ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); s->br_startoff = ((xfs_fileoff_t)l0 & xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; #if XFS_BIG_BLKNOS s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) | (((xfs_fsblock_t)l1) >> 21); #else #ifdef DEBUG { xfs_dfsbno_t b; b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)l1) >> 21); ASSERT((b >> 32) == 0 || isnulldstartblock(b)); s->br_startblock = (xfs_fsblock_t)b; } #else /* !DEBUG */ s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21); #endif /* DEBUG */ #endif /* XFS_BIG_BLKNOS */ s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21)); /* This is xfs_extent_state() in-line */ if (ext_flag) { ASSERT(s->br_blockcount != 0); /* saved for DMIG */ st = XFS_EXT_UNWRITTEN; } else st = XFS_EXT_NORM; s->br_state = st; } void xfs_bmbt_get_all( xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s) { __xfs_bmbt_get_all(r->l0, r->l1, s); } /* * Extract the blockcount field from an in memory bmap extent record. */ xfs_filblks_t xfs_bmbt_get_blockcount( xfs_bmbt_rec_host_t *r) { return (xfs_filblks_t)(r->l1 & xfs_mask64lo(21)); } /* * Extract the startblock field from an in memory bmap extent record. */ xfs_fsblock_t xfs_bmbt_get_startblock( xfs_bmbt_rec_host_t *r) { #if XFS_BIG_BLKNOS return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) | (((xfs_fsblock_t)r->l1) >> 21); #else #ifdef DEBUG xfs_dfsbno_t b; b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)r->l1) >> 21); ASSERT((b >> 32) == 0 || isnulldstartblock(b)); return (xfs_fsblock_t)b; #else /* !DEBUG */ return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); #endif /* DEBUG */ #endif /* XFS_BIG_BLKNOS */ } /* * Extract the startoff field from an in memory bmap extent record. */ xfs_fileoff_t xfs_bmbt_get_startoff( xfs_bmbt_rec_host_t *r) { return ((xfs_fileoff_t)r->l0 & xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; } xfs_exntst_t xfs_bmbt_get_state( xfs_bmbt_rec_host_t *r) { int ext_flag; ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN)); return xfs_extent_state(xfs_bmbt_get_blockcount(r), ext_flag); } /* * Extract the blockcount field from an on disk bmap extent record. */ xfs_filblks_t xfs_bmbt_disk_get_blockcount( xfs_bmbt_rec_t *r) { return (xfs_filblks_t)(be64_to_cpu(r->l1) & xfs_mask64lo(21)); } /* * Extract the startoff field from a disk format bmap extent record. */ xfs_fileoff_t xfs_bmbt_disk_get_startoff( xfs_bmbt_rec_t *r) { return ((xfs_fileoff_t)be64_to_cpu(r->l0) & xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; } /* * Set all the fields in a bmap extent record from the arguments. */ void xfs_bmbt_set_allf( xfs_bmbt_rec_host_t *r, xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t blockcount, xfs_exntst_t state) { int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | ((xfs_bmbt_rec_base_t)startblock >> 43); r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); #else /* !XFS_BIG_BLKNOS */ if (isnullstartblock(startblock)) { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | (xfs_bmbt_rec_base_t)xfs_mask64lo(9); r->l1 = xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } else { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9); r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } #endif /* XFS_BIG_BLKNOS */ } /* * Set all the fields in a bmap extent record from the uncompressed form. */ void xfs_bmbt_set_all( xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s) { xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock, s->br_blockcount, s->br_state); } /* * Set all the fields in a disk format bmap extent record from the arguments. */ void xfs_bmbt_disk_set_allf( xfs_bmbt_rec_t *r, xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t blockcount, xfs_exntst_t state) { int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | ((xfs_bmbt_rec_base_t)startblock >> 43)); r->l1 = cpu_to_be64( ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); #else /* !XFS_BIG_BLKNOS */ if (isnullstartblock(startblock)) { r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); r->l1 = cpu_to_be64(xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); } else { r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9)); r->l1 = cpu_to_be64( ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); } #endif /* XFS_BIG_BLKNOS */ } /* * Set all the fields in a bmap extent record from the uncompressed form. */ STATIC void xfs_bmbt_disk_set_all( xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s) { xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock, s->br_blockcount, s->br_state); } /* * Set the blockcount field in a bmap extent record. */ void xfs_bmbt_set_blockcount( xfs_bmbt_rec_host_t *r, xfs_filblks_t v) { ASSERT((v & xfs_mask64hi(43)) == 0); r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64hi(43)) | (xfs_bmbt_rec_base_t)(v & xfs_mask64lo(21)); } /* * Set the startblock field in a bmap extent record. */ void xfs_bmbt_set_startblock( xfs_bmbt_rec_host_t *r, xfs_fsblock_t v) { #if XFS_BIG_BLKNOS ASSERT((v & xfs_mask64hi(12)) == 0); r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) | (xfs_bmbt_rec_base_t)(v >> 43); r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | (xfs_bmbt_rec_base_t)(v << 21); #else /* !XFS_BIG_BLKNOS */ if (isnullstartblock(v)) { r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9); r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)v << 21) | (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } else { r->l0 &= ~(xfs_bmbt_rec_base_t)xfs_mask64lo(9); r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } #endif /* XFS_BIG_BLKNOS */ } /* * Set the startoff field in a bmap extent record. */ void xfs_bmbt_set_startoff( xfs_bmbt_rec_host_t *r, xfs_fileoff_t v) { ASSERT((v & xfs_mask64hi(9)) == 0); r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) xfs_mask64hi(1)) | ((xfs_bmbt_rec_base_t)v << 9) | (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); } /* * Set the extent state field in a bmap extent record. */ void xfs_bmbt_set_state( xfs_bmbt_rec_host_t *r, xfs_exntst_t v) { ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); if (v == XFS_EXT_NORM) r->l0 &= xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN); else r->l0 |= xfs_mask64hi(BMBT_EXNTFLAG_BITLEN); } /* * Convert in-memory form of btree root to on-disk form. */ void xfs_bmbt_to_bmdr( struct xfs_mount *mp, struct xfs_btree_block *rblock, int rblocklen, xfs_bmdr_block_t *dblock, int dblocklen) { int dmxr; xfs_bmbt_key_t *fkp; __be64 *fpp; xfs_bmbt_key_t *tkp; __be64 *tpp; ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); ASSERT(be64_to_cpu(rblock->bb_u.l.bb_leftsib) == NULLDFSBNO); ASSERT(be64_to_cpu(rblock->bb_u.l.bb_rightsib) == NULLDFSBNO); ASSERT(be16_to_cpu(rblock->bb_level) > 0); dblock->bb_level = rblock->bb_level; dblock->bb_numrecs = rblock->bb_numrecs; dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); tkp = XFS_BMDR_KEY_ADDR(dblock, 1); fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* * Check extent records, which have just been read, for * any bit in the extent flag field. ASSERT on debug * kernels, as this condition should not occur. * Return an error condition (1) if any flags found, * otherwise return 0. */ int xfs_check_nostate_extents( xfs_ifork_t *ifp, xfs_extnum_t idx, xfs_extnum_t num) { for (; num > 0; num--, idx++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); if ((ep->l0 >> (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { ASSERT(0); return 1; } } return 0; } STATIC struct xfs_btree_cur * xfs_bmbt_dup_cursor( struct xfs_btree_cur *cur) { struct xfs_btree_cur *new; new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_private.b.ip, cur->bc_private.b.whichfork); /* * Copy the firstblock, flist, and flags values, * since init cursor doesn't get them. */ new->bc_private.b.firstblock = cur->bc_private.b.firstblock; new->bc_private.b.flist = cur->bc_private.b.flist; new->bc_private.b.flags = cur->bc_private.b.flags; return new; } STATIC void xfs_bmbt_update_cursor( struct xfs_btree_cur *src, struct xfs_btree_cur *dst) { ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) || (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME)); ASSERT(dst->bc_private.b.flist == src->bc_private.b.flist); dst->bc_private.b.allocated += src->bc_private.b.allocated; dst->bc_private.b.firstblock = src->bc_private.b.firstblock; src->bc_private.b.allocated = 0; } STATIC int xfs_bmbt_alloc_block( struct xfs_btree_cur *cur, union xfs_btree_ptr *start, union xfs_btree_ptr *new, int length, int *stat) { xfs_alloc_arg_t args; /* block allocation args */ int error; /* error return value */ memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; args.fsbno = cur->bc_private.b.firstblock; args.firstblock = args.fsbno; if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); args.type = XFS_ALLOCTYPE_START_BNO; /* * Make sure there is sufficient room left in the AG to * complete a full tree split for an extent insert. If * we are converting the middle part of an extent then * we may need space for two tree splits. * * We are relying on the caller to make the correct block * reservation for this operation to succeed. If the * reservation amount is insufficient then we may fail a * block allocation here and corrupt the filesystem. */ args.minleft = xfs_trans_get_block_res(args.tp); } else if (cur->bc_private.b.flist->xbf_low) { args.type = XFS_ALLOCTYPE_START_BNO; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; } args.minlen = args.maxlen = args.prod = 1; args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { error = XFS_ERROR(ENOSPC); goto error0; } error = xfs_alloc_vextent(&args); if (error) goto error0; if (args.fsbno == NULLFSBLOCK && args.minleft) { /* * Could not find an AG with enough free space to satisfy * a full btree split. Try again without minleft and if * successful activate the lowspace algorithm. */ args.fsbno = 0; args.type = XFS_ALLOCTYPE_FIRST_AG; args.minleft = 0; error = xfs_alloc_vextent(&args); if (error) goto error0; cur->bc_private.b.flist->xbf_low = 1; } if (args.fsbno == NULLFSBLOCK) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } ASSERT(args.len == 1); cur->bc_private.b.firstblock = args.fsbno; cur->bc_private.b.allocated++; cur->bc_private.b.ip->i_d.di_nblocks++; xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE); xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip, XFS_TRANS_DQ_BCOUNT, 1L); new->l = cpu_to_be64(args.fsbno); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } STATIC int xfs_bmbt_free_block( struct xfs_btree_cur *cur, struct xfs_buf *bp) { struct xfs_mount *mp = cur->bc_mp; struct xfs_inode *ip = cur->bc_private.b.ip; struct xfs_trans *tp = cur->bc_tp; xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, bp); return 0; } STATIC int xfs_bmbt_get_minrecs( struct xfs_btree_cur *cur, int level) { if (level == cur->bc_nlevels - 1) { struct xfs_ifork *ifp; ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); return xfs_bmbt_maxrecs(cur->bc_mp, ifp->if_broot_bytes, level == 0) / 2; } return cur->bc_mp->m_bmap_dmnr[level != 0]; } int xfs_bmbt_get_maxrecs( struct xfs_btree_cur *cur, int level) { if (level == cur->bc_nlevels - 1) { struct xfs_ifork *ifp; ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); return xfs_bmbt_maxrecs(cur->bc_mp, ifp->if_broot_bytes, level == 0); } return cur->bc_mp->m_bmap_dmxr[level != 0]; } /* * Get the maximum records we could store in the on-disk format. * * For non-root nodes this is equivalent to xfs_bmbt_get_maxrecs, but * for the root node this checks the available space in the dinode fork * so that we can resize the in-memory buffer to match it. After a * resize to the maximum size this function returns the same value * as xfs_bmbt_get_maxrecs for the root node, too. */ STATIC int xfs_bmbt_get_dmaxrecs( struct xfs_btree_cur *cur, int level) { if (level != cur->bc_nlevels - 1) return cur->bc_mp->m_bmap_dmxr[level != 0]; return xfs_bmdr_maxrecs(cur->bc_mp, cur->bc_private.b.forksize, level == 0); } STATIC void xfs_bmbt_init_key_from_rec( union xfs_btree_key *key, union xfs_btree_rec *rec) { key->bmbt.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt)); } STATIC void xfs_bmbt_init_rec_from_key( union xfs_btree_key *key, union xfs_btree_rec *rec) { ASSERT(key->bmbt.br_startoff != 0); xfs_bmbt_disk_set_allf(&rec->bmbt, be64_to_cpu(key->bmbt.br_startoff), 0, 0, XFS_EXT_NORM); } STATIC void xfs_bmbt_init_rec_from_cur( struct xfs_btree_cur *cur, union xfs_btree_rec *rec) { xfs_bmbt_disk_set_all(&rec->bmbt, &cur->bc_rec.b); } STATIC void xfs_bmbt_init_ptr_from_cur( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { ptr->l = 0; } STATIC __int64_t xfs_bmbt_key_diff( struct xfs_btree_cur *cur, union xfs_btree_key *key) { return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) - cur->bc_rec.b.br_startoff; } #ifdef DEBUG STATIC int xfs_bmbt_keys_inorder( struct xfs_btree_cur *cur, union xfs_btree_key *k1, union xfs_btree_key *k2) { return be64_to_cpu(k1->bmbt.br_startoff) < be64_to_cpu(k2->bmbt.br_startoff); } STATIC int xfs_bmbt_recs_inorder( struct xfs_btree_cur *cur, union xfs_btree_rec *r1, union xfs_btree_rec *r2) { return xfs_bmbt_disk_get_startoff(&r1->bmbt) + xfs_bmbt_disk_get_blockcount(&r1->bmbt) <= xfs_bmbt_disk_get_startoff(&r2->bmbt); } #endif /* DEBUG */ #ifdef XFS_BTREE_TRACE ktrace_t *xfs_bmbt_trace_buf; STATIC void xfs_bmbt_trace_enter( struct xfs_btree_cur *cur, const char *func, char *s, int type, int line, __psunsigned_t a0, __psunsigned_t a1, __psunsigned_t a2, __psunsigned_t a3, __psunsigned_t a4, __psunsigned_t a5, __psunsigned_t a6, __psunsigned_t a7, __psunsigned_t a8, __psunsigned_t a9, __psunsigned_t a10) { struct xfs_inode *ip = cur->bc_private.b.ip; int whichfork = cur->bc_private.b.whichfork; ktrace_enter(xfs_bmbt_trace_buf, (void *)((__psint_t)type | (whichfork << 8) | (line << 16)), (void *)func, (void *)s, (void *)ip, (void *)cur, (void *)a0, (void *)a1, (void *)a2, (void *)a3, (void *)a4, (void *)a5, (void *)a6, (void *)a7, (void *)a8, (void *)a9, (void *)a10); } STATIC void xfs_bmbt_trace_cursor( struct xfs_btree_cur *cur, __uint32_t *s0, __uint64_t *l0, __uint64_t *l1) { struct xfs_bmbt_rec_host r; xfs_bmbt_set_all(&r, &cur->bc_rec.b); *s0 = (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) | cur->bc_private.b.allocated; *l0 = r.l0; *l1 = r.l1; } STATIC void xfs_bmbt_trace_key( struct xfs_btree_cur *cur, union xfs_btree_key *key, __uint64_t *l0, __uint64_t *l1) { *l0 = be64_to_cpu(key->bmbt.br_startoff); *l1 = 0; } STATIC void xfs_bmbt_trace_record( struct xfs_btree_cur *cur, union xfs_btree_rec *rec, __uint64_t *l0, __uint64_t *l1, __uint64_t *l2) { struct xfs_bmbt_irec irec; xfs_bmbt_disk_get_all(&rec->bmbt, &irec); *l0 = irec.br_startoff; *l1 = irec.br_startblock; *l2 = irec.br_blockcount; } #endif /* XFS_BTREE_TRACE */ /* Endian flipping versions of the bmbt extraction functions */ void xfs_bmbt_disk_get_all( xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s) { __xfs_bmbt_get_all(get_unaligned_be64(&r->l0), get_unaligned_be64(&r->l1), s); } static const struct xfs_btree_ops xfs_bmbt_ops = { .rec_len = sizeof(xfs_bmbt_rec_t), .key_len = sizeof(xfs_bmbt_key_t), .dup_cursor = xfs_bmbt_dup_cursor, .update_cursor = xfs_bmbt_update_cursor, .alloc_block = xfs_bmbt_alloc_block, .free_block = xfs_bmbt_free_block, .get_maxrecs = xfs_bmbt_get_maxrecs, .get_minrecs = xfs_bmbt_get_minrecs, .get_dmaxrecs = xfs_bmbt_get_dmaxrecs, .init_key_from_rec = xfs_bmbt_init_key_from_rec, .init_rec_from_key = xfs_bmbt_init_rec_from_key, .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, #ifdef DEBUG .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder, #endif #ifdef XFS_BTREE_TRACE .trace_enter = xfs_bmbt_trace_enter, .trace_cursor = xfs_bmbt_trace_cursor, .trace_key = xfs_bmbt_trace_key, .trace_record = xfs_bmbt_trace_record, #endif }; /* * Allocate a new bmap btree cursor. */ struct xfs_btree_cur * /* new bmap btree cursor */ xfs_bmbt_init_cursor( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* inode owning the btree */ int whichfork) /* data or attr fork */ { struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_btree_cur *cur; cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; cur->bc_btnum = XFS_BTNUM_BMAP; cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_ops = &xfs_bmbt_ops; cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); cur->bc_private.b.ip = ip; cur->bc_private.b.firstblock = NULLFSBLOCK; cur->bc_private.b.flist = NULL; cur->bc_private.b.allocated = 0; cur->bc_private.b.flags = 0; cur->bc_private.b.whichfork = whichfork; return cur; } /* * Calculate number of records in a bmap btree block. */ int xfs_bmbt_maxrecs( struct xfs_mount *mp, int blocklen, int leaf) { blocklen -= XFS_BMBT_BLOCK_LEN(mp); if (leaf) return blocklen / sizeof(xfs_bmbt_rec_t); return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)); } /* * Calculate number of records in a bmap btree inode root. */ int xfs_bmdr_maxrecs( struct xfs_mount *mp, int blocklen, int leaf) { blocklen -= sizeof(xfs_bmdr_block_t); if (leaf) return blocklen / sizeof(xfs_bmdr_rec_t); return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t)); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc.c0000664000000000000000000020622711650373061015234 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) #define XFSA_FIXUP_BNO_OK 1 #define XFSA_FIXUP_CNT_OK 2 /* * Prototypes for per-ag allocation routines */ STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); /* * Internal functions. */ /* * Lookup the record equal to [bno, len] in the btree given by cur. */ STATIC int /* error */ xfs_alloc_lookup_eq( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ xfs_extlen_t len, /* length of extent */ int *stat) /* success/failure */ { cur->bc_rec.a.ar_startblock = bno; cur->bc_rec.a.ar_blockcount = len; return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); } /* * Lookup the first record greater than or equal to [bno, len] * in the btree given by cur. */ STATIC int /* error */ xfs_alloc_lookup_ge( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ xfs_extlen_t len, /* length of extent */ int *stat) /* success/failure */ { cur->bc_rec.a.ar_startblock = bno; cur->bc_rec.a.ar_blockcount = len; return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); } /* * Lookup the first record less than or equal to [bno, len] * in the btree given by cur. */ STATIC int /* error */ xfs_alloc_lookup_le( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ xfs_extlen_t len, /* length of extent */ int *stat) /* success/failure */ { cur->bc_rec.a.ar_startblock = bno; cur->bc_rec.a.ar_blockcount = len; return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); } /* * Update the record referred to by cur to the value given * by [bno, len]. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int /* error */ xfs_alloc_update( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* starting block of extent */ xfs_extlen_t len) /* length of extent */ { union xfs_btree_rec rec; rec.alloc.ar_startblock = cpu_to_be32(bno); rec.alloc.ar_blockcount = cpu_to_be32(len); return xfs_btree_update(cur, &rec); } /* * Get the data from the pointed-to record. */ STATIC int /* error */ xfs_alloc_get_rec( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t *bno, /* output: starting block of extent */ xfs_extlen_t *len, /* output: length of extent */ int *stat) /* output: success/failure */ { union xfs_btree_rec *rec; int error; error = xfs_btree_get_rec(cur, &rec, stat); if (!error && *stat == 1) { *bno = be32_to_cpu(rec->alloc.ar_startblock); *len = be32_to_cpu(rec->alloc.ar_blockcount); } return error; } /* * Compute aligned version of the found extent. * Takes alignment and min length into account. */ STATIC void xfs_alloc_compute_aligned( xfs_agblock_t foundbno, /* starting block in found extent */ xfs_extlen_t foundlen, /* length in found extent */ xfs_extlen_t alignment, /* alignment for allocation */ xfs_extlen_t minlen, /* minimum length for allocation */ xfs_agblock_t *resbno, /* result block number */ xfs_extlen_t *reslen) /* result length */ { xfs_agblock_t bno; xfs_extlen_t diff; xfs_extlen_t len; if (alignment > 1 && foundlen >= minlen) { bno = roundup(foundbno, alignment); diff = bno - foundbno; len = diff >= foundlen ? 0 : foundlen - diff; } else { bno = foundbno; len = foundlen; } *resbno = bno; *reslen = len; } /* * Compute best start block and diff for "near" allocations. * freelen >= wantlen already checked by caller. */ STATIC xfs_extlen_t /* difference value (absolute) */ xfs_alloc_compute_diff( xfs_agblock_t wantbno, /* target starting block */ xfs_extlen_t wantlen, /* target length */ xfs_extlen_t alignment, /* target alignment */ xfs_agblock_t freebno, /* freespace's starting block */ xfs_extlen_t freelen, /* freespace's length */ xfs_agblock_t *newbnop) /* result: best start block from free */ { xfs_agblock_t freeend; /* end of freespace extent */ xfs_agblock_t newbno1; /* return block number */ xfs_agblock_t newbno2; /* other new block number */ xfs_extlen_t newlen1=0; /* length with newbno1 */ xfs_extlen_t newlen2=0; /* length with newbno2 */ xfs_agblock_t wantend; /* end of target extent */ ASSERT(freelen >= wantlen); freeend = freebno + freelen; wantend = wantbno + wantlen; if (freebno >= wantbno) { if ((newbno1 = roundup(freebno, alignment)) >= freeend) newbno1 = NULLAGBLOCK; } else if (freeend >= wantend && alignment > 1) { newbno1 = roundup(wantbno, alignment); newbno2 = newbno1 - alignment; if (newbno1 >= freeend) newbno1 = NULLAGBLOCK; else newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1); if (newbno2 < freebno) newbno2 = NULLAGBLOCK; else newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2); if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) { if (newlen1 < newlen2 || (newlen1 == newlen2 && XFS_ABSDIFF(newbno1, wantbno) > XFS_ABSDIFF(newbno2, wantbno))) newbno1 = newbno2; } else if (newbno2 != NULLAGBLOCK) newbno1 = newbno2; } else if (freeend >= wantend) { newbno1 = wantbno; } else if (alignment > 1) { newbno1 = roundup(freeend - wantlen, alignment); if (newbno1 > freeend - wantlen && newbno1 - alignment >= freebno) newbno1 -= alignment; else if (newbno1 >= freeend) newbno1 = NULLAGBLOCK; } else newbno1 = freeend - wantlen; *newbnop = newbno1; return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno); } /* * Fix up the length, based on mod and prod. * len should be k * prod + mod for some k. * If len is too small it is returned unchanged. * If len hits maxlen it is left alone. */ STATIC void xfs_alloc_fix_len( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_extlen_t k; xfs_extlen_t rlen; ASSERT(args->mod < args->prod); rlen = args->len; ASSERT(rlen >= args->minlen); ASSERT(rlen <= args->maxlen); if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen || (args->mod == 0 && rlen < args->prod)) return; k = rlen % args->prod; if (k == args->mod) return; if (k > args->mod) { if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen) return; } else { if ((int)(rlen = rlen - args->prod - (args->mod - k)) < (int)args->minlen) return; } ASSERT(rlen >= args->minlen); ASSERT(rlen <= args->maxlen); args->len = rlen; } /* * Fix up length if there is too little space left in the a.g. * Return 1 if ok, 0 if too little, should give up. */ STATIC int xfs_alloc_fix_minleft( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_agf_t *agf; /* a.g. freelist header */ int diff; /* free space difference */ if (args->minleft == 0) return 1; agf = XFS_BUF_TO_AGF(args->agbp); diff = be32_to_cpu(agf->agf_freeblks) + be32_to_cpu(agf->agf_flcount) - args->len - args->minleft; if (diff >= 0) return 1; args->len += diff; /* shrink the allocated space */ if (args->len >= args->minlen) return 1; args->agbno = NULLAGBLOCK; return 0; } /* * Update the two btrees, logically removing from freespace the extent * starting at rbno, rlen blocks. The extent is contained within the * actual (current) free extent fbno for flen blocks. * Flags are passed in indicating whether the cursors are set to the * relevant records. */ STATIC int /* error code */ xfs_alloc_fixup_trees( xfs_btree_cur_t *cnt_cur, /* cursor for by-size btree */ xfs_btree_cur_t *bno_cur, /* cursor for by-block btree */ xfs_agblock_t fbno, /* starting block of free extent */ xfs_extlen_t flen, /* length of free extent */ xfs_agblock_t rbno, /* starting block of returned extent */ xfs_extlen_t rlen, /* length of returned extent */ int flags) /* flags, XFSA_FIXUP_... */ { int error; /* error code */ int i; /* operation results */ xfs_agblock_t nfbno1; /* first new free startblock */ xfs_agblock_t nfbno2; /* second new free startblock */ xfs_extlen_t nflen1=0; /* first new free length */ xfs_extlen_t nflen2=0; /* second new free length */ /* * Look up the record in the by-size tree if necessary. */ if (flags & XFSA_FIXUP_CNT_OK) { #ifdef DEBUG if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) return error; XFS_WANT_CORRUPTED_RETURN( i == 1 && nfbno1 == fbno && nflen1 == flen); #endif } else { if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } /* * Look up the record in the by-block tree if necessary. */ if (flags & XFSA_FIXUP_BNO_OK) { #ifdef DEBUG if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) return error; XFS_WANT_CORRUPTED_RETURN( i == 1 && nfbno1 == fbno && nflen1 == flen); #endif } else { if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } #ifdef DEBUG if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) { struct xfs_btree_block *bnoblock; struct xfs_btree_block *cntblock; bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); XFS_WANT_CORRUPTED_RETURN( bnoblock->bb_numrecs == cntblock->bb_numrecs); } #endif /* * Deal with all four cases: the allocated record is contained * within the freespace record, so we can have new freespace * at either (or both) end, or no freespace remaining. */ if (rbno == fbno && rlen == flen) nfbno1 = nfbno2 = NULLAGBLOCK; else if (rbno == fbno) { nfbno1 = rbno + rlen; nflen1 = flen - rlen; nfbno2 = NULLAGBLOCK; } else if (rbno + rlen == fbno + flen) { nfbno1 = fbno; nflen1 = flen - rlen; nfbno2 = NULLAGBLOCK; } else { nfbno1 = fbno; nflen1 = rbno - fbno; nfbno2 = rbno + rlen; nflen2 = (fbno + flen) - nfbno2; } /* * Delete the entry from the by-size btree. */ if ((error = xfs_btree_delete(cnt_cur, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); /* * Add new by-size btree entry(s). */ if (nfbno1 != NULLAGBLOCK) { if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 0); if ((error = xfs_btree_insert(cnt_cur, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } if (nfbno2 != NULLAGBLOCK) { if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 0); if ((error = xfs_btree_insert(cnt_cur, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } /* * Fix up the by-block btree entry(s). */ if (nfbno1 == NULLAGBLOCK) { /* * No remaining freespace, just delete the by-block tree entry. */ if ((error = xfs_btree_delete(bno_cur, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } else { /* * Update the by-block entry to start later|be shorter. */ if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1))) return error; } if (nfbno2 != NULLAGBLOCK) { /* * 2 resulting free entries, need to add one. */ if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 0); if ((error = xfs_btree_insert(bno_cur, &i))) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); } return 0; } /* * Read in the allocation group free block array. */ STATIC int /* error */ xfs_alloc_read_agfl( xfs_mount_t *mp, /* mount point structure */ xfs_trans_t *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ xfs_buf_t **bpp) /* buffer for the ag free block array */ { xfs_buf_t *bp; /* return value */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp); if (error) return error; ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF); *bpp = bp; return 0; } /* * Allocation group level functions. */ /* * Allocate a variable extent in the allocation group agno. * Type and bno are used to determine where in the allocation group the * extent will start. * Extent's length (returned in *len) will be between minlen and maxlen, * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. */ STATIC int /* error */ xfs_alloc_ag_vextent( xfs_alloc_arg_t *args) /* argument structure for allocation */ { int error=0; ASSERT(args->minlen > 0); ASSERT(args->maxlen > 0); ASSERT(args->minlen <= args->maxlen); ASSERT(args->mod < args->prod); ASSERT(args->alignment > 0); /* * Branch to correct routine based on the type. */ args->wasfromfl = 0; switch (args->type) { case XFS_ALLOCTYPE_THIS_AG: error = xfs_alloc_ag_vextent_size(args); break; case XFS_ALLOCTYPE_NEAR_BNO: error = xfs_alloc_ag_vextent_near(args); break; case XFS_ALLOCTYPE_THIS_BNO: error = xfs_alloc_ag_vextent_exact(args); break; default: ASSERT(0); /* NOTREACHED */ } if (error) return error; /* * If the allocation worked, need to change the agf structure * (and log it), and the superblock. */ if (args->agbno != NULLAGBLOCK) { xfs_agf_t *agf; /* allocation group freelist header */ long slen = (long)args->len; ASSERT(args->len >= args->minlen && args->len <= args->maxlen); ASSERT(!(args->wasfromfl) || !args->isfl); ASSERT(args->agbno % args->alignment == 0); if (!(args->wasfromfl)) { agf = XFS_BUF_TO_AGF(args->agbp); be32_add_cpu(&agf->agf_freeblks, -(args->len)); xfs_trans_agblocks_delta(args->tp, -((long)(args->len))); args->pag->pagf_freeblks -= args->len; ASSERT(be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length)); xfs_alloc_log_agf(args->tp, args->agbp, XFS_AGF_FREEBLKS); /* * Search the busylist for these blocks and mark the * transaction as synchronous if blocks are found. This * avoids the need to block due to a synchronous log * force to ensure correct ordering as the synchronous * transaction will guarantee that for us. */ if (xfs_alloc_busy_search(args->mp, args->agno, args->agbno, args->len)) xfs_trans_set_sync(args->tp); } if (!args->isfl) xfs_trans_mod_sb(args->tp, args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS : XFS_TRANS_SB_FDBLOCKS, -slen); XFS_STATS_INC(xs_allocx); XFS_STATS_ADD(xs_allocb, args->len); } return 0; } /* * Allocate a variable extent at exactly agno/bno. * Extent's length (returned in *len) will be between minlen and maxlen, * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it. */ STATIC int /* error */ xfs_alloc_ag_vextent_exact( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */ xfs_btree_cur_t *cnt_cur;/* by count btree cursor */ xfs_agblock_t end; /* end of allocated extent */ int error; xfs_agblock_t fbno; /* start block of found extent */ xfs_agblock_t fend; /* end block of found extent */ xfs_extlen_t flen; /* length of found extent */ int i; /* success/failure of operation */ xfs_agblock_t maxend; /* end of maximal extent */ xfs_agblock_t minend; /* end of minimal extent */ xfs_extlen_t rlen; /* length of returned extent */ ASSERT(args->alignment == 1); /* * Allocate/initialize a cursor for the by-number freespace btree. */ bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_BNO); /* * Lookup bno and minlen in the btree (minlen is irrelevant, really). * Look for the closest free block <= bno, it must contain bno * if any free block does. */ error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i); if (error) goto error0; if (!i) goto not_found; /* * Grab the freespace record. */ error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); ASSERT(fbno <= args->agbno); minend = args->agbno + args->minlen; maxend = args->agbno + args->maxlen; fend = fbno + flen; /* * Give up if the freespace isn't long enough for the minimum request. */ if (fend < minend) goto not_found; /* * End of extent will be smaller of the freespace end and the * maximal requested end. * * Fix the length according to mod and prod if given. */ end = XFS_AGBLOCK_MIN(fend, maxend); args->len = end - args->agbno; xfs_alloc_fix_len(args); if (!xfs_alloc_fix_minleft(args)) goto not_found; rlen = args->len; ASSERT(args->agbno + rlen <= fend); end = args->agbno + rlen; /* * We are allocating agbno for rlen [agbno .. end] * Allocate/initialize a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_CNT); ASSERT(args->agbno + args->len <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno, args->len, XFSA_FIXUP_BNO_OK); if (error) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); goto error0; } xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); args->wasfromfl = 0; trace_xfs_alloc_exact_done(args); return 0; not_found: /* Didn't find it, return null. */ xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); args->agbno = NULLAGBLOCK; trace_xfs_alloc_exact_notfound(args); return 0; error0: xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); trace_xfs_alloc_exact_error(args); return error; } /* * Search the btree in a given direction via the search cursor and compare * the records found against the good extent we've already found. */ STATIC int xfs_alloc_find_best_extent( struct xfs_alloc_arg *args, /* allocation argument structure */ struct xfs_btree_cur **gcur, /* good cursor */ struct xfs_btree_cur **scur, /* searching cursor */ xfs_agblock_t gdiff, /* difference for search comparison */ xfs_agblock_t *sbno, /* extent found by search */ xfs_extlen_t *slen, xfs_extlen_t *slena, /* aligned length */ int dir) /* 0 = search right, 1 = search left */ { xfs_agblock_t bno; xfs_agblock_t new; xfs_agblock_t sdiff; int error; int i; /* The good extent is perfect, no need to search. */ if (!gdiff) goto out_use_good; /* * Look until we find a better one, run out of space or run off the end. */ do { error = xfs_alloc_get_rec(*scur, sbno, slen, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_alloc_compute_aligned(*sbno, *slen, args->alignment, args->minlen, &bno, slena); /* * The good extent is closer than this one. */ if (!dir) { if (bno >= args->agbno + gdiff) goto out_use_good; } else { if (bno <= args->agbno - gdiff) goto out_use_good; } /* * Same distance, compare length and pick the best. */ if (*slena >= args->minlen) { args->len = XFS_EXTLEN_MIN(*slena, args->maxlen); xfs_alloc_fix_len(args); sdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, *sbno, *slen, &new); /* * Choose closer size and invalidate other cursor. */ if (sdiff < gdiff) goto out_use_search; goto out_use_good; } if (!dir) error = xfs_btree_increment(*scur, 0, &i); else error = xfs_btree_decrement(*scur, 0, &i); if (error) goto error0; } while (i); out_use_good: xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR); *scur = NULL; return 0; out_use_search: xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR); *gcur = NULL; return 0; error0: /* caller invalidates cursors */ return error; } /* * Allocate a variable extent near bno in the allocation group agno. * Extent's length (returned in len) will be between minlen and maxlen, * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. */ STATIC int /* error */ xfs_alloc_ag_vextent_near( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ xfs_agblock_t gtbno; /* start bno of right side entry */ xfs_agblock_t gtbnoa; /* aligned ... */ xfs_extlen_t gtdiff; /* difference to right side entry */ xfs_extlen_t gtlen; /* length of right side entry */ xfs_extlen_t gtlena = 0; /* aligned ... */ xfs_agblock_t gtnew; /* useful start bno of right side */ int error; /* error code */ int i; /* result code, temporary */ int j; /* result code, temporary */ xfs_agblock_t ltbno; /* start bno of left side entry */ xfs_agblock_t ltbnoa; /* aligned ... */ xfs_extlen_t ltdiff; /* difference to left side entry */ xfs_extlen_t ltlen; /* length of left side entry */ xfs_extlen_t ltlena = 0; /* aligned ... */ xfs_agblock_t ltnew; /* useful start bno of left side */ xfs_extlen_t rlen; /* length of returned extent */ #if defined(DEBUG) && defined(__KERNEL__) /* * Randomly don't execute the first algorithm. */ int dofirst; /* set to do first algorithm */ dofirst = random32() & 1; #endif /* * Get a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_CNT); ltlen = 0; bno_cur_lt = bno_cur_gt = NULL; /* * See if there are any free extents as big as maxlen. */ if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i))) goto error0; /* * If none, then pick up the last entry in the tree unless the * tree is empty. */ if (!i) { if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, <bno, <len, &i))) goto error0; if (i == 0 || ltlen == 0) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); return 0; } ASSERT(i == 1); } args->wasfromfl = 0; /* * First algorithm. * If the requested extent is large wrt the freespaces available * in this a.g., then the cursor will be pointing to a btree entry * near the right edge of the tree. If it's in the last btree leaf * block, then we just examine all the entries in that block * that are big enough, and pick the best one. * This is written as a while loop so we can break out of it, * but we never loop back to the top. */ while (xfs_btree_islastblock(cnt_cur, 0)) { xfs_extlen_t bdiff; int besti=0; xfs_extlen_t blen=0; xfs_agblock_t bnew=0; #if defined(DEBUG) && defined(__KERNEL__) if (!dofirst) break; #endif /* * Start from the entry that lookup found, sequence through * all larger free blocks. If we're actually pointing at a * record smaller than maxlen, go to the start of this block, * and skip all those smaller than minlen. */ if (ltlen || args->alignment > 1) { cnt_cur->bc_ptrs[0] = 1; do { if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if (ltlen >= args->minlen) break; if ((error = xfs_btree_increment(cnt_cur, 0, &i))) goto error0; } while (i); ASSERT(ltlen >= args->minlen); if (!i) break; } i = cnt_cur->bc_ptrs[0]; for (j = 1, blen = 0, bdiff = 0; !error && j && (blen < args->maxlen || bdiff > 0); error = xfs_btree_increment(cnt_cur, 0, &j)) { /* * For each entry, decide if it's better than * the previous best entry. */ if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, args->minlen, <bnoa, <lena); if (ltlena < args->minlen) continue; args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); ASSERT(args->len >= args->minlen); if (args->len < blen) continue; ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, ltbno, ltlen, <new); if (ltnew != NULLAGBLOCK && (args->len > blen || ltdiff < bdiff)) { bdiff = ltdiff; bnew = ltnew; blen = args->len; besti = cnt_cur->bc_ptrs[0]; } } /* * It didn't work. We COULD be in a case where * there's a good record somewhere, so try again. */ if (blen == 0) break; /* * Point at the best entry, and retrieve it again. */ cnt_cur->bc_ptrs[0] = besti; if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); args->len = blen; if (!xfs_alloc_fix_minleft(args)) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_near_nominleft(args); return 0; } blen = args->len; /* * We are allocating starting at bnew for blen blocks. */ args->agbno = bnew; ASSERT(bnew >= ltbno); ASSERT(bnew + blen <= ltbno + ltlen); /* * Set up a cursor for the by-bno tree. */ bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_BNO); /* * Fix up the btree entries. */ if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, bnew, blen, XFSA_FIXUP_CNT_OK))) goto error0; xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); trace_xfs_alloc_near_first(args); return 0; } /* * Second algorithm. * Search in the by-bno tree to the left and to the right * simultaneously, until in each case we find a space big enough, * or run into the edge of the tree. When we run into the edge, * we deallocate that cursor. * If both searches succeed, we compare the two spaces and pick * the better one. * With alignment, it's possible for both to fail; the upper * level algorithm that picks allocation groups for allocations * is not supposed to do this. */ /* * Allocate and initialize the cursor for the leftward search. */ bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_BNO); /* * Lookup <= bno to find the leftward search's starting point. */ if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i))) goto error0; if (!i) { /* * Didn't find anything; use this cursor for the rightward * search. */ bno_cur_gt = bno_cur_lt; bno_cur_lt = NULL; } /* * Found something. Duplicate the cursor for the rightward search. */ else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt))) goto error0; /* * Increment the cursor, so we will point at the entry just right * of the leftward entry if any, or to the leftmost entry. */ if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) goto error0; if (!i) { /* * It failed, there are no rightward entries. */ xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR); bno_cur_gt = NULL; } /* * Loop going left with the leftward cursor, right with the * rightward cursor, until either both directions give up or * we find an entry at least as big as minlen. */ do { if (bno_cur_lt) { if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, args->minlen, <bnoa, <lena); if (ltlena >= args->minlen) break; if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i))) goto error0; if (!i) { xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); bno_cur_lt = NULL; } } if (bno_cur_gt) { if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_alloc_compute_aligned(gtbno, gtlen, args->alignment, args->minlen, >bnoa, >lena); if (gtlena >= args->minlen) break; if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) goto error0; if (!i) { xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR); bno_cur_gt = NULL; } } } while (bno_cur_lt || bno_cur_gt); /* * Got both cursors still active, need to find better entry. */ if (bno_cur_lt && bno_cur_gt) { if (ltlena >= args->minlen) { /* * Left side is good, look for a right side entry. */ args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); rlen = args->len; ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, ltbno, ltlen, <new); error = xfs_alloc_find_best_extent(args, &bno_cur_lt, &bno_cur_gt, ltdiff, >bno, >len, >lena, 0 /* search right */); } else { ASSERT(gtlena >= args->minlen); /* * Right side is good, look for a left side entry. */ args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); xfs_alloc_fix_len(args); gtdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, gtbno, gtlen, >new); error = xfs_alloc_find_best_extent(args, &bno_cur_gt, &bno_cur_lt, gtdiff, <bno, <len, <lena, 1 /* search left */); } if (error) goto error0; } /* * If we couldn't get anything, give up. */ if (bno_cur_lt == NULL && bno_cur_gt == NULL) { trace_xfs_alloc_size_neither(args); args->agbno = NULLAGBLOCK; return 0; } /* * At this point we have selected a freespace entry, either to the * left or to the right. If it's on the right, copy all the * useful variables to the "left" set so we only have one * copy of this code. */ if (bno_cur_gt) { bno_cur_lt = bno_cur_gt; bno_cur_gt = NULL; ltbno = gtbno; ltbnoa = gtbnoa; ltlen = gtlen; ltlena = gtlena; j = 1; } else j = 0; /* * Fix up the length and compute the useful address. */ args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); if (!xfs_alloc_fix_minleft(args)) { trace_xfs_alloc_near_nominleft(args); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); return 0; } rlen = args->len; (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, ltbno, ltlen, <new); ASSERT(ltnew >= ltbno); ASSERT(ltnew + rlen <= ltbno + ltlen); ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); args->agbno = ltnew; if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, ltnew, rlen, XFSA_FIXUP_BNO_OK))) goto error0; if (j) trace_xfs_alloc_near_greater(args); else trace_xfs_alloc_near_lesser(args); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); return 0; error0: trace_xfs_alloc_near_error(args); if (cnt_cur != NULL) xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); if (bno_cur_lt != NULL) xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR); if (bno_cur_gt != NULL) xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR); return error; } /* * Allocate a variable extent anywhere in the allocation group agno. * Extent's length (returned in len) will be between minlen and maxlen, * and of the form k * prod + mod unless there's nothing that large. * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. */ STATIC int /* error */ xfs_alloc_ag_vextent_size( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_btree_cur_t *bno_cur; /* cursor for bno btree */ xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */ int error; /* error result */ xfs_agblock_t fbno; /* start of found freespace */ xfs_extlen_t flen; /* length of found freespace */ int i; /* temp status variable */ xfs_agblock_t rbno; /* returned block number */ xfs_extlen_t rlen; /* length of returned extent */ /* * Allocate and initialize a cursor for the by-size btree. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_CNT); bno_cur = NULL; /* * Look for an entry >= maxlen+alignment-1 blocks. */ if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen + args->alignment - 1, &i))) goto error0; /* * If none, then pick up the last entry in the tree unless the * tree is empty. */ if (!i) { if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &fbno, &flen, &i))) goto error0; if (i == 0 || flen == 0) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_size_noentry(args); return 0; } ASSERT(i == 1); } /* * There's a freespace as big as maxlen+alignment-1, get it. */ else { if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); } /* * In the first case above, we got the last entry in the * by-size btree. Now we check to see if the space hits maxlen * once aligned; if not, we search left for something better. * This can't happen in the second case above. */ xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen, &rbno, &rlen); rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); XFS_WANT_CORRUPTED_GOTO(rlen == 0 || (rlen <= flen && rbno + rlen <= fbno + flen), error0); if (rlen < args->maxlen) { xfs_agblock_t bestfbno; xfs_extlen_t bestflen; xfs_agblock_t bestrbno; xfs_extlen_t bestrlen; bestrlen = rlen; bestrbno = rbno; bestflen = flen; bestfbno = fbno; for (;;) { if ((error = xfs_btree_decrement(cnt_cur, 0, &i))) goto error0; if (i == 0) break; if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if (flen < bestrlen) break; xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen, &rbno, &rlen); rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); XFS_WANT_CORRUPTED_GOTO(rlen == 0 || (rlen <= flen && rbno + rlen <= fbno + flen), error0); if (rlen > bestrlen) { bestrlen = rlen; bestrbno = rbno; bestflen = flen; bestfbno = fbno; if (rlen == args->maxlen) break; } } if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); rlen = bestrlen; rbno = bestrbno; flen = bestflen; fbno = bestfbno; } args->wasfromfl = 0; /* * Fix up the length. */ args->len = rlen; xfs_alloc_fix_len(args); if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_size_nominleft(args); args->agbno = NULLAGBLOCK; return 0; } rlen = args->len; XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0); /* * Allocate and initialize a cursor for the by-block tree. */ bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, args->agno, XFS_BTNUM_BNO); if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, rbno, rlen, XFSA_FIXUP_CNT_OK))) goto error0; xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); cnt_cur = bno_cur = NULL; args->len = rlen; args->agbno = rbno; XFS_WANT_CORRUPTED_GOTO( args->agbno + args->len <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), error0); trace_xfs_alloc_size_done(args); return 0; error0: trace_xfs_alloc_size_error(args); if (cnt_cur) xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); if (bno_cur) xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); return error; } /* * Deal with the case where only small freespaces remain. * Either return the contents of the last freespace record, * or allocate space from the freelist if there is nothing in the tree. */ STATIC int /* error */ xfs_alloc_ag_vextent_small( xfs_alloc_arg_t *args, /* allocation argument structure */ xfs_btree_cur_t *ccur, /* by-size cursor */ xfs_agblock_t *fbnop, /* result block number */ xfs_extlen_t *flenp, /* result length */ int *stat) /* status: 0-freelist, 1-normal/none */ { int error; xfs_agblock_t fbno; xfs_extlen_t flen; int i; if ((error = xfs_btree_decrement(ccur, 0, &i))) goto error0; if (i) { if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); } /* * Nothing in the btree, try the freelist. Make sure * to respect minleft even when pulling from the * freelist. */ else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) > args->minleft)) { error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); if (error) goto error0; if (fbno != NULLAGBLOCK) { if (args->userdata) { xfs_buf_t *bp; bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno, 0); xfs_trans_binval(args->tp, bp); } args->len = 1; args->agbno = fbno; XFS_WANT_CORRUPTED_GOTO( args->agbno + args->len <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), error0); args->wasfromfl = 1; trace_xfs_alloc_small_freelist(args); *stat = 0; return 0; } /* * Nothing in the freelist. */ else flen = 0; } /* * Can't allocate from the freelist for some reason. */ else { fbno = NULLAGBLOCK; flen = 0; } /* * Can't do the allocation, give up. */ if (flen < args->minlen) { args->agbno = NULLAGBLOCK; trace_xfs_alloc_small_notenough(args); flen = 0; } *fbnop = fbno; *flenp = flen; *stat = 1; trace_xfs_alloc_small_done(args); return 0; error0: trace_xfs_alloc_small_error(args); return error; } /* * Free the extent starting at agno/bno for length. */ STATIC int /* error */ xfs_free_ag_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *agbp, /* buffer for a.g. freelist header */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t bno, /* starting block number */ xfs_extlen_t len, /* length of extent */ int isfl) /* set if is freelist blocks - no sb acctg */ { xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ int error; /* error return value */ xfs_agblock_t gtbno; /* start of right neighbor block */ xfs_extlen_t gtlen; /* length of right neighbor block */ int haveleft; /* have a left neighbor block */ int haveright; /* have a right neighbor block */ int i; /* temp, result code */ xfs_agblock_t ltbno; /* start of left neighbor block */ xfs_extlen_t ltlen; /* length of left neighbor block */ xfs_mount_t *mp; /* mount point struct for filesystem */ xfs_agblock_t nbno; /* new starting block of freespace */ xfs_extlen_t nlen; /* new length of freespace */ mp = tp->t_mountp; /* * Allocate and initialize a cursor for the by-block btree. */ bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); cnt_cur = NULL; /* * Look for a neighboring block on the left (lower block numbers) * that is contiguous with this space. */ if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft))) goto error0; if (haveleft) { /* * There is a block to our left. */ if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * It's not contiguous, though. */ if (ltbno + ltlen < bno) haveleft = 0; else { /* * If this failure happens the request to free this * space was invalid, it's (partly) already free. * Very bad. */ XFS_WANT_CORRUPTED_GOTO(ltbno + ltlen <= bno, error0); } } /* * Look for a neighboring block on the right (higher block numbers) * that is contiguous with this space. */ if ((error = xfs_btree_increment(bno_cur, 0, &haveright))) goto error0; if (haveright) { /* * There is a block to our right. */ if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * It's not contiguous, though. */ if (bno + len < gtbno) haveright = 0; else { /* * If this failure happens the request to free this * space was invalid, it's (partly) already free. * Very bad. */ XFS_WANT_CORRUPTED_GOTO(gtbno >= bno + len, error0); } } /* * Now allocate and initialize a cursor for the by-size tree. */ cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT); /* * Have both left and right contiguous neighbors. * Merge all three into a single free block. */ if (haveleft && haveright) { /* * Delete the old by-size entry on the left. */ if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * Delete the old by-size entry on the right. */ if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * Delete the old by-block entry for the right block. */ if ((error = xfs_btree_delete(bno_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * Move the by-block cursor back to the left neighbor. */ if ((error = xfs_btree_decrement(bno_cur, 0, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); #ifdef DEBUG /* * Check that this is the right record: delete didn't * mangle the cursor. */ { xfs_agblock_t xxbno; xfs_extlen_t xxlen; if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO( i == 1 && xxbno == ltbno && xxlen == ltlen, error0); } #endif /* * Update remaining by-block entry to the new, joined block. */ nbno = ltbno; nlen = len + ltlen + gtlen; if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) goto error0; } /* * Have only a left contiguous neighbor. * Merge it together with the new freespace. */ else if (haveleft) { /* * Delete the old by-size entry on the left. */ if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * Back up the by-block cursor to the left neighbor, and * update its length. */ if ((error = xfs_btree_decrement(bno_cur, 0, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); nbno = ltbno; nlen = len + ltlen; if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) goto error0; } /* * Have only a right contiguous neighbor. * Merge it together with the new freespace. */ else if (haveright) { /* * Delete the old by-size entry on the right. */ if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* * Update the starting block and length of the right * neighbor in the by-block tree. */ nbno = bno; nlen = len + gtlen; if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) goto error0; } /* * No contiguous neighbors. * Insert the new freespace into the by-block tree. */ else { nbno = bno; nlen = len; if ((error = xfs_btree_insert(bno_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); } xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); bno_cur = NULL; /* * In all cases we need to insert the new freespace in the by-size tree. */ if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 0, error0); if ((error = xfs_btree_insert(cnt_cur, &i))) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); cnt_cur = NULL; /* * Update the freespace totals in the ag and superblock. */ { xfs_agf_t *agf; xfs_perag_t *pag; /* per allocation group data */ pag = xfs_perag_get(mp, agno); pag->pagf_freeblks += len; xfs_perag_put(pag); agf = XFS_BUF_TO_AGF(agbp); be32_add_cpu(&agf->agf_freeblks, len); xfs_trans_agblocks_delta(tp, len); XFS_WANT_CORRUPTED_GOTO( be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length), error0); xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); if (!isfl) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); XFS_STATS_INC(xs_freex); XFS_STATS_ADD(xs_freeb, len); } trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); /* * Since blocks move to the free list without the coordination * used in xfs_bmap_finish, we can't allow block to be available * for reallocation and non-transaction writing (user data) * until we know that the transaction that moved it to the free * list is permanently on disk. We track the blocks by declaring * these blocks as "busy"; the busy list is maintained on a per-ag * basis and each transaction records which entries should be removed * when the iclog commits to disk. If a busy block is allocated, * the iclog is pushed up to the LSN that freed the block. */ xfs_alloc_busy_insert(tp, agno, bno, len); return 0; error0: trace_xfs_free_extent(mp, agno, bno, len, isfl, -1, -1); if (bno_cur) xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); if (cnt_cur) xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); return error; } /* * Visible (exported) allocation/free functions. * Some of these are used just by xfs_alloc_btree.c and this file. */ /* * Compute and fill in value of m_ag_maxlevels. */ void xfs_alloc_compute_maxlevels( xfs_mount_t *mp) /* file system mount structure */ { int level; uint maxblocks; uint maxleafents; int minleafrecs; int minnoderecs; maxleafents = (mp->m_sb.sb_agblocks + 1) / 2; minleafrecs = mp->m_alloc_mnr[0]; minnoderecs = mp->m_alloc_mnr[1]; maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; for (level = 1; maxblocks > 1; level++) maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; mp->m_ag_maxlevels = level; } /* * Find the length of the longest extent in an AG. */ xfs_extlen_t xfs_alloc_longest_free_extent( struct xfs_mount *mp, struct xfs_perag *pag) { xfs_extlen_t need, delta = 0; need = XFS_MIN_FREELIST_PAG(pag, mp); if (need > pag->pagf_flcount) delta = need - pag->pagf_flcount; if (pag->pagf_longest > delta) return pag->pagf_longest - delta; return pag->pagf_flcount > 0 || pag->pagf_longest > 0; } /* * Decide whether to use this allocation group for this allocation. * If so, fix up the btree freelist's size. * * Note: This is public so mkfs can call it */ int /* error */ xfs_alloc_fix_freelist( xfs_alloc_arg_t *args, /* allocation argument structure */ int flags) /* XFS_ALLOC_FLAG_... */ { xfs_buf_t *agbp; /* agf buffer pointer */ xfs_agf_t *agf; /* a.g. freespace structure pointer */ xfs_buf_t *agflbp;/* agfl buffer pointer */ xfs_agblock_t bno; /* freelist block */ xfs_extlen_t delta; /* new blocks needed in freelist */ int error; /* error result code */ xfs_extlen_t longest;/* longest extent in allocation group */ xfs_mount_t *mp; /* file system mount point structure */ xfs_extlen_t need; /* total blocks needed in freelist */ xfs_perag_t *pag; /* per-ag information structure */ xfs_alloc_arg_t targs; /* local allocation arguments */ xfs_trans_t *tp; /* transaction pointer */ mp = args->mp; pag = args->pag; tp = args->tp; if (!pag->pagf_init) { if ((error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp))) return error; if (!pag->pagf_init) { ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } } else agbp = NULL; /* * If this is a metadata preferred pag and we are user data * then try somewhere else if we are not being asked to * try harder at this point */ if (pag->pagf_metadata && args->userdata && (flags & XFS_ALLOC_FLAG_TRYLOCK)) { ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } if (!(flags & XFS_ALLOC_FLAG_FREEING)) { /* * If it looks like there isn't a long enough extent, or enough * total blocks, reject it. */ need = XFS_MIN_FREELIST_PAG(pag, mp); longest = xfs_alloc_longest_free_extent(mp, pag); if ((args->minlen + args->alignment + args->minalignslop - 1) > longest || ((int)(pag->pagf_freeblks + pag->pagf_flcount - need - args->total) < (int)args->minleft)) { if (agbp) xfs_trans_brelse(tp, agbp); args->agbp = NULL; return 0; } } /* * Get the a.g. freespace buffer. * Can fail if we're not blocking on locks, and it's held. */ if (agbp == NULL) { if ((error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp))) return error; if (agbp == NULL) { ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } } /* * Figure out how many blocks we should have in the freelist. */ agf = XFS_BUF_TO_AGF(agbp); need = XFS_MIN_FREELIST(agf, mp); /* * If there isn't enough total or single-extent, reject it. */ if (!(flags & XFS_ALLOC_FLAG_FREEING)) { delta = need > be32_to_cpu(agf->agf_flcount) ? (need - be32_to_cpu(agf->agf_flcount)) : 0; longest = be32_to_cpu(agf->agf_longest); longest = (longest > delta) ? (longest - delta) : (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); if ((args->minlen + args->alignment + args->minalignslop - 1) > longest || ((int)(be32_to_cpu(agf->agf_freeblks) + be32_to_cpu(agf->agf_flcount) - need - args->total) < (int)args->minleft)) { xfs_trans_brelse(tp, agbp); args->agbp = NULL; return 0; } } /* * Make the freelist shorter if it's too long. */ while (be32_to_cpu(agf->agf_flcount) > need) { xfs_buf_t *bp; error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); if (error) return error; if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) return error; bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); xfs_trans_binval(tp, bp); } /* * Initialize the args structure. */ targs.tp = tp; targs.mp = mp; targs.agbp = agbp; targs.agno = args->agno; targs.mod = targs.minleft = targs.wasdel = targs.userdata = targs.minalignslop = 0; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; targs.type = XFS_ALLOCTYPE_THIS_AG; targs.pag = pag; if ((error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp))) return error; /* * Make the freelist longer if it's too short. */ while (be32_to_cpu(agf->agf_flcount) < need) { targs.agbno = 0; targs.maxlen = need - be32_to_cpu(agf->agf_flcount); /* * Allocate as many blocks as possible at once. */ if ((error = xfs_alloc_ag_vextent(&targs))) { xfs_trans_brelse(tp, agflbp); return error; } /* * Stop if we run out. Won't happen if callers are obeying * the restrictions correctly. Can happen for free calls * on a completely full ag. */ if (targs.agbno == NULLAGBLOCK) { if (flags & XFS_ALLOC_FLAG_FREEING) break; xfs_trans_brelse(tp, agflbp); args->agbp = NULL; return 0; } /* * Put each allocated block on the list. */ for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { error = xfs_alloc_put_freelist(tp, agbp, agflbp, bno, 0); if (error) return error; } } xfs_trans_brelse(tp, agflbp); args->agbp = agbp; return 0; } /* * Get a block from the freelist. * Returns with the buffer for the block gotten. */ int /* error */ xfs_alloc_get_freelist( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *agbp, /* buffer containing the agf structure */ xfs_agblock_t *bnop, /* block address retrieved from freelist */ int btreeblk) /* destination is a AGF btree */ { xfs_agf_t *agf; /* a.g. freespace structure */ xfs_agfl_t *agfl; /* a.g. freelist structure */ xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ xfs_agblock_t bno; /* block number returned */ int error; int logflags; xfs_mount_t *mp; /* mount structure */ xfs_perag_t *pag; /* per allocation group data */ agf = XFS_BUF_TO_AGF(agbp); /* * Freelist is empty, give up. */ if (!agf->agf_flcount) { *bnop = NULLAGBLOCK; return 0; } /* * Read the array of free blocks. */ mp = tp->t_mountp; if ((error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno), &agflbp))) return error; agfl = XFS_BUF_TO_AGFL(agflbp); /* * Get the block number and update the data structures. */ bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); be32_add_cpu(&agf->agf_flfirst, 1); xfs_trans_brelse(tp, agflbp); if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) agf->agf_flfirst = 0; pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); be32_add_cpu(&agf->agf_flcount, -1); xfs_trans_agflist_delta(tp, -1); pag->pagf_flcount--; xfs_perag_put(pag); logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; if (btreeblk) { be32_add_cpu(&agf->agf_btreeblks, 1); pag->pagf_btreeblks++; logflags |= XFS_AGF_BTREEBLKS; } xfs_alloc_log_agf(tp, agbp, logflags); *bnop = bno; /* * As blocks are freed, they are added to the per-ag busy list and * remain there until the freeing transaction is committed to disk. * Now that we have allocated blocks, this list must be searched to see * if a block is being reused. If one is, then the freeing transaction * must be pushed to disk before this transaction. * * We do this by setting the current transaction to a sync transaction * which guarantees that the freeing transaction is on disk before this * transaction. This is done instead of a synchronous log force here so * that we don't sit and wait with the AGF locked in the transaction * during the log force. */ if (xfs_alloc_busy_search(mp, be32_to_cpu(agf->agf_seqno), bno, 1)) xfs_trans_set_sync(tp); return 0; } /* * Log the given fields from the agf structure. */ void xfs_alloc_log_agf( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *bp, /* buffer for a.g. freelist header */ int fields) /* mask of fields to be logged (XFS_AGF_...) */ { int first; /* first byte offset */ int last; /* last byte offset */ static const short offsets[] = { offsetof(xfs_agf_t, agf_magicnum), offsetof(xfs_agf_t, agf_versionnum), offsetof(xfs_agf_t, agf_seqno), offsetof(xfs_agf_t, agf_length), offsetof(xfs_agf_t, agf_roots[0]), offsetof(xfs_agf_t, agf_levels[0]), offsetof(xfs_agf_t, agf_flfirst), offsetof(xfs_agf_t, agf_fllast), offsetof(xfs_agf_t, agf_flcount), offsetof(xfs_agf_t, agf_freeblks), offsetof(xfs_agf_t, agf_longest), offsetof(xfs_agf_t, agf_btreeblks), sizeof(xfs_agf_t) }; trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_); xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last); xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); } /* * Interface for inode allocation to force the pag data to be initialized. */ int /* error */ xfs_alloc_pagf_init( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags) /* XFS_ALLOC_FLAGS_... */ { xfs_buf_t *bp; int error; if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp))) return error; if (bp) xfs_trans_brelse(tp, bp); return 0; } /* * Put the block on the freelist for the allocation group. */ int /* error */ xfs_alloc_put_freelist( xfs_trans_t *tp, /* transaction pointer */ xfs_buf_t *agbp, /* buffer for a.g. freelist header */ xfs_buf_t *agflbp,/* buffer for a.g. free block array */ xfs_agblock_t bno, /* block being freed */ int btreeblk) /* block came from a AGF btree */ { xfs_agf_t *agf; /* a.g. freespace structure */ xfs_agfl_t *agfl; /* a.g. free block array */ __be32 *blockp;/* pointer to array entry */ int error; int logflags; xfs_mount_t *mp; /* mount structure */ xfs_perag_t *pag; /* per allocation group data */ agf = XFS_BUF_TO_AGF(agbp); mp = tp->t_mountp; if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno), &agflbp))) return error; agfl = XFS_BUF_TO_AGFL(agflbp); be32_add_cpu(&agf->agf_fllast, 1); if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) agf->agf_fllast = 0; pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); be32_add_cpu(&agf->agf_flcount, 1); xfs_trans_agflist_delta(tp, 1); pag->pagf_flcount++; logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; if (btreeblk) { be32_add_cpu(&agf->agf_btreeblks, -1); pag->pagf_btreeblks--; logflags |= XFS_AGF_BTREEBLKS; } xfs_perag_put(pag); xfs_alloc_log_agf(tp, agbp, logflags); ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; *blockp = cpu_to_be32(bno); xfs_alloc_log_agf(tp, agbp, logflags); xfs_trans_log_buf(tp, agflbp, (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + sizeof(xfs_agblock_t) - 1)); return 0; } /* * Read in the allocation group header (free/alloc section). */ int /* error */ xfs_read_agf( struct xfs_mount *mp, /* mount point structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags, /* XFS_BUF_ */ struct xfs_buf **bpp) /* buffer for the ag freelist header */ { struct xfs_agf *agf; /* ag freelist header */ int agf_ok; /* set if agf is consistent */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_trans_read_buf( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), flags, bpp); if (error) return error; if (!*bpp) return 0; ASSERT(!XFS_BUF_GETERROR(*bpp)); agf = XFS_BUF_TO_AGF(*bpp); /* * Validate the magic number of the agf block. */ agf_ok = be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp) && be32_to_cpu(agf->agf_seqno) == agno; if (xfs_sb_version_haslazysbcount(&mp->m_sb)) agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <= be32_to_cpu(agf->agf_length); if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, XFS_RANDOM_ALLOC_READ_AGF))) { XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", XFS_ERRLEVEL_LOW, mp, agf); xfs_trans_brelse(tp, *bpp); return XFS_ERROR(EFSCORRUPTED); } XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); return 0; } /* * Read in the allocation group header (free/alloc section). */ int /* error */ xfs_alloc_read_agf( struct xfs_mount *mp, /* mount point structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags, /* XFS_ALLOC_FLAG_... */ struct xfs_buf **bpp) /* buffer for the ag freelist header */ { struct xfs_agf *agf; /* ag freelist header */ struct xfs_perag *pag; /* per allocation group data */ int error; ASSERT(agno != NULLAGNUMBER); error = xfs_read_agf(mp, tp, agno, (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, bpp); if (error) return error; if (!*bpp) return 0; ASSERT(!XFS_BUF_GETERROR(*bpp)); agf = XFS_BUF_TO_AGF(*bpp); pag = xfs_perag_get(mp, agno); if (!pag->pagf_init) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); pag->pagf_longest = be32_to_cpu(agf->agf_longest); pag->pagf_levels[XFS_BTNUM_BNOi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); pag->pagf_levels[XFS_BTNUM_CNTi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); spin_lock_init(&pag->pagb_lock); pag->pagb_count = 0; pag->pagf_init = 1; } #ifdef DEBUG else if (!XFS_FORCED_SHUTDOWN(mp)) { ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks)); ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks)); ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount)); ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest)); ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] == be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi])); ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] == be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); } #endif xfs_perag_put(pag); return 0; } /* * Allocate an extent (variable-size). * Depending on the allocation type, we either look in a single allocation * group or loop over the allocation groups to find the result. */ int /* error */ xfs_alloc_vextent( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_agblock_t agsize; /* allocation group size */ int error; int flags; /* XFS_ALLOC_FLAG_... locking flags */ xfs_extlen_t minleft;/* minimum left value, temp copy */ xfs_mount_t *mp; /* mount structure pointer */ xfs_agnumber_t sagno; /* starting allocation group number */ xfs_alloctype_t type; /* input allocation type */ int bump_rotor = 0; int no_min = 0; xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ mp = args->mp; type = args->otype = args->type; args->agbno = NULLAGBLOCK; /* * Just fix this up, for the case where the last a.g. is shorter * (or there's only one a.g.) and the caller couldn't easily figure * that out (xfs_bmap_alloc). */ agsize = mp->m_sb.sb_agblocks; if (args->maxlen > agsize) args->maxlen = agsize; if (args->alignment == 0) args->alignment = 1; ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount); ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize); ASSERT(args->minlen <= args->maxlen); ASSERT(args->minlen <= agsize); ASSERT(args->mod < args->prod); if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount || XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize || args->minlen > args->maxlen || args->minlen > agsize || args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; trace_xfs_alloc_vextent_badargs(args); return 0; } minleft = args->minleft; switch (type) { case XFS_ALLOCTYPE_THIS_AG: case XFS_ALLOCTYPE_NEAR_BNO: case XFS_ALLOCTYPE_THIS_BNO: /* * These three force us into a single a.g. */ args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->pag = xfs_perag_get(mp, args->agno); args->minleft = 0; error = xfs_alloc_fix_freelist(args, 0); args->minleft = minleft; if (error) { trace_xfs_alloc_vextent_nofix(args); goto error0; } if (!args->agbp) { trace_xfs_alloc_vextent_noagbp(args); break; } args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); if ((error = xfs_alloc_ag_vextent(args))) goto error0; break; case XFS_ALLOCTYPE_START_BNO: /* * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. */ if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount), 0); bump_rotor = 1; } args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_NEAR_BNO; /* FALLTHROUGH */ case XFS_ALLOCTYPE_ANY_AG: case XFS_ALLOCTYPE_START_AG: case XFS_ALLOCTYPE_FIRST_AG: /* * Rotate through the allocation groups looking for a winner. */ if (type == XFS_ALLOCTYPE_ANY_AG) { /* * Start with the last place we left off. */ args->agno = sagno = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount; args->type = XFS_ALLOCTYPE_THIS_AG; flags = XFS_ALLOC_FLAG_TRYLOCK; } else if (type == XFS_ALLOCTYPE_FIRST_AG) { /* * Start with allocation group given by bno. */ args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_THIS_AG; sagno = 0; flags = 0; } else { if (type == XFS_ALLOCTYPE_START_AG) args->type = XFS_ALLOCTYPE_THIS_AG; /* * Start with the given allocation group. */ args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno); flags = XFS_ALLOC_FLAG_TRYLOCK; } /* * Loop over allocation groups twice; first time with * trylock set, second time without. */ for (;;) { args->pag = xfs_perag_get(mp, args->agno); if (no_min) args->minleft = 0; error = xfs_alloc_fix_freelist(args, flags); args->minleft = minleft; if (error) { trace_xfs_alloc_vextent_nofix(args); goto error0; } /* * If we get a buffer back then the allocation will fly. */ if (args->agbp) { if ((error = xfs_alloc_ag_vextent(args))) goto error0; break; } trace_xfs_alloc_vextent_loopfailed(args); /* * Didn't work, figure out the next iteration. */ if (args->agno == sagno && type == XFS_ALLOCTYPE_START_BNO) args->type = XFS_ALLOCTYPE_THIS_AG; /* * For the first allocation, we can try any AG to get * space. However, if we already have allocated a * block, we don't want to try AGs whose number is below * sagno. Otherwise, we may end up with out-of-order * locking of AGF, which might cause deadlock. */ if (++(args->agno) == mp->m_sb.sb_agcount) { if (args->firstblock != NULLFSBLOCK) args->agno = sagno; else args->agno = 0; } /* * Reached the starting a.g., must either be done * or switch to non-trylock mode. */ if (args->agno == sagno) { if (no_min == 1) { args->agbno = NULLAGBLOCK; trace_xfs_alloc_vextent_allfailed(args); break; } if (flags == 0) { no_min = 1; } else { flags = 0; if (type == XFS_ALLOCTYPE_START_BNO) { args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); args->type = XFS_ALLOCTYPE_NEAR_BNO; } } } xfs_perag_put(args->pag); } if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) { if (args->agno == sagno) mp->m_agfrotor = (mp->m_agfrotor + 1) % (mp->m_sb.sb_agcount * rotorstep); else mp->m_agfrotor = (args->agno * rotorstep + 1) % (mp->m_sb.sb_agcount * rotorstep); } break; default: ASSERT(0); /* NOTREACHED */ } if (args->agbno == NULLAGBLOCK) args->fsbno = NULLFSBLOCK; else { args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno); #ifdef DEBUG ASSERT(args->len >= args->minlen); ASSERT(args->len <= args->maxlen); ASSERT(args->agbno % args->alignment == 0); XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); #endif } xfs_perag_put(args->pag); return 0; error0: xfs_perag_put(args->pag); return error; } /* * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent * after fixing up the freelist. */ int /* error */ xfs_free_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len) /* length of extent */ { xfs_alloc_arg_t args; int error; ASSERT(len != 0); memset(&args, 0, sizeof(xfs_alloc_arg_t)); args.tp = tp; args.mp = tp->t_mountp; args.agno = XFS_FSB_TO_AGNO(args.mp, bno); ASSERT(args.agno < args.mp->m_sb.sb_agcount); args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); args.pag = xfs_perag_get(args.mp, args.agno); if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) goto error0; #ifdef DEBUG ASSERT(args.agbp != NULL); ASSERT((args.agbno + len) <= be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); #endif error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); error0: xfs_perag_put(args.pag); return error; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_da_btree.c0000664000000000000000000020274111650373061015704 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * xfs_da_btree.c * * Routines to implement directories as Btrees of hashed names. */ /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ /* * Routines used for growing the Btree. */ STATIC int xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *existing_root, xfs_da_state_blk_t *new_child); STATIC int xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *existing_blk, xfs_da_state_blk_t *split_blk, xfs_da_state_blk_t *blk_to_add, int treelevel, int *result); STATIC void xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *node_blk_1, xfs_da_state_blk_t *node_blk_2); STATIC void xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *old_node_blk, xfs_da_state_blk_t *new_node_blk); /* * Routines used for shrinking the Btree. */ STATIC int xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk); STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *retval); STATIC void xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk); STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *src_node_blk, xfs_da_state_blk_t *dst_node_blk); /* * Utility routines. */ STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk); STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); /*======================================================================== * Routines used for growing the Btree. *========================================================================*/ /* * Create the initial contents of an intermediate node. */ int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, xfs_dabuf_t **bpp, int whichfork) { xfs_da_intnode_t *node; xfs_dabuf_t *bp; int error; xfs_trans_t *tp; tp = args->trans; error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork); if (error) return(error); ASSERT(bp != NULL); node = bp->data; node->hdr.info.forw = 0; node->hdr.info.back = 0; node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC); node->hdr.info.pad = 0; node->hdr.count = 0; node->hdr.level = cpu_to_be16(level); xfs_da_log_buf(tp, bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); *bpp = bp; return(0); } /* * Split a leaf node, rebalance, then possibly split * intermediate nodes, rebalance, etc. */ int /* error */ xfs_da_split(xfs_da_state_t *state) { xfs_da_state_blk_t *oldblk, *newblk, *addblk; xfs_da_intnode_t *node; xfs_dabuf_t *bp; int max, action, error, i; /* * Walk back up the tree splitting/inserting/adjusting as necessary. * If we need to insert and there isn't room, split the node, then * decide which fragment to insert the new block from below into. * Note that we may split the root this way, but we need more fixup. */ max = state->path.active - 1; ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC); addblk = &state->path.blk[max]; /* initial dummy value */ for (i = max; (i >= 0) && addblk; state->path.active--, i--) { oldblk = &state->path.blk[i]; newblk = &state->altpath.blk[i]; /* * If a leaf node then * Allocate a new leaf node, then rebalance across them. * else if an intermediate node then * We split on the last layer, must we split the node? */ switch (oldblk->magic) { case XFS_ATTR_LEAF_MAGIC: error = xfs_attr_leaf_split(state, oldblk, newblk); if ((error != 0) && (error != ENOSPC)) { return(error); /* GROT: attr is inconsistent */ } if (!error) { addblk = newblk; break; } /* * Entry wouldn't fit, split the leaf again. */ state->extravalid = 1; if (state->inleaf) { state->extraafter = 0; /* before newblk */ error = xfs_attr_leaf_split(state, oldblk, &state->extrablk); } else { state->extraafter = 1; /* after newblk */ error = xfs_attr_leaf_split(state, newblk, &state->extrablk); } if (error) return(error); /* GROT: attr inconsistent */ addblk = newblk; break; case XFS_DIR2_LEAFN_MAGIC: error = xfs_dir2_leafn_split(state, oldblk, newblk); if (error) return error; addblk = newblk; break; case XFS_DA_NODE_MAGIC: error = xfs_da_node_split(state, oldblk, newblk, addblk, max - i, &action); xfs_da_buf_done(addblk->bp); addblk->bp = NULL; if (error) return(error); /* GROT: dir is inconsistent */ /* * Record the newly split block for the next time thru? */ if (action) addblk = newblk; else addblk = NULL; break; } /* * Update the btree to show the new hashval for this child. */ xfs_da_fixhashpath(state, &state->path); /* * If we won't need this block again, it's getting dropped * from the active path by the loop control, so we need * to mark it done now. */ if (i > 0 || !addblk) xfs_da_buf_done(oldblk->bp); } if (!addblk) return(0); /* * Split the root node. */ ASSERT(state->path.active == 0); oldblk = &state->path.blk[0]; error = xfs_da_root_split(state, oldblk, addblk); if (error) { xfs_da_buf_done(oldblk->bp); xfs_da_buf_done(addblk->bp); addblk->bp = NULL; return(error); /* GROT: dir is inconsistent */ } /* * Update pointers to the node which used to be block 0 and * just got bumped because of the addition of a new root node. * There might be three blocks involved if a double split occurred, * and the original block 0 could be at any position in the list. */ node = oldblk->bp->data; if (node->hdr.info.forw) { if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) { bp = addblk->bp; } else { ASSERT(state->extravalid); bp = state->extrablk.bp; } node = bp->data; node->hdr.info.back = cpu_to_be32(oldblk->blkno); xfs_da_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); } node = oldblk->bp->data; if (node->hdr.info.back) { if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) { bp = addblk->bp; } else { ASSERT(state->extravalid); bp = state->extrablk.bp; } node = bp->data; node->hdr.info.forw = cpu_to_be32(oldblk->blkno); xfs_da_log_buf(state->args->trans, bp, XFS_DA_LOGRANGE(node, &node->hdr.info, sizeof(node->hdr.info))); } xfs_da_buf_done(oldblk->bp); xfs_da_buf_done(addblk->bp); addblk->bp = NULL; return(0); } /* * Split the root. We have to create a new root and point to the two * parts (the split old root) that we just created. Copy block zero to * the EOF, extending the inode in process. */ STATIC int /* error */ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2) { xfs_da_intnode_t *node, *oldroot; xfs_da_args_t *args; xfs_dablk_t blkno; xfs_dabuf_t *bp; int error, size; xfs_inode_t *dp; xfs_trans_t *tp; xfs_mount_t *mp; xfs_dir2_leaf_t *leaf; /* * Copy the existing (incorrect) block from the root node position * to a free space somewhere. */ args = state->args; ASSERT(args != NULL); error = xfs_da_grow_inode(args, &blkno); if (error) return(error); dp = args->dp; tp = args->trans; mp = state->mp; error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); node = bp->data; oldroot = blk1->bp->data; if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) { size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - (char *)oldroot); } else { ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); leaf = (xfs_dir2_leaf_t *)oldroot; size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - (char *)leaf); } memcpy(node, oldroot, size); xfs_da_log_buf(tp, bp, 0, size - 1); xfs_da_buf_done(blk1->bp); blk1->bp = bp; blk1->blkno = blkno; /* * Set up the new root node. */ error = xfs_da_node_create(args, (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); if (error) return(error); node = bp->data; node->btree[0].hashval = cpu_to_be32(blk1->hashval); node->btree[0].before = cpu_to_be32(blk1->blkno); node->btree[1].hashval = cpu_to_be32(blk2->hashval); node->btree[1].before = cpu_to_be32(blk2->blkno); node->hdr.count = cpu_to_be16(2); #ifdef DEBUG if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) { ASSERT(blk1->blkno >= mp->m_dirleafblk && blk1->blkno < mp->m_dirfreeblk); ASSERT(blk2->blkno >= mp->m_dirleafblk && blk2->blkno < mp->m_dirfreeblk); } #endif /* Header is already logged by xfs_da_node_create */ xfs_da_log_buf(tp, bp, XFS_DA_LOGRANGE(node, node->btree, sizeof(xfs_da_node_entry_t) * 2)); xfs_da_buf_done(bp); return(0); } /* * Split the node, rebalance, then add the new entry. */ STATIC int /* error */ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, xfs_da_state_blk_t *newblk, xfs_da_state_blk_t *addblk, int treelevel, int *result) { xfs_da_intnode_t *node; xfs_dablk_t blkno; int newcount, error; int useextra; node = oldblk->bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); /* * With V2 dirs the extra block is data or freespace. */ useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK; newcount = 1 + useextra; /* * Do we have to split the node? */ if ((be16_to_cpu(node->hdr.count) + newcount) > state->node_ents) { /* * Allocate a new node, add to the doubly linked chain of * nodes, then move some of our excess entries into it. */ error = xfs_da_grow_inode(state->args, &blkno); if (error) return(error); /* GROT: dir is inconsistent */ error = xfs_da_node_create(state->args, blkno, treelevel, &newblk->bp, state->args->whichfork); if (error) return(error); /* GROT: dir is inconsistent */ newblk->blkno = blkno; newblk->magic = XFS_DA_NODE_MAGIC; xfs_da_node_rebalance(state, oldblk, newblk); error = xfs_da_blk_link(state, oldblk, newblk); if (error) return(error); *result = 1; } else { *result = 0; } /* * Insert the new entry(s) into the correct block * (updating last hashval in the process). * * xfs_da_node_add() inserts BEFORE the given index, * and as a result of using node_lookup_int() we always * point to a valid entry (not after one), but a split * operation always results in a new block whose hashvals * FOLLOW the current block. * * If we had double-split op below us, then add the extra block too. */ node = oldblk->bp->data; if (oldblk->index <= be16_to_cpu(node->hdr.count)) { oldblk->index++; xfs_da_node_add(state, oldblk, addblk); if (useextra) { if (state->extraafter) oldblk->index++; xfs_da_node_add(state, oldblk, &state->extrablk); state->extravalid = 0; } } else { newblk->index++; xfs_da_node_add(state, newblk, addblk); if (useextra) { if (state->extraafter) newblk->index++; xfs_da_node_add(state, newblk, &state->extrablk); state->extravalid = 0; } } return(0); } /* * Balance the btree elements between two intermediate nodes, * usually one full and one empty. * * NOTE: if blk2 is empty, then it will get the upper half of blk1. */ STATIC void xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2) { xfs_da_intnode_t *node1, *node2, *tmpnode; xfs_da_node_entry_t *btree_s, *btree_d; int count, tmp; xfs_trans_t *tp; node1 = blk1->bp->data; node2 = blk2->bp->data; /* * Figure out how many entries need to move, and in which direction. * Swap the nodes around if that makes it simpler. */ if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && ((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) || (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { tmpnode = node1; node1 = node2; node2 = tmpnode; } ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC); ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC); count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2; if (count == 0) return; tp = state->args->trans; /* * Two cases: high-to-low and low-to-high. */ if (count > 0) { /* * Move elements in node2 up to make a hole. */ if ((tmp = be16_to_cpu(node2->hdr.count)) > 0) { tmp *= (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[0]; btree_d = &node2->btree[count]; memmove(btree_d, btree_s, tmp); } /* * Move the req'd B-tree elements from high in node1 to * low in node2. */ be16_add_cpu(&node2->hdr.count, count); tmp = count * (uint)sizeof(xfs_da_node_entry_t); btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count]; btree_d = &node2->btree[0]; memcpy(btree_d, btree_s, tmp); be16_add_cpu(&node1->hdr.count, -count); } else { /* * Move the req'd B-tree elements from low in node2 to * high in node1. */ count = -count; tmp = count * (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[0]; btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; memcpy(btree_d, btree_s, tmp); be16_add_cpu(&node1->hdr.count, count); xfs_da_log_buf(tp, blk1->bp, XFS_DA_LOGRANGE(node1, btree_d, tmp)); /* * Move elements in node2 down to fill the hole. */ tmp = be16_to_cpu(node2->hdr.count) - count; tmp *= (uint)sizeof(xfs_da_node_entry_t); btree_s = &node2->btree[count]; btree_d = &node2->btree[0]; memmove(btree_d, btree_s, tmp); be16_add_cpu(&node2->hdr.count, -count); } /* * Log header of node 1 and all current bits of node 2. */ xfs_da_log_buf(tp, blk1->bp, XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr))); xfs_da_log_buf(tp, blk2->bp, XFS_DA_LOGRANGE(node2, &node2->hdr, sizeof(node2->hdr) + sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count))); /* * Record the last hashval from each block for upward propagation. * (note: don't use the swapped node pointers) */ node1 = blk1->bp->data; node2 = blk2->bp->data; blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval); blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval); /* * Adjust the expected index for insertion. */ if (blk1->index >= be16_to_cpu(node1->hdr.count)) { blk2->index = blk1->index - be16_to_cpu(node1->hdr.count); blk1->index = be16_to_cpu(node1->hdr.count) + 1; /* make it invalid */ } } /* * Add a new entry to an intermediate node. */ STATIC void xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, xfs_da_state_blk_t *newblk) { xfs_da_intnode_t *node; xfs_da_node_entry_t *btree; int tmp; node = oldblk->bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); ASSERT(newblk->blkno != 0); if (state->args->whichfork == XFS_DATA_FORK) ASSERT(newblk->blkno >= state->mp->m_dirleafblk && newblk->blkno < state->mp->m_dirfreeblk); /* * We may need to make some room before we insert the new node. */ tmp = 0; btree = &node->btree[ oldblk->index ]; if (oldblk->index < be16_to_cpu(node->hdr.count)) { tmp = (be16_to_cpu(node->hdr.count) - oldblk->index) * (uint)sizeof(*btree); memmove(btree + 1, btree, tmp); } btree->hashval = cpu_to_be32(newblk->hashval); btree->before = cpu_to_be32(newblk->blkno); xfs_da_log_buf(state->args->trans, oldblk->bp, XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); be16_add_cpu(&node->hdr.count, 1); xfs_da_log_buf(state->args->trans, oldblk->bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); /* * Copy the last hash value from the oldblk to propagate upwards. */ oldblk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1 ].hashval); } /*======================================================================== * Routines used for shrinking the Btree. *========================================================================*/ /* * Deallocate an empty leaf node, remove it from its parent, * possibly deallocating that block, etc... */ int xfs_da_join(xfs_da_state_t *state) { xfs_da_state_blk_t *drop_blk, *save_blk; int action, error; action = 0; drop_blk = &state->path.blk[ state->path.active-1 ]; save_blk = &state->altpath.blk[ state->path.active-1 ]; ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); /* * Walk back up the tree joining/deallocating as necessary. * When we stop dropping blocks, break out. */ for ( ; state->path.active >= 2; drop_blk--, save_blk--, state->path.active--) { /* * See if we can combine the block with a neighbor. * (action == 0) => no options, just leave * (action == 1) => coalesce, then unlink * (action == 2) => block empty, unlink it */ switch (drop_blk->magic) { case XFS_ATTR_LEAF_MAGIC: error = xfs_attr_leaf_toosmall(state, &action); if (error) return(error); if (action == 0) return(0); xfs_attr_leaf_unbalance(state, drop_blk, save_blk); break; case XFS_DIR2_LEAFN_MAGIC: error = xfs_dir2_leafn_toosmall(state, &action); if (error) return error; if (action == 0) return 0; xfs_dir2_leafn_unbalance(state, drop_blk, save_blk); break; case XFS_DA_NODE_MAGIC: /* * Remove the offending node, fixup hashvals, * check for a toosmall neighbor. */ xfs_da_node_remove(state, drop_blk); xfs_da_fixhashpath(state, &state->path); error = xfs_da_node_toosmall(state, &action); if (error) return(error); if (action == 0) return 0; xfs_da_node_unbalance(state, drop_blk, save_blk); break; } xfs_da_fixhashpath(state, &state->altpath); error = xfs_da_blk_unlink(state, drop_blk, save_blk); xfs_da_state_kill_altpath(state); if (error) return(error); error = xfs_da_shrink_inode(state->args, drop_blk->blkno, drop_blk->bp); drop_blk->bp = NULL; if (error) return(error); } /* * We joined all the way to the top. If it turns out that * we only have one entry in the root, make the child block * the new root. */ xfs_da_node_remove(state, drop_blk); xfs_da_fixhashpath(state, &state->path); error = xfs_da_root_join(state, &state->path.blk[0]); return(error); } /* * We have only one entry in the root. Copy the only remaining child of * the old root to block 0 as the new root node. */ STATIC int xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) { xfs_da_intnode_t *oldroot; /* REFERENCED */ xfs_da_blkinfo_t *blkinfo; xfs_da_args_t *args; xfs_dablk_t child; xfs_dabuf_t *bp; int error; args = state->args; ASSERT(args != NULL); ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); oldroot = root_blk->bp->data; ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC); ASSERT(!oldroot->hdr.info.forw); ASSERT(!oldroot->hdr.info.back); /* * If the root has more than one child, then don't do anything. */ if (be16_to_cpu(oldroot->hdr.count) > 1) return(0); /* * Read in the (only) child block, then copy those bytes into * the root block's buffer and free the original child block. */ child = be32_to_cpu(oldroot->btree[0].before); ASSERT(child != 0); error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); blkinfo = bp->data; if (be16_to_cpu(oldroot->hdr.level) == 1) { ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); } else { ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); } ASSERT(!blkinfo->forw); ASSERT(!blkinfo->back); memcpy(root_blk->bp->data, bp->data, state->blocksize); xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); error = xfs_da_shrink_inode(args, child, bp); return(error); } /* * Check a node block and its neighbors to see if the block should be * collapsed into one or the other neighbor. Always keep the block * with the smaller block number. * If the current block is over 50% full, don't try to join it, return 0. * If the block is empty, fill in the state structure and return 2. * If it can be collapsed, fill in the state structure and return 1. * If nothing can be done, return 0. */ STATIC int xfs_da_node_toosmall(xfs_da_state_t *state, int *action) { xfs_da_intnode_t *node; xfs_da_state_blk_t *blk; xfs_da_blkinfo_t *info; int count, forward, error, retval, i; xfs_dablk_t blkno; xfs_dabuf_t *bp; /* * Check for the degenerate case of the block being over 50% full. * If so, it's not worth even looking to see if we might be able * to coalesce with a sibling. */ blk = &state->path.blk[ state->path.active-1 ]; info = blk->bp->data; ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC); node = (xfs_da_intnode_t *)info; count = be16_to_cpu(node->hdr.count); if (count > (state->node_ents >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); /* blk over 50%, don't try to join */ } /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { /* * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); if (error) return(error); if (retval) { *action = 0; } else { *action = 2; } return(0); } /* * Examine each sibling block to see if we can coalesce with * at least 25% free space to spare. We need to figure out * whether to merge with the forward or the backward block. * We prefer coalescing with the lower numbered sibling so as * to shrink a directory over time. */ /* start with smaller blk num */ forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); for (i = 0; i < 2; forward = !forward, i++) { if (forward) blkno = be32_to_cpu(info->forw); else blkno = be32_to_cpu(info->back); if (blkno == 0) continue; error = xfs_da_read_buf(state->args->trans, state->args->dp, blkno, -1, &bp, state->args->whichfork); if (error) return(error); ASSERT(bp != NULL); node = (xfs_da_intnode_t *)info; count = state->node_ents; count -= state->node_ents >> 2; count -= be16_to_cpu(node->hdr.count); node = bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); count -= be16_to_cpu(node->hdr.count); xfs_da_brelse(state->args->trans, bp); if (count >= 0) break; /* fits with at least 25% to spare */ } if (i >= 2) { *action = 0; return(0); } /* * Make altpath point to the block we want to keep (the lower * numbered block) and path point to the block we want to drop. */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) { error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); if (error) { return(error); } if (retval) { *action = 0; return(0); } } else { error = xfs_da_path_shift(state, &state->path, forward, 0, &retval); if (error) { return(error); } if (retval) { *action = 0; return(0); } } *action = 1; return(0); } /* * Walk back up the tree adjusting hash values as necessary, * when we stop making changes, return. */ void xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) { xfs_da_state_blk_t *blk; xfs_da_intnode_t *node; xfs_da_node_entry_t *btree; xfs_dahash_t lasthash=0; int level, count; level = path->active-1; blk = &path->blk[ level ]; switch (blk->magic) { case XFS_ATTR_LEAF_MAGIC: lasthash = xfs_attr_leaf_lasthash(blk->bp, &count); if (count == 0) return; break; case XFS_DIR2_LEAFN_MAGIC: lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); if (count == 0) return; break; case XFS_DA_NODE_MAGIC: lasthash = xfs_da_node_lasthash(blk->bp, &count); if (count == 0) return; break; } for (blk--, level--; level >= 0; blk--, level--) { node = blk->bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); btree = &node->btree[ blk->index ]; if (be32_to_cpu(btree->hashval) == lasthash) break; blk->hashval = lasthash; btree->hashval = cpu_to_be32(lasthash); xfs_da_log_buf(state->args->trans, blk->bp, XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); } } /* * Remove an entry from an intermediate node. */ STATIC void xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) { xfs_da_intnode_t *node; xfs_da_node_entry_t *btree; int tmp; node = drop_blk->bp->data; ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count)); ASSERT(drop_blk->index >= 0); /* * Copy over the offending entry, or just zero it out. */ btree = &node->btree[drop_blk->index]; if (drop_blk->index < (be16_to_cpu(node->hdr.count)-1)) { tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1; tmp *= (uint)sizeof(xfs_da_node_entry_t); memmove(btree, btree + 1, tmp); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, btree, tmp)); btree = &node->btree[be16_to_cpu(node->hdr.count)-1]; } memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); be16_add_cpu(&node->hdr.count, -1); xfs_da_log_buf(state->args->trans, drop_blk->bp, XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); /* * Copy the last hash value from the block to propagate upwards. */ btree--; drop_blk->hashval = be32_to_cpu(btree->hashval); } /* * Unbalance the btree elements between two intermediate nodes, * move all Btree elements from one node into another. */ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk) { xfs_da_intnode_t *drop_node, *save_node; xfs_da_node_entry_t *btree; int tmp; xfs_trans_t *tp; drop_node = drop_blk->bp->data; save_node = save_blk->bp->data; ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); tp = state->args->trans; /* * If the dying block has lower hashvals, then move all the * elements in the remaining block up to make a hole. */ if ((be32_to_cpu(drop_node->btree[0].hashval) < be32_to_cpu(save_node->btree[ 0 ].hashval)) || (be32_to_cpu(drop_node->btree[be16_to_cpu(drop_node->hdr.count)-1].hashval) < be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval))) { btree = &save_node->btree[be16_to_cpu(drop_node->hdr.count)]; tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); memmove(btree, &save_node->btree[0], tmp); btree = &save_node->btree[0]; xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, btree, (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) * sizeof(xfs_da_node_entry_t))); } else { btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)]; xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, btree, be16_to_cpu(drop_node->hdr.count) * sizeof(xfs_da_node_entry_t))); } /* * Move all the B-tree elements from drop_blk to save_blk. */ tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); memcpy(btree, &drop_node->btree[0], tmp); be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); xfs_da_log_buf(tp, save_blk->bp, XFS_DA_LOGRANGE(save_node, &save_node->hdr, sizeof(save_node->hdr))); /* * Save the last hashval in the remaining block for upward propagation. */ save_blk->hashval = be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval); } /*======================================================================== * Routines used for finding things in the Btree. *========================================================================*/ /* * Walk down the Btree looking for a particular filename, filling * in the state structure as we go. * * We will set the state structure to point to each of the elements * in each of the nodes where either the hashval is or should be. * * We support duplicate hashval's so for each entry in the current * node that could contain the desired hashval, descend. This is a * pruned depth-first tree search. */ int /* error */ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) { xfs_da_state_blk_t *blk; xfs_da_blkinfo_t *curr; xfs_da_intnode_t *node; xfs_da_node_entry_t *btree; xfs_dablk_t blkno; int probe, span, max, error, retval; xfs_dahash_t hashval, btreehashval; xfs_da_args_t *args; args = state->args; /* * Descend thru the B-tree searching each level for the right * node to use, until the right hashval is found. */ blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; for (blk = &state->path.blk[0], state->path.active = 1; state->path.active <= XFS_DA_NODE_MAXDEPTH; blk++, state->path.active++) { /* * Read the next node down in the tree. */ blk->blkno = blkno; error = xfs_da_read_buf(args->trans, args->dp, blkno, -1, &blk->bp, args->whichfork); if (error) { blk->blkno = 0; state->path.active--; return(error); } curr = blk->bp->data; blk->magic = be16_to_cpu(curr->magic); ASSERT(blk->magic == XFS_DA_NODE_MAGIC || blk->magic == XFS_DIR2_LEAFN_MAGIC || blk->magic == XFS_ATTR_LEAF_MAGIC); /* * Search an intermediate node for a match. */ if (blk->magic == XFS_DA_NODE_MAGIC) { node = blk->bp->data; max = be16_to_cpu(node->hdr.count); blk->hashval = be32_to_cpu(node->btree[max-1].hashval); /* * Binary search. (note: small blocks will skip loop) */ probe = span = max / 2; hashval = args->hashval; for (btree = &node->btree[probe]; span > 4; btree = &node->btree[probe]) { span /= 2; btreehashval = be32_to_cpu(btree->hashval); if (btreehashval < hashval) probe += span; else if (btreehashval > hashval) probe -= span; else break; } ASSERT((probe >= 0) && (probe < max)); ASSERT((span <= 4) || (be32_to_cpu(btree->hashval) == hashval)); /* * Since we may have duplicate hashval's, find the first * matching hashval in the node. */ while ((probe > 0) && (be32_to_cpu(btree->hashval) >= hashval)) { btree--; probe--; } while ((probe < max) && (be32_to_cpu(btree->hashval) < hashval)) { btree++; probe++; } /* * Pick the right block to descend on. */ if (probe == max) { blk->index = max-1; blkno = be32_to_cpu(node->btree[max-1].before); } else { blk->index = probe; blkno = be32_to_cpu(btree->before); } } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); break; } } /* * A leaf block that ends in the hashval that we are interested in * (final hashval == search hashval) means that the next block may * contain more entries with the same hashval, shift upward to the * next leaf and keep searching. */ for (;;) { if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { retval = xfs_dir2_leafn_lookup_int(blk->bp, args, &blk->index, state); } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { retval = xfs_attr_leaf_lookup_int(blk->bp, args); blk->index = args->index; args->blkno = blk->blkno; } else { ASSERT(0); return XFS_ERROR(EFSCORRUPTED); } if (((retval == ENOENT) || (retval == ENOATTR)) && (blk->hashval == args->hashval)) { error = xfs_da_path_shift(state, &state->path, 1, 1, &retval); if (error) return(error); if (retval == 0) { continue; } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { /* path_shift() gives ENOENT */ retval = XFS_ERROR(ENOATTR); } } break; } *result = retval; return(0); } /*======================================================================== * Utility routines. *========================================================================*/ /* * Link a new block into a doubly linked list of blocks (of whatever type). */ int /* error */ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, xfs_da_state_blk_t *new_blk) { xfs_da_blkinfo_t *old_info, *new_info, *tmp_info; xfs_da_args_t *args; int before=0, error; xfs_dabuf_t *bp; /* * Set up environment. */ args = state->args; ASSERT(args != NULL); old_info = old_blk->bp->data; new_info = new_blk->bp->data; ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || old_blk->magic == XFS_DIR2_LEAFN_MAGIC || old_blk->magic == XFS_ATTR_LEAF_MAGIC); ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); ASSERT(old_blk->magic == new_blk->magic); switch (old_blk->magic) { case XFS_ATTR_LEAF_MAGIC: before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); break; case XFS_DIR2_LEAFN_MAGIC: before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); break; case XFS_DA_NODE_MAGIC: before = xfs_da_node_order(old_blk->bp, new_blk->bp); break; } /* * Link blocks in appropriate order. */ if (before) { /* * Link new block in before existing block. */ new_info->forw = cpu_to_be32(old_blk->blkno); new_info->back = old_info->back; if (old_info->back) { error = xfs_da_read_buf(args->trans, args->dp, be32_to_cpu(old_info->back), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic)); ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno); tmp_info->forw = cpu_to_be32(new_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); xfs_da_buf_done(bp); } old_info->back = cpu_to_be32(new_blk->blkno); } else { /* * Link new block in after existing block. */ new_info->forw = old_info->forw; new_info->back = cpu_to_be32(old_blk->blkno); if (old_info->forw) { error = xfs_da_read_buf(args->trans, args->dp, be32_to_cpu(old_info->forw), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; ASSERT(tmp_info->magic == old_info->magic); ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno); tmp_info->back = cpu_to_be32(new_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); xfs_da_buf_done(bp); } old_info->forw = cpu_to_be32(new_blk->blkno); } xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); return(0); } /* * Compare two intermediate nodes for "order". */ STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) { xfs_da_intnode_t *node1, *node2; node1 = node1_bp->data; node2 = node2_bp->data; ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) && (be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC)); if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && ((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) || (be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) < be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) { return(1); } return(0); } /* * Pick up the last hashvalue from an intermediate node. */ STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) { xfs_da_intnode_t *node; node = bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); if (count) *count = be16_to_cpu(node->hdr.count); if (!node->hdr.count) return(0); return be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); } /* * Unlink a block from a doubly linked list of blocks. */ STATIC int /* error */ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk) { xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info; xfs_da_args_t *args; xfs_dabuf_t *bp; int error; /* * Set up environment. */ args = state->args; ASSERT(args != NULL); save_info = save_blk->bp->data; drop_info = drop_blk->bp->data; ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || save_blk->magic == XFS_DIR2_LEAFN_MAGIC || save_blk->magic == XFS_ATTR_LEAF_MAGIC); ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); ASSERT(save_blk->magic == drop_blk->magic); ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) || (be32_to_cpu(save_info->back) == drop_blk->blkno)); ASSERT((be32_to_cpu(drop_info->forw) == save_blk->blkno) || (be32_to_cpu(drop_info->back) == save_blk->blkno)); /* * Unlink the leaf block from the doubly linked chain of leaves. */ if (be32_to_cpu(save_info->back) == drop_blk->blkno) { save_info->back = drop_info->back; if (drop_info->back) { error = xfs_da_read_buf(args->trans, args->dp, be32_to_cpu(drop_info->back), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; ASSERT(tmp_info->magic == save_info->magic); ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno); tmp_info->forw = cpu_to_be32(save_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); xfs_da_buf_done(bp); } } else { save_info->forw = drop_info->forw; if (drop_info->forw) { error = xfs_da_read_buf(args->trans, args->dp, be32_to_cpu(drop_info->forw), -1, &bp, args->whichfork); if (error) return(error); ASSERT(bp != NULL); tmp_info = bp->data; ASSERT(tmp_info->magic == save_info->magic); ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno); tmp_info->back = cpu_to_be32(save_blk->blkno); xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info) - 1); xfs_da_buf_done(bp); } } xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); return(0); } /* * Move a path "forward" or "!forward" one block at the current level. * * This routine will adjust a "path" to point to the next block * "forward" (higher hashvalues) or "!forward" (lower hashvals) in the * Btree, including updating pointers to the intermediate nodes between * the new bottom and the root. */ int /* error */ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, int forward, int release, int *result) { xfs_da_state_blk_t *blk; xfs_da_blkinfo_t *info; xfs_da_intnode_t *node; xfs_da_args_t *args; xfs_dablk_t blkno=0; int level, error; /* * Roll up the Btree looking for the first block where our * current index is not at the edge of the block. Note that * we skip the bottom layer because we want the sibling block. */ args = state->args; ASSERT(args != NULL); ASSERT(path != NULL); ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); level = (path->active-1) - 1; /* skip bottom layer in path */ for (blk = &path->blk[level]; level >= 0; blk--, level--) { ASSERT(blk->bp != NULL); node = blk->bp->data; ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { blk->index++; blkno = be32_to_cpu(node->btree[blk->index].before); break; } else if (!forward && (blk->index > 0)) { blk->index--; blkno = be32_to_cpu(node->btree[blk->index].before); break; } } if (level < 0) { *result = XFS_ERROR(ENOENT); /* we're out of our tree */ ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); return(0); } /* * Roll down the edge of the subtree until we reach the * same depth we were at originally. */ for (blk++, level++; level < path->active; blk++, level++) { /* * Release the old block. * (if it's dirty, trans won't actually let go) */ if (release) xfs_da_brelse(args->trans, blk->bp); /* * Read the next child block. */ blk->blkno = blkno; error = xfs_da_read_buf(args->trans, args->dp, blkno, -1, &blk->bp, args->whichfork); if (error) return(error); ASSERT(blk->bp != NULL); info = blk->bp->data; ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); blk->magic = be16_to_cpu(info->magic); if (blk->magic == XFS_DA_NODE_MAGIC) { node = (xfs_da_intnode_t *)info; blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); if (forward) blk->index = 0; else blk->index = be16_to_cpu(node->hdr.count)-1; blkno = be32_to_cpu(node->btree[blk->index].before); } else { ASSERT(level == path->active-1); blk->index = 0; switch(blk->magic) { case XFS_ATTR_LEAF_MAGIC: blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; case XFS_DIR2_LEAFN_MAGIC: blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); break; default: ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || blk->magic == XFS_DIR2_LEAFN_MAGIC); break; } } } *result = 0; return(0); } /*======================================================================== * Utility routines. *========================================================================*/ /* * Implement a simple hash on a character string. * Rotate the hash value by 7 bits, then XOR each character in. * This is implemented with some source-level loop unrolling. */ xfs_dahash_t xfs_da_hashname(const __uint8_t *name, int namelen) { xfs_dahash_t hash; /* * Do four characters at a time as long as we can. */ for (hash = 0; namelen >= 4; namelen -= 4, name += 4) hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^ (name[3] << 0) ^ rol32(hash, 7 * 4); /* * Now do the rest of the characters. */ switch (namelen) { case 3: return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^ rol32(hash, 7 * 3); case 2: return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2); case 1: return (name[0] << 0) ^ rol32(hash, 7 * 1); default: /* case 0: */ return hash; } } enum xfs_dacmp xfs_da_compname( struct xfs_da_args *args, const unsigned char *name, int len) { return (args->namelen == len && memcmp(args->name, name, len) == 0) ? XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } static xfs_dahash_t xfs_default_hashname( struct xfs_name *name) { return xfs_da_hashname(name->name, name->len); } const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, .compname = xfs_da_compname }; /* * Add a block to the btree ahead of the file. * Return the new block number to the caller. */ int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) { xfs_fileoff_t bno, b; xfs_bmbt_irec_t map; xfs_bmbt_irec_t *mapp; xfs_inode_t *dp; int nmap, error, w, count, c, got, i, mapi; xfs_trans_t *tp; xfs_mount_t *mp; xfs_drfsbno_t nblks; dp = args->dp; mp = dp->i_mount; w = args->whichfork; tp = args->trans; nblks = dp->i_d.di_nblocks; /* * For new directories adjust the file offset and block count. */ if (w == XFS_DATA_FORK) { bno = mp->m_dirleafblk; count = mp->m_dirblkfsbs; } else { bno = 0; count = 1; } /* * Find a spot in the file space to put the new block. */ if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) return error; if (w == XFS_DATA_FORK) ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); /* * Try mapping it in one filesystem block. */ nmap = 1; ASSERT(args->firstblock != NULL); if ((error = xfs_bmapi(tp, dp, bno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, args->flist))) { return error; } ASSERT(nmap <= 1); if (nmap == 1) { mapp = ↦ mapi = 1; } /* * If we didn't get it and the block might work if fragmented, * try without the CONTIG flag. Loop until we get it all. */ else if (nmap == 0 && count > 1) { mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); for (b = bno, mapi = 0; b < bno + count; ) { nmap = MIN(XFS_BMAP_MAX_NMAP, count); c = (int)(bno + count - b); if ((error = xfs_bmapi(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| XFS_BMAPI_METADATA, args->firstblock, args->total, &mapp[mapi], &nmap, args->flist))) { kmem_free(mapp); return error; } if (nmap < 1) break; mapi += nmap; b = mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount; } } else { mapi = 0; mapp = NULL; } /* * Count the blocks we got, make sure it matches the total. */ for (i = 0, got = 0; i < mapi; i++) got += mapp[i].br_blockcount; if (got != count || mapp[0].br_startoff != bno || mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != bno + count) { if (mapp != &map) kmem_free(mapp); return XFS_ERROR(ENOSPC); } if (mapp != &map) kmem_free(mapp); /* account for newly allocated blocks in reserved blocks total */ args->total -= dp->i_d.di_nblocks - nblks; *new_blkno = (xfs_dablk_t)bno; return 0; } /* * Ick. We need to always be able to remove a btree block, even * if there's no space reservation because the filesystem is full. * This is called if xfs_bunmapi on a btree block fails due to ENOSPC. * It swaps the target block with the last block in the file. The * last block in the file can always be removed since it can't cause * a bmap btree split to do that. */ STATIC int xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, xfs_dabuf_t **dead_bufp) { xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno; xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf; xfs_fileoff_t lastoff; xfs_inode_t *ip; xfs_trans_t *tp; xfs_mount_t *mp; int error, w, entno, level, dead_level; xfs_da_blkinfo_t *dead_info, *sib_info; xfs_da_intnode_t *par_node, *dead_node; xfs_dir2_leaf_t *dead_leaf2; xfs_dahash_t dead_hash; dead_buf = *dead_bufp; dead_blkno = *dead_blknop; tp = args->trans; ip = args->dp; w = args->whichfork; ASSERT(w == XFS_DATA_FORK); mp = ip->i_mount; lastoff = mp->m_dirfreeblk; error = xfs_bmap_last_before(tp, ip, &lastoff, w); if (error) return error; if (unlikely(lastoff == 0)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } /* * Read the last block in the btree space. */ last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; if ((error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w))) return error; /* * Copy the last block into the dead buffer and log it. */ memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize); xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); dead_info = dead_buf->data; /* * Get values from the moved block. */ if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; dead_level = 0; dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); } else { ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC); dead_node = (xfs_da_intnode_t *)dead_info; dead_level = be16_to_cpu(dead_node->hdr.level); dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval); } sib_buf = par_buf = NULL; /* * If the moved block has a left sibling, fix up the pointers. */ if ((sib_blkno = be32_to_cpu(dead_info->back))) { if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; if (unlikely( be32_to_cpu(sib_info->forw) != last_blkno || sib_info->magic != dead_info->magic)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } sib_info->forw = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->forw, sizeof(sib_info->forw))); xfs_da_buf_done(sib_buf); sib_buf = NULL; } /* * If the moved block has a right sibling, fix up the pointers. */ if ((sib_blkno = be32_to_cpu(dead_info->forw))) { if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; if (unlikely( be32_to_cpu(sib_info->back) != last_blkno || sib_info->magic != dead_info->magic)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } sib_info->back = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, sib_buf, XFS_DA_LOGRANGE(sib_info, &sib_info->back, sizeof(sib_info->back))); xfs_da_buf_done(sib_buf); sib_buf = NULL; } par_blkno = mp->m_dirleafblk; level = -1; /* * Walk down the tree looking for the parent of the moved block. */ for (;;) { if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) goto done; par_node = par_buf->data; if (unlikely( be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC || (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } level = be16_to_cpu(par_node->hdr.level); for (entno = 0; entno < be16_to_cpu(par_node->hdr.count) && be32_to_cpu(par_node->btree[entno].hashval) < dead_hash; entno++) continue; if (unlikely(entno == be16_to_cpu(par_node->hdr.count))) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } par_blkno = be32_to_cpu(par_node->btree[entno].before); if (level == dead_level + 1) break; xfs_da_brelse(tp, par_buf); par_buf = NULL; } /* * We're in the right parent block. * Look for the right entry. */ for (;;) { for (; entno < be16_to_cpu(par_node->hdr.count) && be32_to_cpu(par_node->btree[entno].before) != last_blkno; entno++) continue; if (entno < be16_to_cpu(par_node->hdr.count)) break; par_blkno = be32_to_cpu(par_node->hdr.info.forw); xfs_da_brelse(tp, par_buf); par_buf = NULL; if (unlikely(par_blkno == 0)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) goto done; par_node = par_buf->data; if (unlikely( be16_to_cpu(par_node->hdr.level) != level || be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) { XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } entno = 0; } /* * Update the parent entry pointing to the moved block. */ par_node->btree[entno].before = cpu_to_be32(dead_blkno); xfs_da_log_buf(tp, par_buf, XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, sizeof(par_node->btree[entno].before))); xfs_da_buf_done(par_buf); xfs_da_buf_done(dead_buf); *dead_blknop = last_blkno; *dead_bufp = last_buf; return 0; done: if (par_buf) xfs_da_brelse(tp, par_buf); if (sib_buf) xfs_da_brelse(tp, sib_buf); xfs_da_brelse(tp, last_buf); return error; } /* * Remove a btree block from a directory or attribute. */ int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, xfs_dabuf_t *dead_buf) { xfs_inode_t *dp; int done, error, w, count; xfs_trans_t *tp; xfs_mount_t *mp; dp = args->dp; w = args->whichfork; tp = args->trans; mp = dp->i_mount; if (w == XFS_DATA_FORK) count = mp->m_dirblkfsbs; else count = 1; for (;;) { /* * Remove extents. If we get ENOSPC for a dir we have to move * the last block to the place we want to kill. */ if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, &done)) == ENOSPC) { if (w != XFS_DATA_FORK) break; if ((error = xfs_da_swap_lastblock(args, &dead_blkno, &dead_buf))) break; } else { break; } } xfs_da_binval(tp, dead_buf); return error; } /* * See if the mapping(s) for this btree block are valid, i.e. * don't contain holes, are logically contiguous, and cover the whole range. */ STATIC int xfs_da_map_covers_blocks( int nmap, xfs_bmbt_irec_t *mapp, xfs_dablk_t bno, int count) { int i; xfs_fileoff_t off; for (i = 0, off = bno; i < nmap; i++) { if (mapp[i].br_startblock == HOLESTARTBLOCK || mapp[i].br_startblock == DELAYSTARTBLOCK) { return 0; } if (off != mapp[i].br_startoff) { return 0; } off += mapp[i].br_blockcount; } return off == bno + count; } /* * Make a dabuf. * Used for get_buf, read_buf, read_bufr, and reada_buf. */ int xfs_da_do_buf( xfs_trans_t *trans, xfs_inode_t *dp, xfs_dablk_t bno, xfs_daddr_t *mappedbnop, xfs_dabuf_t **bpp, int whichfork, int caller, inst_t *ra) { xfs_buf_t *bp = NULL; xfs_buf_t **bplist; int error=0; int i; xfs_bmbt_irec_t map; xfs_bmbt_irec_t *mapp; xfs_daddr_t mappedbno; xfs_mount_t *mp; int nbplist=0; int nfsb; int nmap; xfs_dabuf_t *rbp; mp = dp->i_mount; nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; mappedbno = *mappedbnop; /* * Caller doesn't have a mapping. -2 means don't complain * if we land in a hole. */ if (mappedbno == -1 || mappedbno == -2) { /* * Optimize the one-block case. */ if (nfsb == 1) { xfs_fsblock_t fsb; if ((error = xfs_bmapi_single(trans, dp, whichfork, &fsb, (xfs_fileoff_t)bno))) { return error; } mapp = ↦ if (fsb == NULLFSBLOCK) { nmap = 0; } else { map.br_startblock = fsb; map.br_startoff = (xfs_fileoff_t)bno; map.br_blockcount = 1; nmap = 1; } } else { mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP); nmap = nfsb; if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno, nfsb, XFS_BMAPI_METADATA | xfs_bmapi_aflag(whichfork), NULL, 0, mapp, &nmap, NULL))) goto exit0; } } else { map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); map.br_startoff = (xfs_fileoff_t)bno; map.br_blockcount = nfsb; mapp = ↦ nmap = 1; } if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); if (unlikely(error == EFSCORRUPTED)) { if (xfs_error_level >= XFS_ERRLEVEL_LOW) { cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n", (long long)bno); cmn_err(CE_ALERT, "dir: inode %lld\n", (long long)dp->i_ino); for (i = 0; i < nmap; i++) { cmn_err(CE_ALERT, "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n", i, (long long)mapp[i].br_startoff, (long long)mapp[i].br_startblock, (long long)mapp[i].br_blockcount, mapp[i].br_state); } } XFS_ERROR_REPORT("xfs_da_do_buf(1)", XFS_ERRLEVEL_LOW, mp); } goto exit0; } if (caller != 3 && nmap > 1) { bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP); nbplist = 0; } else bplist = NULL; /* * Turn the mapping(s) into buffer(s). */ for (i = 0; i < nmap; i++) { int nmapped; mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock); if (i == 0) *mappedbnop = mappedbno; nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount); switch (caller) { case 0: bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, mappedbno, nmapped, 0); error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO); break; case 1: case 2: bp = NULL; error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp, mappedbno, nmapped, 0, &bp); break; case 3: xfs_buf_readahead(mp->m_ddev_targp, mappedbno, nmapped); error = 0; bp = NULL; break; } if (error) { if (bp) xfs_trans_brelse(trans, bp); goto exit1; } if (!bp) continue; if (caller == 1) { if (whichfork == XFS_ATTR_FORK) { XFS_BUF_SET_VTYPE_REF(bp, B_FS_ATTR_BTREE, XFS_ATTR_BTREE_REF); } else { XFS_BUF_SET_VTYPE_REF(bp, B_FS_DIR_BTREE, XFS_DIR_BTREE_REF); } } if (bplist) { bplist[nbplist++] = bp; } } /* * Build a dabuf structure. */ if (bplist) { rbp = xfs_da_buf_make(nbplist, bplist, ra); } else if (bp) rbp = xfs_da_buf_make(1, &bp, ra); else rbp = NULL; /* * For read_buf, check the magic number. */ if (caller == 1) { xfs_dir2_data_t *data; xfs_dir2_free_t *free; xfs_da_blkinfo_t *info; uint magic, magic1; info = rbp->data; data = rbp->data; free = rbp->data; magic = be16_to_cpu(info->magic); magic1 = be32_to_cpu(data->hdr.magic); if (unlikely( XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && (magic != XFS_ATTR_LEAF_MAGIC) && (magic != XFS_DIR2_LEAF1_MAGIC) && (magic != XFS_DIR2_LEAFN_MAGIC) && (magic1 != XFS_DIR2_BLOCK_MAGIC) && (magic1 != XFS_DIR2_DATA_MAGIC) && (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC), mp, XFS_ERRTAG_DA_READ_BUF, XFS_RANDOM_DA_READ_BUF))) { trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", XFS_ERRLEVEL_LOW, mp, info); error = XFS_ERROR(EFSCORRUPTED); xfs_da_brelse(trans, rbp); nbplist = 0; goto exit1; } } if (bplist) { kmem_free(bplist); } if (mapp != &map) { kmem_free(mapp); } if (bpp) *bpp = rbp; return 0; exit1: if (bplist) { for (i = 0; i < nbplist; i++) xfs_trans_brelse(trans, bplist[i]); kmem_free(bplist); } exit0: if (mapp != &map) kmem_free(mapp); if (bpp) *bpp = NULL; return error; } /* * Get a buffer for the dir/attr block. */ int xfs_da_get_buf( xfs_trans_t *trans, xfs_inode_t *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dabuf_t **bpp, int whichfork) { return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0, (inst_t *)__return_address); } /* * Get a buffer for the dir/attr block, fill in the contents. */ int xfs_da_read_buf( xfs_trans_t *trans, xfs_inode_t *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dabuf_t **bpp, int whichfork) { return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1, (inst_t *)__return_address); } /* * Readahead the dir/attr block. */ xfs_daddr_t xfs_da_reada_buf( xfs_trans_t *trans, xfs_inode_t *dp, xfs_dablk_t bno, int whichfork) { xfs_daddr_t rval; rval = -1; if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3, (inst_t *)__return_address)) return -1; else return rval; } kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ /* * Allocate a dir-state structure. * We don't put them on the stack since they're large. */ xfs_da_state_t * xfs_da_state_alloc(void) { return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS); } /* * Kill the altpath contents of a da-state structure. */ STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state) { int i; for (i = 0; i < state->altpath.active; i++) { if (state->altpath.blk[i].bp) { if (state->altpath.blk[i].bp != state->path.blk[i].bp) xfs_da_buf_done(state->altpath.blk[i].bp); state->altpath.blk[i].bp = NULL; } } state->altpath.active = 0; } /* * Free a da-state structure. */ void xfs_da_state_free(xfs_da_state_t *state) { int i; xfs_da_state_kill_altpath(state); for (i = 0; i < state->path.active; i++) { if (state->path.blk[i].bp) xfs_da_buf_done(state->path.blk[i].bp); } if (state->extravalid && state->extrablk.bp) xfs_da_buf_done(state->extrablk.bp); #ifdef DEBUG memset((char *)state, 0, sizeof(*state)); #endif /* DEBUG */ kmem_zone_free(xfs_da_state_zone, state); } #ifdef XFS_DABUF_DEBUG xfs_dabuf_t *xfs_dabuf_global_list; static DEFINE_SPINLOCK(xfs_dabuf_global_lock); #endif /* * Create a dabuf. */ /* ARGSUSED */ STATIC xfs_dabuf_t * xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) { xfs_buf_t *bp; xfs_dabuf_t *dabuf; int i; int off; if (nbuf == 1) dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); else dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); dabuf->dirty = 0; #ifdef XFS_DABUF_DEBUG dabuf->ra = ra; dabuf->target = XFS_BUF_TARGET(bps[0]); dabuf->blkno = XFS_BUF_ADDR(bps[0]); #endif if (nbuf == 1) { dabuf->nbuf = 1; bp = bps[0]; dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); dabuf->data = XFS_BUF_PTR(bp); dabuf->bps[0] = bp; } else { dabuf->nbuf = nbuf; for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) { dabuf->bps[i] = bp = bps[i]; dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp)); } dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = bps[i]; memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp)); } } #ifdef XFS_DABUF_DEBUG { xfs_dabuf_t *p; spin_lock(&xfs_dabuf_global_lock); for (p = xfs_dabuf_global_list; p; p = p->next) { ASSERT(p->blkno != dabuf->blkno || p->target != dabuf->target); } dabuf->prev = NULL; if (xfs_dabuf_global_list) xfs_dabuf_global_list->prev = dabuf; dabuf->next = xfs_dabuf_global_list; xfs_dabuf_global_list = dabuf; spin_unlock(&xfs_dabuf_global_lock); } #endif return dabuf; } /* * Un-dirty a dabuf. */ STATIC void xfs_da_buf_clean(xfs_dabuf_t *dabuf) { xfs_buf_t *bp; int i; int off; if (dabuf->dirty) { ASSERT(dabuf->nbuf > 1); dabuf->dirty = 0; for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = dabuf->bps[i]; memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off, XFS_BUF_COUNT(bp)); } } } /* * Release a dabuf. */ void xfs_da_buf_done(xfs_dabuf_t *dabuf) { ASSERT(dabuf); ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); if (dabuf->dirty) xfs_da_buf_clean(dabuf); if (dabuf->nbuf > 1) kmem_free(dabuf->data); #ifdef XFS_DABUF_DEBUG { spin_lock(&xfs_dabuf_global_lock); if (dabuf->prev) dabuf->prev->next = dabuf->next; else xfs_dabuf_global_list = dabuf->next; if (dabuf->next) dabuf->next->prev = dabuf->prev; spin_unlock(&xfs_dabuf_global_lock); } memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); #endif if (dabuf->nbuf == 1) kmem_zone_free(xfs_dabuf_zone, dabuf); else kmem_free(dabuf); } /* * Log transaction from a dabuf. */ void xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) { xfs_buf_t *bp; uint f; int i; uint l; int off; ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); if (dabuf->nbuf == 1) { ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0])); xfs_trans_log_buf(tp, dabuf->bps[0], first, last); return; } dabuf->dirty = 1; ASSERT(first <= last); for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = dabuf->bps[i]; f = off; l = f + XFS_BUF_COUNT(bp) - 1; if (f < first) f = first; if (l > last) l = last; if (f <= l) xfs_trans_log_buf(tp, bp, f - off, l - off); /* * B_DONE is set by xfs_trans_log buf. * If we don't set it on a new buffer (get not read) * then if we don't put anything in the buffer it won't * be set, and at commit it it released into the cache, * and then a read will fail. */ else if (!(XFS_BUF_ISDONE(bp))) XFS_BUF_DONE(bp); } ASSERT(last < off); } /* * Release dabuf from a transaction. * Have to free up the dabuf before the buffers are released, * since the synchronization on the dabuf is really the lock on the buffer. */ void xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) { xfs_buf_t *bp; xfs_buf_t **bplist; int i; int nbuf; ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); if ((nbuf = dabuf->nbuf) == 1) { bplist = &bp; bp = dabuf->bps[0]; } else { bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); } xfs_da_buf_done(dabuf); for (i = 0; i < nbuf; i++) xfs_trans_brelse(tp, bplist[i]); if (bplist != &bp) kmem_free(bplist); } /* * Invalidate dabuf from a transaction. */ void xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) { xfs_buf_t *bp; xfs_buf_t **bplist; int i; int nbuf; ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); if ((nbuf = dabuf->nbuf) == 1) { bplist = &bp; bp = dabuf->bps[0]; } else { bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); } xfs_da_buf_done(dabuf); for (i = 0; i < nbuf; i++) xfs_trans_binval(tp, bplist[i]); if (bplist != &bp) kmem_free(bplist); } /* * Get the first daddr from a dabuf. */ xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf) { ASSERT(dabuf->nbuf); ASSERT(dabuf->data); return XFS_BUF_ADDR(dabuf->bps[0]); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_mount.c0000664000000000000000000002601611650373061015300 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include static const struct { short offset; short type; /* 0 = integer * 1 = binary / string (no translation) */ } xfs_sb_info[] = { { offsetof(xfs_sb_t, sb_magicnum), 0 }, { offsetof(xfs_sb_t, sb_blocksize), 0 }, { offsetof(xfs_sb_t, sb_dblocks), 0 }, { offsetof(xfs_sb_t, sb_rblocks), 0 }, { offsetof(xfs_sb_t, sb_rextents), 0 }, { offsetof(xfs_sb_t, sb_uuid), 1 }, { offsetof(xfs_sb_t, sb_logstart), 0 }, { offsetof(xfs_sb_t, sb_rootino), 0 }, { offsetof(xfs_sb_t, sb_rbmino), 0 }, { offsetof(xfs_sb_t, sb_rsumino), 0 }, { offsetof(xfs_sb_t, sb_rextsize), 0 }, { offsetof(xfs_sb_t, sb_agblocks), 0 }, { offsetof(xfs_sb_t, sb_agcount), 0 }, { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, { offsetof(xfs_sb_t, sb_logblocks), 0 }, { offsetof(xfs_sb_t, sb_versionnum), 0 }, { offsetof(xfs_sb_t, sb_sectsize), 0 }, { offsetof(xfs_sb_t, sb_inodesize), 0 }, { offsetof(xfs_sb_t, sb_inopblock), 0 }, { offsetof(xfs_sb_t, sb_fname[0]), 1 }, { offsetof(xfs_sb_t, sb_blocklog), 0 }, { offsetof(xfs_sb_t, sb_sectlog), 0 }, { offsetof(xfs_sb_t, sb_inodelog), 0 }, { offsetof(xfs_sb_t, sb_inopblog), 0 }, { offsetof(xfs_sb_t, sb_agblklog), 0 }, { offsetof(xfs_sb_t, sb_rextslog), 0 }, { offsetof(xfs_sb_t, sb_inprogress), 0 }, { offsetof(xfs_sb_t, sb_imax_pct), 0 }, { offsetof(xfs_sb_t, sb_icount), 0 }, { offsetof(xfs_sb_t, sb_ifree), 0 }, { offsetof(xfs_sb_t, sb_fdblocks), 0 }, { offsetof(xfs_sb_t, sb_frextents), 0 }, { offsetof(xfs_sb_t, sb_uquotino), 0 }, { offsetof(xfs_sb_t, sb_gquotino), 0 }, { offsetof(xfs_sb_t, sb_qflags), 0 }, { offsetof(xfs_sb_t, sb_flags), 0 }, { offsetof(xfs_sb_t, sb_shared_vn), 0 }, { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, { offsetof(xfs_sb_t, sb_unit), 0 }, { offsetof(xfs_sb_t, sb_width), 0 }, { offsetof(xfs_sb_t, sb_dirblklog), 0 }, { offsetof(xfs_sb_t, sb_logsectlog), 0 }, { offsetof(xfs_sb_t, sb_logsectsize),0 }, { offsetof(xfs_sb_t, sb_logsunit), 0 }, { offsetof(xfs_sb_t, sb_features2), 0 }, { offsetof(xfs_sb_t, sb_bad_features2), 0 }, { sizeof(xfs_sb_t), 0 } }; /* * Reference counting access wrappers to the perag structures. * Because we never free per-ag structures, the only thing we * have to protect against changes is the tree structure itself. */ struct xfs_perag * xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno) { struct xfs_perag *pag; int ref = 0; rcu_read_lock(); pag = radix_tree_lookup(&mp->m_perag_tree, agno); if (pag) { ASSERT(atomic_read(&pag->pag_ref) >= 0); ref = atomic_inc_return(&pag->pag_ref); } trace_xfs_perag_get(mp, agno, ref, _RET_IP_); rcu_read_unlock(); return pag; } void xfs_perag_put(struct xfs_perag *pag) { int ref; ASSERT(atomic_read(&pag->pag_ref) > 0); ref = atomic_dec_return(&pag->pag_ref); trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); } void xfs_sb_from_disk( xfs_sb_t *to, xfs_dsb_t *from) { to->sb_magicnum = be32_to_cpu(from->sb_magicnum); to->sb_blocksize = be32_to_cpu(from->sb_blocksize); to->sb_dblocks = be64_to_cpu(from->sb_dblocks); to->sb_rblocks = be64_to_cpu(from->sb_rblocks); to->sb_rextents = be64_to_cpu(from->sb_rextents); memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); to->sb_logstart = be64_to_cpu(from->sb_logstart); to->sb_rootino = be64_to_cpu(from->sb_rootino); to->sb_rbmino = be64_to_cpu(from->sb_rbmino); to->sb_rsumino = be64_to_cpu(from->sb_rsumino); to->sb_rextsize = be32_to_cpu(from->sb_rextsize); to->sb_agblocks = be32_to_cpu(from->sb_agblocks); to->sb_agcount = be32_to_cpu(from->sb_agcount); to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); to->sb_logblocks = be32_to_cpu(from->sb_logblocks); to->sb_versionnum = be16_to_cpu(from->sb_versionnum); to->sb_sectsize = be16_to_cpu(from->sb_sectsize); to->sb_inodesize = be16_to_cpu(from->sb_inodesize); to->sb_inopblock = be16_to_cpu(from->sb_inopblock); memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); to->sb_blocklog = from->sb_blocklog; to->sb_sectlog = from->sb_sectlog; to->sb_inodelog = from->sb_inodelog; to->sb_inopblog = from->sb_inopblog; to->sb_agblklog = from->sb_agblklog; to->sb_rextslog = from->sb_rextslog; to->sb_inprogress = from->sb_inprogress; to->sb_imax_pct = from->sb_imax_pct; to->sb_icount = be64_to_cpu(from->sb_icount); to->sb_ifree = be64_to_cpu(from->sb_ifree); to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); to->sb_frextents = be64_to_cpu(from->sb_frextents); to->sb_uquotino = be64_to_cpu(from->sb_uquotino); to->sb_gquotino = be64_to_cpu(from->sb_gquotino); to->sb_qflags = be16_to_cpu(from->sb_qflags); to->sb_flags = from->sb_flags; to->sb_shared_vn = from->sb_shared_vn; to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); to->sb_unit = be32_to_cpu(from->sb_unit); to->sb_width = be32_to_cpu(from->sb_width); to->sb_dirblklog = from->sb_dirblklog; to->sb_logsectlog = from->sb_logsectlog; to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); to->sb_logsunit = be32_to_cpu(from->sb_logsunit); to->sb_features2 = be32_to_cpu(from->sb_features2); to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2); } /* * Copy in core superblock to ondisk one. * * The fields argument is mask of superblock fields to copy. */ void xfs_sb_to_disk( xfs_dsb_t *to, xfs_sb_t *from, __int64_t fields) { xfs_caddr_t to_ptr = (xfs_caddr_t)to; xfs_caddr_t from_ptr = (xfs_caddr_t)from; xfs_sb_field_t f; int first; int size; ASSERT(fields); if (!fields) return; while (fields) { f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); first = xfs_sb_info[f].offset; size = xfs_sb_info[f + 1].offset - first; ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); if (size == 1 || xfs_sb_info[f].type == 1) { memcpy(to_ptr + first, from_ptr + first, size); } else { switch (size) { case 2: *(__be16 *)(to_ptr + first) = cpu_to_be16(*(__u16 *)(from_ptr + first)); break; case 4: *(__be32 *)(to_ptr + first) = cpu_to_be32(*(__u32 *)(from_ptr + first)); break; case 8: *(__be64 *)(to_ptr + first) = cpu_to_be64(*(__u64 *)(from_ptr + first)); break; default: ASSERT(0); } } fields &= ~(1LL << f); } } /* * xfs_mount_common * * Mount initialization code establishing various mount * fields from the superblock associated with the given * mount structure * * Note: this requires user-space public scope for libxfs_mount */ void xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) { mp->m_agfrotor = mp->m_agirotor = 0; spin_lock_init(&mp->m_agirotor_lock); mp->m_maxagi = mp->m_sb.sb_agcount; mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; mp->m_blockmask = sbp->sb_blocksize - 1; mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; mp->m_blockwmask = mp->m_blockwsize - 1; mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2; mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2; mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; mp->m_bsize = XFS_FSB_TO_BB(mp, 1); mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, sbp->sb_inopblock); mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; } /* * xfs_initialize_perag_data * * Read in each per-ag structure so we can count up the number of * allocated inodes, free inodes and used filesystem blocks as this * information is no longer persistent in the superblock. Once we have * this information, write it into the in-core superblock structure. * * Note: this requires user-space public scope for libxfs_mount */ int xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) { xfs_agnumber_t index; xfs_perag_t *pag; xfs_sb_t *sbp = &mp->m_sb; uint64_t ifree = 0; uint64_t ialloc = 0; uint64_t bfree = 0; uint64_t bfreelst = 0; uint64_t btree = 0; int error; for (index = 0; index < agcount; index++) { /* * read the agf, then the agi. This gets us * all the information we need and populates the * per-ag structures for us. */ error = xfs_alloc_pagf_init(mp, NULL, index, 0); if (error) return error; error = xfs_ialloc_pagi_init(mp, NULL, index); if (error) return error; pag = xfs_perag_get(mp, index); ifree += pag->pagi_freecount; ialloc += pag->pagi_count; bfree += pag->pagf_freeblks; bfreelst += pag->pagf_flcount; btree += pag->pagf_btreeblks; xfs_perag_put(pag); } /* * Overwrite incore superblock counters with just-read data */ spin_lock(&mp->m_sb_lock); sbp->sb_ifree = ifree; sbp->sb_icount = ialloc; sbp->sb_fdblocks = bfree + bfreelst + btree; spin_unlock(&mp->m_sb_lock); /* Fixup the per-cpu counters as well. */ xfs_icsb_reinit_counters(mp); return 0; } /* * xfs_mod_sb() can be used to copy arbitrary changes to the * in-core superblock into the superblock buffer to be logged. * It does not provide the higher level of locking that is * needed to protect the in-core superblock from concurrent * access. */ void xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) { xfs_buf_t *bp; int first; int last; xfs_mount_t *mp; xfs_sb_field_t f; ASSERT(fields); if (!fields) return; mp = tp->t_mountp; bp = xfs_trans_getsb(tp, mp, 0); first = sizeof(xfs_sb_t); last = 0; /* translate/copy */ xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); /* find modified range */ f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); ASSERT((1LL << f) & XFS_SB_MOD_BITS); last = xfs_sb_info[f + 1].offset - 1; f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); ASSERT((1LL << f) & XFS_SB_MOD_BITS); first = xfs_sb_info[f].offset; xfs_trans_log_buf(tp, bp, first, last); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_inode.c0000664000000000000000000017570311650373061015244 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include kmem_zone_t *xfs_ifork_zone; kmem_zone_t *xfs_inode_zone; STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); #ifdef DEBUG /* * Make sure that the extents in the given memory buffer * are valid. */ STATIC void xfs_validate_extents( xfs_ifork_t *ifp, int nrecs, xfs_exntfmt_t fmt) { xfs_bmbt_irec_t irec; xfs_bmbt_rec_host_t rec; int i; for (i = 0; i < nrecs; i++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); rec.l0 = get_unaligned(&ep->l0); rec.l1 = get_unaligned(&ep->l1); xfs_bmbt_get_all(&rec, &irec); if (fmt == XFS_EXTFMT_NOSTATE) ASSERT(irec.br_state == XFS_EXT_NORM); } } #else /* DEBUG */ #define xfs_validate_extents(ifp, nrecs, fmt) #endif /* DEBUG */ /* * Check that none of the inode's in the buffer have a next * unlinked field of 0. */ #if defined(DEBUG) void xfs_inobp_check( xfs_mount_t *mp, xfs_buf_t *bp) { int i; int j; xfs_dinode_t *dip; j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; for (i = 0; i < j; i++) { dip = (xfs_dinode_t *)xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize); if (!dip->di_next_unlinked) { xfs_fs_cmn_err(CE_ALERT, mp, "Detected a bogus zero next_unlinked field in incore inode buffer 0x%p. About to pop an ASSERT.", bp); ASSERT(dip->di_next_unlinked); } } } #endif /* * Find the buffer associated with the given inode map * We do basic validation checks on the buffer once it has been * retrieved from disk. */ int xfs_imap_to_bp( xfs_mount_t *mp, xfs_trans_t *tp, struct xfs_imap *imap, xfs_buf_t **bpp, uint buf_flags, uint iget_flags) { int error; int i; int ni; xfs_buf_t *bp; error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, (int)imap->im_len, buf_flags, &bp); if (error) { if (error != EAGAIN) { cmn_err(CE_WARN, "xfs_imap_to_bp: xfs_trans_read_buf()returned " "an error %d on %s. Returning error.", error, mp->m_fsname); } else { ASSERT(buf_flags & XBF_TRYLOCK); } return error; } /* * Validate the magic number and version of every inode in the buffer * (if DEBUG kernel) or the first inode in the buffer, otherwise. */ #ifdef DEBUG ni = BBTOB(imap->im_len) >> mp->m_sb.sb_inodelog; #else /* usual case */ ni = 1; #endif for (i = 0; i < ni; i++) { int di_ok; xfs_dinode_t *dip; dip = (xfs_dinode_t *)xfs_buf_offset(bp, (i << mp->m_sb.sb_inodelog)); di_ok = be16_to_cpu(dip->di_magic) == XFS_DINODE_MAGIC && XFS_DINODE_GOOD_VERSION(dip->di_version); if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, XFS_RANDOM_ITOBP_INOTOBP))) { if (iget_flags & XFS_IGET_UNTRUSTED) { xfs_trans_brelse(tp, bp); return XFS_ERROR(EINVAL); } XFS_CORRUPTION_ERROR("xfs_imap_to_bp", XFS_ERRLEVEL_HIGH, mp, dip); #ifdef DEBUG cmn_err(CE_PANIC, "Device %s - bad inode magic/vsn " "daddr %lld #%d (magic=%x)", XFS_BUFTARG_NAME(mp->m_ddev_targp), (unsigned long long)imap->im_blkno, i, be16_to_cpu(dip->di_magic)); #endif xfs_trans_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } } xfs_inobp_check(mp, bp); /* * Mark the buffer as an inode buffer now that it looks good */ XFS_BUF_SET_VTYPE(bp, B_FS_INO); *bpp = bp; return 0; } /* * This routine is called to map an inode number within a file * system to the buffer containing the on-disk version of the * inode. It returns a pointer to the buffer containing the * on-disk inode in the bpp parameter, and in the dip parameter * it returns a pointer to the on-disk inode within that buffer. * * If a non-zero error is returned, then the contents of bpp and * dipp are undefined. * * Use xfs_imap() to determine the size and location of the * buffer to read from disk. */ int xfs_inotobp( xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, xfs_dinode_t **dipp, xfs_buf_t **bpp, int *offset, uint imap_flags) { struct xfs_imap imap; xfs_buf_t *bp; int error; imap.im_blkno = 0; error = xfs_imap(mp, tp, ino, &imap, imap_flags); if (error) return error; error = xfs_imap_to_bp(mp, tp, &imap, &bp, XBF_LOCK, imap_flags); if (error) return error; *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); *bpp = bp; *offset = imap.im_boffset; return 0; } /* * This routine is called to map an inode to the buffer containing * the on-disk version of the inode. It returns a pointer to the * buffer containing the on-disk inode in the bpp parameter, and in * the dip parameter it returns a pointer to the on-disk inode within * that buffer. * * If a non-zero error is returned, then the contents of bpp and * dipp are undefined. * * The inode is expected to already been mapped to its buffer and read * in once, thus we can use the mapping information stored in the inode * rather than calling xfs_imap(). This allows us to avoid the overhead * of looking at the inode btree for small block file systems * (see xfs_imap()). */ int xfs_itobp( xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *ip, xfs_dinode_t **dipp, xfs_buf_t **bpp, uint buf_flags) { xfs_buf_t *bp; int error; ASSERT(ip->i_imap.im_blkno != 0); error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, buf_flags, 0); if (error) return error; if (!bp) { ASSERT(buf_flags & XBF_TRYLOCK); ASSERT(tp == NULL); *bpp = NULL; return EAGAIN; } *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); *bpp = bp; return 0; } /* * Move inode type and inode format specific information from the * on-disk inode to the in-core inode. For fifos, devs, and sockets * this means set if_rdev to the proper value. For files, directories, * and symlinks this means to bring in the in-line data or extent * pointers. For a file in B-tree format, only the root is immediately * brought in-core. The rest will be in-lined in if_extents when it * is first referenced (see xfs_iread_extents()). */ int xfs_iformat( xfs_inode_t *ip, xfs_dinode_t *dip) { xfs_attr_shortform_t *atp; int size; int error; xfs_fsize_t di_size; ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); error = 0; if (unlikely(be32_to_cpu(dip->di_nextents) + be16_to_cpu(dip->di_anextents) > be64_to_cpu(dip->di_nblocks))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", (unsigned long long)ip->i_ino, (int)(be32_to_cpu(dip->di_nextents) + be16_to_cpu(dip->di_anextents)), (unsigned long long) be64_to_cpu(dip->di_nblocks)); XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.", (unsigned long long)ip->i_ino, dip->di_forkoff); XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && !ip->i_mount->m_rtdev)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, has realtime flag set.", ip->i_ino); XFS_CORRUPTION_ERROR("xfs_iformat(realtime)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } switch (ip->i_d.di_mode & S_IFMT) { case S_IFIFO: case S_IFCHR: case S_IFBLK: case S_IFSOCK: if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) { XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } ip->i_d.di_size = 0; ip->i_size = 0; ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); break; case S_IFREG: case S_IFLNK: case S_IFDIR: switch (dip->di_format) { case XFS_DINODE_FMT_LOCAL: /* * no local regular files yet */ if (unlikely((be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " "(local format for regular file).", (unsigned long long) ip->i_ino); XFS_CORRUPTION_ERROR("xfs_iformat(4)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } di_size = be64_to_cpu(dip->di_size); if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " "(bad size %Ld for local inode).", (unsigned long long) ip->i_ino, (long long) di_size); XFS_CORRUPTION_ERROR("xfs_iformat(5)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } size = (int)di_size; error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK); break; case XFS_DINODE_FMT_BTREE: error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); break; default: XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } break; default: XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } if (error) { return error; } if (!XFS_DFORK_Q(dip)) return 0; ASSERT(ip->i_afp == NULL); ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); size = be16_to_cpu(atp->hdr.totsize); if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " "(bad attr fork size %Ld).", (unsigned long long) ip->i_ino, (long long) size); XFS_CORRUPTION_ERROR("xfs_iformat(8)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_BTREE: error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); break; default: error = XFS_ERROR(EFSCORRUPTED); break; } if (error) { kmem_zone_free(xfs_ifork_zone, ip->i_afp); ip->i_afp = NULL; xfs_idestroy_fork(ip, XFS_DATA_FORK); } return error; } /* * The file is in-lined in the on-disk inode. * If it fits into if_inline_data, then copy * it there, otherwise allocate a buffer for it * and copy the data there. Either way, set * if_data to point at the data. * If we allocate a buffer for the data, make * sure that its size is a multiple of 4 and * record the real size in i_real_bytes. */ STATIC int xfs_iformat_local( xfs_inode_t *ip, xfs_dinode_t *dip, int whichfork, int size) { xfs_ifork_t *ifp; int real_size; /* * If the size is unreasonable, then something * is wrong and we just bail out rather than crash in * kmem_alloc() or memcpy() below. */ if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu " "(bad size %d for local fork, size = %d).", (unsigned long long) ip->i_ino, size, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } ifp = XFS_IFORK_PTR(ip, whichfork); real_size = 0; if (size == 0) ifp->if_u1.if_data = NULL; else if (size <= sizeof(ifp->if_u2.if_inline_data)) ifp->if_u1.if_data = ifp->if_u2.if_inline_data; else { real_size = roundup(size, 4); ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); } ifp->if_bytes = size; ifp->if_real_bytes = real_size; if (size) memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size); ifp->if_flags &= ~XFS_IFEXTENTS; ifp->if_flags |= XFS_IFINLINE; return 0; } /* * The file consists of a set of extents all * of which fit into the on-disk inode. * If there are few enough extents to fit into * the if_inline_ext, then copy them there. * Otherwise allocate a buffer for them and copy * them into it. Either way, set if_extents * to point at the extents. */ STATIC int xfs_iformat_extents( xfs_inode_t *ip, xfs_dinode_t *dip, int whichfork) { xfs_bmbt_rec_t *dp; xfs_ifork_t *ifp; int nex; int size; int i; ifp = XFS_IFORK_PTR(ip, whichfork); nex = XFS_DFORK_NEXTENTS(dip, whichfork); size = nex * (uint)sizeof(xfs_bmbt_rec_t); /* * If the number of extents is unreasonable, then something * is wrong and we just bail out rather than crash in * kmem_alloc() or memcpy() below. */ if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu ((a)extents = %d).", (unsigned long long) ip->i_ino, nex); XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } ifp->if_real_bytes = 0; if (nex == 0) ifp->if_u1.if_extents = NULL; else if (nex <= XFS_INLINE_EXTS) ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; else xfs_iext_add(ifp, 0, nex); ifp->if_bytes = size; if (size) { dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); for (i = 0; i < nex; i++, dp++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); ep->l0 = get_unaligned_be64(&dp->l0); ep->l1 = get_unaligned_be64(&dp->l1); } XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); if (whichfork != XFS_DATA_FORK || XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) if (unlikely(xfs_check_nostate_extents( ifp, 0, nex))) { XFS_ERROR_REPORT("xfs_iformat_extents(2)", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } } ifp->if_flags |= XFS_IFEXTENTS; return 0; } /* * The file has too many extents to fit into * the inode, so they are in B-tree format. * Allocate a buffer for the root of the B-tree * and copy the root into it. The i_extents * field will remain NULL until all of the * extents are read in (when they are needed). */ STATIC int xfs_iformat_btree( xfs_inode_t *ip, xfs_dinode_t *dip, int whichfork) { xfs_bmdr_block_t *dfp; xfs_ifork_t *ifp; /* REFERENCED */ int nrecs; int size; ifp = XFS_IFORK_PTR(ip, whichfork); dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); size = XFS_BMAP_BROOT_SPACE(dfp); nrecs = be16_to_cpu(dfp->bb_numrecs); /* * blow out if -- fork has less extents than can fit in * fork (fork shouldn't be a btree format), root btree * block has more records than can fit into the fork, * or the number of extents is greater than the number of * blocks. */ if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max || XFS_BMDR_SPACE_CALC(nrecs) > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt inode %Lu (btree).", (unsigned long long) ip->i_ino); XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } ifp->if_broot_bytes = size; ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS); ASSERT(ifp->if_broot != NULL); /* * Copy and convert from the on-disk structure * to the in-memory structure. */ xfs_bmdr_to_bmbt(ip->i_mount, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), ifp->if_broot, size); ifp->if_flags &= ~XFS_IFEXTENTS; ifp->if_flags |= XFS_IFBROOT; return 0; } void xfs_dinode_from_disk( xfs_icdinode_t *to, xfs_dinode_t *from) { to->di_magic = be16_to_cpu(from->di_magic); to->di_mode = be16_to_cpu(from->di_mode); to->di_version = from ->di_version; to->di_format = from->di_format; to->di_onlink = be16_to_cpu(from->di_onlink); to->di_uid = be32_to_cpu(from->di_uid); to->di_gid = be32_to_cpu(from->di_gid); to->di_nlink = be32_to_cpu(from->di_nlink); to->di_projid_lo = be16_to_cpu(from->di_projid_lo); to->di_projid_hi = be16_to_cpu(from->di_projid_hi); memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); to->di_flushiter = be16_to_cpu(from->di_flushiter); to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); to->di_size = be64_to_cpu(from->di_size); to->di_nblocks = be64_to_cpu(from->di_nblocks); to->di_extsize = be32_to_cpu(from->di_extsize); to->di_nextents = be32_to_cpu(from->di_nextents); to->di_anextents = be16_to_cpu(from->di_anextents); to->di_forkoff = from->di_forkoff; to->di_aformat = from->di_aformat; to->di_dmevmask = be32_to_cpu(from->di_dmevmask); to->di_dmstate = be16_to_cpu(from->di_dmstate); to->di_flags = be16_to_cpu(from->di_flags); to->di_gen = be32_to_cpu(from->di_gen); } void xfs_dinode_to_disk( xfs_dinode_t *to, xfs_icdinode_t *from) { to->di_magic = cpu_to_be16(from->di_magic); to->di_mode = cpu_to_be16(from->di_mode); to->di_version = from ->di_version; to->di_format = from->di_format; to->di_onlink = cpu_to_be16(from->di_onlink); to->di_uid = cpu_to_be32(from->di_uid); to->di_gid = cpu_to_be32(from->di_gid); to->di_nlink = cpu_to_be32(from->di_nlink); to->di_projid_lo = cpu_to_be16(from->di_projid_lo); to->di_projid_hi = cpu_to_be16(from->di_projid_hi); memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); to->di_flushiter = cpu_to_be16(from->di_flushiter); to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); to->di_extsize = cpu_to_be32(from->di_extsize); to->di_nextents = cpu_to_be32(from->di_nextents); to->di_anextents = cpu_to_be16(from->di_anextents); to->di_forkoff = from->di_forkoff; to->di_aformat = from->di_aformat; to->di_dmevmask = cpu_to_be32(from->di_dmevmask); to->di_dmstate = cpu_to_be16(from->di_dmstate); to->di_flags = cpu_to_be16(from->di_flags); to->di_gen = cpu_to_be32(from->di_gen); } /* * Read in extents from a btree-format inode. * Allocate and fill in if_extents. Real work is done in xfs_bmap.c. */ int xfs_iread_extents( xfs_trans_t *tp, xfs_inode_t *ip, int whichfork) { int error; xfs_ifork_t *ifp; xfs_extnum_t nextents; if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } nextents = XFS_IFORK_NEXTENTS(ip, whichfork); ifp = XFS_IFORK_PTR(ip, whichfork); /* * We know that the size is valid (it's checked in iformat_btree) */ ifp->if_lastex = NULLEXTNUM; ifp->if_bytes = ifp->if_real_bytes = 0; ifp->if_flags |= XFS_IFEXTENTS; xfs_iext_add(ifp, 0, nextents); error = xfs_bmap_read_extents(tp, ip, whichfork); if (error) { xfs_iext_destroy(ifp); ifp->if_flags &= ~XFS_IFEXTENTS; return error; } xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); return 0; } /* * Reallocate the space for if_broot based on the number of records * being added or deleted as indicated in rec_diff. Move the records * and pointers in if_broot to fit the new size. When shrinking this * will eliminate holes between the records and pointers created by * the caller. When growing this will create holes to be filled in * by the caller. * * The caller must not request to add more records than would fit in * the on-disk inode root. If the if_broot is currently NULL, then * if we adding records one will be allocated. The caller must also * not request that the number of records go below zero, although * it can go to zero. * * ip -- the inode whose if_broot area is changing * ext_diff -- the change in the number of records, positive or negative, * requested for the if_broot array. */ void xfs_iroot_realloc( xfs_inode_t *ip, int rec_diff, int whichfork) { struct xfs_mount *mp = ip->i_mount; int cur_max; xfs_ifork_t *ifp; struct xfs_btree_block *new_broot; int new_max; size_t new_size; char *np; char *op; /* * Handle the degenerate case quietly. */ if (rec_diff == 0) { return; } ifp = XFS_IFORK_PTR(ip, whichfork); if (rec_diff > 0) { /* * If there wasn't any memory allocated before, just * allocate it now and get out. */ if (ifp->if_broot_bytes == 0) { new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff); ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); ifp->if_broot_bytes = (int)new_size; return; } /* * If there is already an existing if_broot, then we need * to realloc() it and shift the pointers to their new * location. The records don't change location because * they are kept butted up against the btree block header. */ cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); new_max = cur_max + rec_diff; new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */ KM_SLEEP | KM_NOFS); op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, ifp->if_broot_bytes); np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, (int)new_size); ifp->if_broot_bytes = (int)new_size; ASSERT(ifp->if_broot_bytes <= XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); return; } /* * rec_diff is less than 0. In this case, we are shrinking the * if_broot buffer. It must already exist. If we go to zero * records, just get rid of the root and clear the status bit. */ ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); if (new_max > 0) new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); else new_size = 0; if (new_size > 0) { new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); /* * First copy over the btree block header. */ memcpy(new_broot, ifp->if_broot, XFS_BTREE_LBLOCK_LEN); } else { new_broot = NULL; ifp->if_flags &= ~XFS_IFBROOT; } /* * Only copy the records and pointers if there are any. */ if (new_max > 0) { /* * First copy the records. */ op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); /* * Then copy the pointers. */ op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, ifp->if_broot_bytes); np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, (int)new_size); memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); } kmem_free(ifp->if_broot); ifp->if_broot = new_broot; ifp->if_broot_bytes = (int)new_size; ASSERT(ifp->if_broot_bytes <= XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); return; } /* * This is called when the amount of space needed for if_data * is increased or decreased. The change in size is indicated by * the number of bytes that need to be added or deleted in the * byte_diff parameter. * * If the amount of space needed has decreased below the size of the * inline buffer, then switch to using the inline buffer. Otherwise, * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer * to what is needed. * * ip -- the inode whose if_data area is changing * byte_diff -- the change in the number of bytes, positive or negative, * requested for the if_data array. */ void xfs_idata_realloc( xfs_inode_t *ip, int byte_diff, int whichfork) { xfs_ifork_t *ifp; int new_size; int real_size; if (byte_diff == 0) { return; } ifp = XFS_IFORK_PTR(ip, whichfork); new_size = (int)ifp->if_bytes + byte_diff; ASSERT(new_size >= 0); if (new_size == 0) { if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { kmem_free(ifp->if_u1.if_data); } ifp->if_u1.if_data = NULL; real_size = 0; } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) { /* * If the valid extents/data can fit in if_inline_ext/data, * copy them from the malloc'd vector and free it. */ if (ifp->if_u1.if_data == NULL) { ifp->if_u1.if_data = ifp->if_u2.if_inline_data; } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { ASSERT(ifp->if_real_bytes != 0); memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, new_size); kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = ifp->if_u2.if_inline_data; } real_size = 0; } else { /* * Stuck with malloc/realloc. * For inline data, the underlying buffer must be * a multiple of 4 bytes in size so that it can be * logged and stay on word boundaries. We enforce * that here. */ real_size = roundup(new_size, 4); if (ifp->if_u1.if_data == NULL) { ASSERT(ifp->if_real_bytes == 0); ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { /* * Only do the realloc if the underlying size * is really changing. */ if (ifp->if_real_bytes != real_size) { ifp->if_u1.if_data = kmem_realloc(ifp->if_u1.if_data, real_size, ifp->if_real_bytes, KM_SLEEP | KM_NOFS); } } else { ASSERT(ifp->if_real_bytes == 0); ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data, ifp->if_bytes); } } ifp->if_real_bytes = real_size; ifp->if_bytes = new_size; ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); } void xfs_idestroy_fork( xfs_inode_t *ip, int whichfork) { xfs_ifork_t *ifp; ifp = XFS_IFORK_PTR(ip, whichfork); if (ifp->if_broot != NULL) { kmem_free(ifp->if_broot); ifp->if_broot = NULL; } /* * If the format is local, then we can't have an extents * array so just look for an inline data array. If we're * not local then we may or may not have an extents list, * so check and free it up if we do. */ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && (ifp->if_u1.if_data != NULL)) { ASSERT(ifp->if_real_bytes != 0); kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = NULL; ifp->if_real_bytes = 0; } } else if ((ifp->if_flags & XFS_IFEXTENTS) && ((ifp->if_flags & XFS_IFEXTIREC) || ((ifp->if_u1.if_extents != NULL) && (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) { ASSERT(ifp->if_real_bytes != 0); xfs_iext_destroy(ifp); } ASSERT(ifp->if_u1.if_extents == NULL || ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); ASSERT(ifp->if_real_bytes == 0); if (whichfork == XFS_ATTR_FORK) { kmem_zone_free(xfs_ifork_zone, ip->i_afp); ip->i_afp = NULL; } } /* * xfs_iextents_copy() * * This is called to copy the REAL extents (as opposed to the delayed * allocation extents) from the inode into the given buffer. It * returns the number of bytes copied into the buffer. * * If there are no delayed allocation extents, then we can just * memcpy() the extents into the buffer. Otherwise, we need to * examine each extent in turn and skip those which are delayed. */ int xfs_iextents_copy( xfs_inode_t *ip, xfs_bmbt_rec_t *dp, int whichfork) { int copied; int i; xfs_ifork_t *ifp; int nrecs; xfs_fsblock_t start_block; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(ifp->if_bytes > 0); nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); ASSERT(nrecs > 0); /* * There are some delayed allocation extents in the * inode, so copy the extents one at a time and skip * the delayed ones. There must be at least one * non-delayed extent. */ copied = 0; for (i = 0; i < nrecs; i++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); start_block = xfs_bmbt_get_startblock(ep); if (isnullstartblock(start_block)) { /* * It's a delayed allocation extent, so skip it. */ continue; } /* Translate to on disk format */ put_unaligned_be64(ep->l0, &dp->l0); put_unaligned_be64(ep->l1, &dp->l1); dp++; copied++; } ASSERT(copied != 0); xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); return (copied * (uint)sizeof(xfs_bmbt_rec_t)); } /* * Each of the following cases stores data into the same region * of the on-disk inode, so only one of them can be valid at * any given time. While it is possible to have conflicting formats * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is * in EXTENTS format, this can only happen when the fork has * changed formats after being modified but before being flushed. * In these cases, the format always takes precedence, because the * format indicates the current state of the fork. */ /*ARGSUSED*/ void xfs_iflush_fork( xfs_inode_t *ip, xfs_dinode_t *dip, xfs_inode_log_item_t *iip, int whichfork, xfs_buf_t *bp) { char *cp; xfs_ifork_t *ifp; xfs_mount_t *mp; #ifdef XFS_TRANS_DEBUG int first; #endif static const short brootflag[2] = { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; static const short dataflag[2] = { XFS_ILOG_DDATA, XFS_ILOG_ADATA }; static const short extflag[2] = { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; if (!iip) return; ifp = XFS_IFORK_PTR(ip, whichfork); /* * This can happen if we gave up in iformat in an error path, * for the attribute fork. */ if (!ifp) { ASSERT(whichfork == XFS_ATTR_FORK); return; } cp = XFS_DFORK_PTR(dip, whichfork); mp = ip->i_mount; switch (XFS_IFORK_FORMAT(ip, whichfork)) { case XFS_DINODE_FMT_LOCAL: if ((iip->ili_format.ilf_fields & dataflag[whichfork]) && (ifp->if_bytes > 0)) { ASSERT(ifp->if_u1.if_data != NULL); ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); } break; case XFS_DINODE_FMT_EXTENTS: ASSERT((ifp->if_flags & XFS_IFEXTENTS) || !(iip->ili_format.ilf_fields & extflag[whichfork])); ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) || (ifp->if_bytes == 0)); ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) || (ifp->if_bytes > 0)); if ((iip->ili_format.ilf_fields & extflag[whichfork]) && (ifp->if_bytes > 0)) { ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, whichfork); } break; case XFS_DINODE_FMT_BTREE: if ((iip->ili_format.ilf_fields & brootflag[whichfork]) && (ifp->if_broot_bytes > 0)) { ASSERT(ifp->if_broot != NULL); ASSERT(ifp->if_broot_bytes <= (XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ)); xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, (xfs_bmdr_block_t *)cp, XFS_DFORK_SIZE(dip, mp, whichfork)); } break; case XFS_DINODE_FMT_DEV: if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { ASSERT(whichfork == XFS_DATA_FORK); xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); } break; case XFS_DINODE_FMT_UUID: if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { ASSERT(whichfork == XFS_DATA_FORK); memcpy(XFS_DFORK_DPTR(dip), &ip->i_df.if_u2.if_uuid, sizeof(uuid_t)); } break; default: ASSERT(0); break; } } /* * Return a pointer to the extent record at file index idx. */ xfs_bmbt_rec_host_t * xfs_iext_get_ext( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx) /* index of target extent */ { ASSERT(idx >= 0); if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { return ifp->if_u1.if_ext_irec->er_extbuf; } else if (ifp->if_flags & XFS_IFEXTIREC) { xfs_ext_irec_t *erp; /* irec pointer */ int erp_idx = 0; /* irec index */ xfs_extnum_t page_idx = idx; /* ext index in target list */ erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); return &erp->er_extbuf[page_idx]; } else if (ifp->if_bytes) { return &ifp->if_u1.if_extents[idx]; } else { return NULL; } } /* * Insert new item(s) into the extent records for incore inode * fork 'ifp'. 'count' new items are inserted at index 'idx'. */ void xfs_iext_insert( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* starting index of new items */ xfs_extnum_t count, /* number of inserted items */ xfs_bmbt_irec_t *new, /* items to insert */ int state) /* type of extent conversion */ { xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; xfs_extnum_t i; /* extent record index */ trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); ASSERT(ifp->if_flags & XFS_IFEXTENTS); xfs_iext_add(ifp, idx, count); for (i = idx; i < idx + count; i++, new++) xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); } /* * This is called when the amount of space required for incore file * extents needs to be increased. The ext_diff parameter stores the * number of new extents being added and the idx parameter contains * the extent index where the new extents will be added. If the new * extents are being appended, then we just need to (re)allocate and * initialize the space. Otherwise, if the new extents are being * inserted into the middle of the existing entries, a bit more work * is required to make room for the new extents to be inserted. The * caller is responsible for filling in the new extent entries upon * return. */ void xfs_iext_add( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx, /* index to begin adding exts */ int ext_diff) /* number of extents to add */ { int byte_diff; /* new bytes being added */ int new_size; /* size of extents after adding */ xfs_extnum_t nextents; /* number of extents in file */ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ASSERT((idx >= 0) && (idx <= nextents)); byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t); new_size = ifp->if_bytes + byte_diff; /* * If the new number of extents (nextents + ext_diff) * fits inside the inode, then continue to use the inline * extent buffer. */ if (nextents + ext_diff <= XFS_INLINE_EXTS) { if (idx < nextents) { memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff], &ifp->if_u2.if_inline_ext[idx], (nextents - idx) * sizeof(xfs_bmbt_rec_t)); memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff); } ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; ifp->if_real_bytes = 0; ifp->if_lastex = nextents + ext_diff; } /* * Otherwise use a linear (direct) extent list. * If the extents are currently inside the inode, * xfs_iext_realloc_direct will switch us from * inline to direct extent allocation mode. */ else if (nextents + ext_diff <= XFS_LINEAR_EXTS) { xfs_iext_realloc_direct(ifp, new_size); if (idx < nextents) { memmove(&ifp->if_u1.if_extents[idx + ext_diff], &ifp->if_u1.if_extents[idx], (nextents - idx) * sizeof(xfs_bmbt_rec_t)); memset(&ifp->if_u1.if_extents[idx], 0, byte_diff); } } /* Indirection array */ else { xfs_ext_irec_t *erp; int erp_idx = 0; int page_idx = idx; ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS); if (ifp->if_flags & XFS_IFEXTIREC) { erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1); } else { xfs_iext_irec_init(ifp); ASSERT(ifp->if_flags & XFS_IFEXTIREC); erp = ifp->if_u1.if_ext_irec; } /* Extents fit in target extent page */ if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) { if (page_idx < erp->er_extcount) { memmove(&erp->er_extbuf[page_idx + ext_diff], &erp->er_extbuf[page_idx], (erp->er_extcount - page_idx) * sizeof(xfs_bmbt_rec_t)); memset(&erp->er_extbuf[page_idx], 0, byte_diff); } erp->er_extcount += ext_diff; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); } /* Insert a new extent page */ else if (erp) { xfs_iext_add_indirect_multi(ifp, erp_idx, page_idx, ext_diff); } /* * If extent(s) are being appended to the last page in * the indirection array and the new extent(s) don't fit * in the page, then erp is NULL and erp_idx is set to * the next index needed in the indirection array. */ else { int count = ext_diff; while (count) { erp = xfs_iext_irec_new(ifp, erp_idx); erp->er_extcount = count; count -= MIN(count, (int)XFS_LINEAR_EXTS); if (count) { erp_idx++; } } } } ifp->if_bytes = new_size; } /* * This is called when incore extents are being added to the indirection * array and the new extents do not fit in the target extent list. The * erp_idx parameter contains the irec index for the target extent list * in the indirection array, and the idx parameter contains the extent * index within the list. The number of extents being added is stored * in the count parameter. * * |-------| |-------| * | | | | idx - number of extents before idx * | idx | | count | * | | | | count - number of extents being inserted at idx * |-------| |-------| * | count | | nex2 | nex2 - number of extents after idx + count * |-------| |-------| */ void xfs_iext_add_indirect_multi( xfs_ifork_t *ifp, /* inode fork pointer */ int erp_idx, /* target extent irec index */ xfs_extnum_t idx, /* index within target list */ int count) /* new extents being added */ { int byte_diff; /* new bytes being added */ xfs_ext_irec_t *erp; /* pointer to irec entry */ xfs_extnum_t ext_diff; /* number of extents to add */ xfs_extnum_t ext_cnt; /* new extents still needed */ xfs_extnum_t nex2; /* extents after idx + count */ xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */ int nlists; /* number of irec's (lists) */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); erp = &ifp->if_u1.if_ext_irec[erp_idx]; nex2 = erp->er_extcount - idx; nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; /* * Save second part of target extent list * (all extents past */ if (nex2) { byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); erp->er_extcount -= nex2; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); memset(&erp->er_extbuf[idx], 0, byte_diff); } /* * Add the new extents to the end of the target * list, then allocate new irec record(s) and * extent buffer(s) as needed to store the rest * of the new extents. */ ext_cnt = count; ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount); if (ext_diff) { erp->er_extcount += ext_diff; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); ext_cnt -= ext_diff; } while (ext_cnt) { erp_idx++; erp = xfs_iext_irec_new(ifp, erp_idx); ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS); erp->er_extcount = ext_diff; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); ext_cnt -= ext_diff; } /* Add nex2 extents back to indirection array */ if (nex2) { xfs_extnum_t ext_avail; int i; byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; i = 0; /* * If nex2 extents fit in the current page, append * nex2_ep after the new extents. */ if (nex2 <= ext_avail) { i = erp->er_extcount; } /* * Otherwise, check if space is available in the * next page. */ else if ((erp_idx < nlists - 1) && (nex2 <= (ext_avail = XFS_LINEAR_EXTS - ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) { erp_idx++; erp++; /* Create a hole for nex2 extents */ memmove(&erp->er_extbuf[nex2], erp->er_extbuf, erp->er_extcount * sizeof(xfs_bmbt_rec_t)); } /* * Final choice, create a new extent page for * nex2 extents. */ else { erp_idx++; erp = xfs_iext_irec_new(ifp, erp_idx); } memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); kmem_free(nex2_ep); erp->er_extcount += nex2; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); } } /* * This is called when the amount of space required for incore file * extents needs to be decreased. The ext_diff parameter stores the * number of extents to be removed and the idx parameter contains * the extent index where the extents will be removed from. * * If the amount of space needed has decreased below the linear * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous * extent array. Otherwise, use kmem_realloc() to adjust the * size to what is needed. */ void xfs_iext_remove( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* index to begin removing exts */ int ext_diff, /* number of extents to remove */ int state) /* type of extent conversion */ { xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; xfs_extnum_t nextents; /* number of extents in file */ int new_size; /* size of extents after removal */ trace_xfs_iext_remove(ip, idx, state, _RET_IP_); ASSERT(ext_diff > 0); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); if (new_size == 0) { xfs_iext_destroy(ifp); } else if (ifp->if_flags & XFS_IFEXTIREC) { xfs_iext_remove_indirect(ifp, idx, ext_diff); } else if (ifp->if_real_bytes) { xfs_iext_remove_direct(ifp, idx, ext_diff); } else { xfs_iext_remove_inline(ifp, idx, ext_diff); } ifp->if_bytes = new_size; } /* * This removes ext_diff extents from the inline buffer, beginning * at extent index idx. */ void xfs_iext_remove_inline( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx, /* index to begin removing exts */ int ext_diff) /* number of extents to remove */ { int nextents; /* number of extents in file */ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); ASSERT(idx < XFS_INLINE_EXTS); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ASSERT(((nextents - ext_diff) > 0) && (nextents - ext_diff) < XFS_INLINE_EXTS); if (idx + ext_diff < nextents) { memmove(&ifp->if_u2.if_inline_ext[idx], &ifp->if_u2.if_inline_ext[idx + ext_diff], (nextents - (idx + ext_diff)) * sizeof(xfs_bmbt_rec_t)); memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff], 0, ext_diff * sizeof(xfs_bmbt_rec_t)); } else { memset(&ifp->if_u2.if_inline_ext[idx], 0, ext_diff * sizeof(xfs_bmbt_rec_t)); } } /* * This removes ext_diff extents from a linear (direct) extent list, * beginning at extent index idx. If the extents are being removed * from the end of the list (ie. truncate) then we just need to re- * allocate the list to remove the extra space. Otherwise, if the * extents are being removed from the middle of the existing extent * entries, then we first need to move the extent records beginning * at idx + ext_diff up in the list to overwrite the records being * removed, then remove the extra space via kmem_realloc. */ void xfs_iext_remove_direct( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx, /* index to begin removing exts */ int ext_diff) /* number of extents to remove */ { xfs_extnum_t nextents; /* number of extents in file */ int new_size; /* size of extents after removal */ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); new_size = ifp->if_bytes - (ext_diff * sizeof(xfs_bmbt_rec_t)); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (new_size == 0) { xfs_iext_destroy(ifp); return; } /* Move extents up in the list (if needed) */ if (idx + ext_diff < nextents) { memmove(&ifp->if_u1.if_extents[idx], &ifp->if_u1.if_extents[idx + ext_diff], (nextents - (idx + ext_diff)) * sizeof(xfs_bmbt_rec_t)); } memset(&ifp->if_u1.if_extents[nextents - ext_diff], 0, ext_diff * sizeof(xfs_bmbt_rec_t)); /* * Reallocate the direct extent list. If the extents * will fit inside the inode then xfs_iext_realloc_direct * will switch from direct to inline extent allocation * mode for us. */ xfs_iext_realloc_direct(ifp, new_size); ifp->if_bytes = new_size; } /* * This is called when incore extents are being removed from the * indirection array and the extents being removed span multiple extent * buffers. The idx parameter contains the file extent index where we * want to begin removing extents, and the count parameter contains * how many extents need to be removed. * * |-------| |-------| * | nex1 | | | nex1 - number of extents before idx * |-------| | count | * | | | | count - number of extents being removed at idx * | count | |-------| * | | | nex2 | nex2 - number of extents after idx + count * |-------| |-------| */ void xfs_iext_remove_indirect( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx, /* index to begin removing extents */ int count) /* number of extents to remove */ { xfs_ext_irec_t *erp; /* indirection array pointer */ int erp_idx = 0; /* indirection array index */ xfs_extnum_t ext_cnt; /* extents left to remove */ xfs_extnum_t ext_diff; /* extents to remove in current list */ xfs_extnum_t nex1; /* number of extents before idx */ xfs_extnum_t nex2; /* extents after idx + count */ int page_idx = idx; /* index in target extent list */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); ASSERT(erp != NULL); nex1 = page_idx; ext_cnt = count; while (ext_cnt) { nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0); ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1)); /* * Check for deletion of entire list; * xfs_iext_irec_remove() updates extent offsets. */ if (ext_diff == erp->er_extcount) { xfs_iext_irec_remove(ifp, erp_idx); ext_cnt -= ext_diff; nex1 = 0; if (ext_cnt) { ASSERT(erp_idx < ifp->if_real_bytes / XFS_IEXT_BUFSZ); erp = &ifp->if_u1.if_ext_irec[erp_idx]; nex1 = 0; continue; } else { break; } } /* Move extents up (if needed) */ if (nex2) { memmove(&erp->er_extbuf[nex1], &erp->er_extbuf[nex1 + ext_diff], nex2 * sizeof(xfs_bmbt_rec_t)); } /* Zero out rest of page */ memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ - ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t)))); /* Update remaining counters */ erp->er_extcount -= ext_diff; xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff); ext_cnt -= ext_diff; nex1 = 0; erp_idx++; erp++; } ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t); xfs_iext_irec_compact(ifp); } /* * Create, destroy, or resize a linear (direct) block of extents. */ void xfs_iext_realloc_direct( xfs_ifork_t *ifp, /* inode fork pointer */ int new_size) /* new size of extents */ { int rnew_size; /* real new size of extents */ rnew_size = new_size; ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) || ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) && (new_size != ifp->if_real_bytes))); /* Free extent records */ if (new_size == 0) { xfs_iext_destroy(ifp); } /* Resize direct extent list and zero any new bytes */ else if (ifp->if_real_bytes) { /* Check if extents will fit inside the inode */ if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) { xfs_iext_direct_to_inline(ifp, new_size / (uint)sizeof(xfs_bmbt_rec_t)); ifp->if_bytes = new_size; return; } if (!is_power_of_2(new_size)){ rnew_size = roundup_pow_of_two(new_size); } if (rnew_size != ifp->if_real_bytes) { ifp->if_u1.if_extents = kmem_realloc(ifp->if_u1.if_extents, rnew_size, ifp->if_real_bytes, KM_NOFS); } if (rnew_size > ifp->if_real_bytes) { memset(&ifp->if_u1.if_extents[ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)], 0, rnew_size - ifp->if_real_bytes); } } /* * Switch from the inline extent buffer to a direct * extent list. Be sure to include the inline extent * bytes in new_size. */ else { new_size += ifp->if_bytes; if (!is_power_of_2(new_size)) { rnew_size = roundup_pow_of_two(new_size); } xfs_iext_inline_to_direct(ifp, rnew_size); } ifp->if_real_bytes = rnew_size; ifp->if_bytes = new_size; } /* * Switch from linear (direct) extent records to inline buffer. */ void xfs_iext_direct_to_inline( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t nextents) /* number of extents in file */ { ASSERT(ifp->if_flags & XFS_IFEXTENTS); ASSERT(nextents <= XFS_INLINE_EXTS); /* * The inline buffer was zeroed when we switched * from inline to direct extent allocation mode, * so we don't need to clear it here. */ memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, nextents * sizeof(xfs_bmbt_rec_t)); kmem_free(ifp->if_u1.if_extents); ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; ifp->if_real_bytes = 0; } /* * Switch from inline buffer to linear (direct) extent records. * new_size should already be rounded up to the next power of 2 * by the caller (when appropriate), so use new_size as it is. * However, since new_size may be rounded up, we can't update * if_bytes here. It is the caller's responsibility to update * if_bytes upon return. */ void xfs_iext_inline_to_direct( xfs_ifork_t *ifp, /* inode fork pointer */ int new_size) /* number of extents in file */ { ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); memset(ifp->if_u1.if_extents, 0, new_size); if (ifp->if_bytes) { memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, ifp->if_bytes); memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)); } ifp->if_real_bytes = new_size; } /* * Resize an extent indirection array to new_size bytes. */ STATIC void xfs_iext_realloc_indirect( xfs_ifork_t *ifp, /* inode fork pointer */ int new_size) /* new indirection array size */ { int nlists; /* number of irec's (ex lists) */ int size; /* current indirection array size */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; size = nlists * sizeof(xfs_ext_irec_t); ASSERT(ifp->if_real_bytes); ASSERT((new_size >= 0) && (new_size != size)); if (new_size == 0) { xfs_iext_destroy(ifp); } else { ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) kmem_realloc(ifp->if_u1.if_ext_irec, new_size, size, KM_NOFS); } } /* * Switch from indirection array to linear (direct) extent allocations. */ STATIC void xfs_iext_indirect_to_direct( xfs_ifork_t *ifp) /* inode fork pointer */ { xfs_bmbt_rec_host_t *ep; /* extent record pointer */ xfs_extnum_t nextents; /* number of extents in file */ int size; /* size of file extents */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ASSERT(nextents <= XFS_LINEAR_EXTS); size = nextents * sizeof(xfs_bmbt_rec_t); xfs_iext_irec_compact_pages(ifp); ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); ep = ifp->if_u1.if_ext_irec->er_extbuf; kmem_free(ifp->if_u1.if_ext_irec); ifp->if_flags &= ~XFS_IFEXTIREC; ifp->if_u1.if_extents = ep; ifp->if_bytes = size; if (nextents < XFS_LINEAR_EXTS) { xfs_iext_realloc_direct(ifp, size); } } /* * Free incore file extents. */ void xfs_iext_destroy( xfs_ifork_t *ifp) /* inode fork pointer */ { if (ifp->if_flags & XFS_IFEXTIREC) { int erp_idx; int nlists; nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) { xfs_iext_irec_remove(ifp, erp_idx); } ifp->if_flags &= ~XFS_IFEXTIREC; } else if (ifp->if_real_bytes) { kmem_free(ifp->if_u1.if_extents); } else if (ifp->if_bytes) { memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)); } ifp->if_u1.if_extents = NULL; ifp->if_real_bytes = 0; ifp->if_bytes = 0; } /* * Return a pointer to the extent record for file system block bno. */ xfs_bmbt_rec_host_t * /* pointer to found extent record */ xfs_iext_bno_to_ext( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number to search for */ xfs_extnum_t *idxp) /* index of target extent */ { xfs_bmbt_rec_host_t *base; /* pointer to first extent */ xfs_filblks_t blockcount = 0; /* number of blocks in extent */ xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ int high; /* upper boundary in search */ xfs_extnum_t idx = 0; /* index of target extent */ int low; /* lower boundary in search */ xfs_extnum_t nextents; /* number of file extents */ xfs_fileoff_t startoff = 0; /* start offset of extent */ nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (nextents == 0) { *idxp = 0; return NULL; } low = 0; if (ifp->if_flags & XFS_IFEXTIREC) { /* Find target extent list */ int erp_idx = 0; erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); base = erp->er_extbuf; high = erp->er_extcount - 1; } else { base = ifp->if_u1.if_extents; high = nextents - 1; } /* Binary search extent records */ while (low <= high) { idx = (low + high) >> 1; ep = base + idx; startoff = xfs_bmbt_get_startoff(ep); blockcount = xfs_bmbt_get_blockcount(ep); if (bno < startoff) { high = idx - 1; } else if (bno >= startoff + blockcount) { low = idx + 1; } else { /* Convert back to file-based extent index */ if (ifp->if_flags & XFS_IFEXTIREC) { idx += erp->er_extoff; } *idxp = idx; return ep; } } /* Convert back to file-based extent index */ if (ifp->if_flags & XFS_IFEXTIREC) { idx += erp->er_extoff; } if (bno >= startoff + blockcount) { if (++idx == nextents) { ep = NULL; } else { ep = xfs_iext_get_ext(ifp, idx); } } *idxp = idx; return ep; } /* * Return a pointer to the indirection array entry containing the * extent record for filesystem block bno. Store the index of the * target irec in *erp_idxp. */ xfs_ext_irec_t * /* pointer to found extent record */ xfs_iext_bno_to_irec( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number to search for */ int *erp_idxp) /* irec index of target ext list */ { xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ xfs_ext_irec_t *erp_next; /* next indirection array entry */ int erp_idx; /* indirection array index */ int nlists; /* number of extent irec's (lists) */ int high; /* binary search upper limit */ int low; /* binary search lower limit */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; erp_idx = 0; low = 0; high = nlists - 1; while (low <= high) { erp_idx = (low + high) >> 1; erp = &ifp->if_u1.if_ext_irec[erp_idx]; erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL; if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) { high = erp_idx - 1; } else if (erp_next && bno >= xfs_bmbt_get_startoff(erp_next->er_extbuf)) { low = erp_idx + 1; } else { break; } } *erp_idxp = erp_idx; return erp; } /* * Return a pointer to the indirection array entry containing the * extent record at file extent index *idxp. Store the index of the * target irec in *erp_idxp and store the page index of the target * extent record in *idxp. */ xfs_ext_irec_t * xfs_iext_idx_to_irec( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t *idxp, /* extent index (file -> page) */ int *erp_idxp, /* pointer to target irec */ int realloc) /* new bytes were just added */ { xfs_ext_irec_t *prev; /* pointer to previous irec */ xfs_ext_irec_t *erp = NULL; /* pointer to current irec */ int erp_idx; /* indirection array index */ int nlists; /* number of irec's (ex lists) */ int high; /* binary search upper limit */ int low; /* binary search lower limit */ xfs_extnum_t page_idx = *idxp; /* extent index in target list */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); ASSERT(page_idx >= 0 && page_idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; erp_idx = 0; low = 0; high = nlists - 1; /* Binary search extent irec's */ while (low <= high) { erp_idx = (low + high) >> 1; erp = &ifp->if_u1.if_ext_irec[erp_idx]; prev = erp_idx > 0 ? erp - 1 : NULL; if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff && realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) { high = erp_idx - 1; } else if (page_idx > erp->er_extoff + erp->er_extcount || (page_idx == erp->er_extoff + erp->er_extcount && !realloc)) { low = erp_idx + 1; } else if (page_idx == erp->er_extoff + erp->er_extcount && erp->er_extcount == XFS_LINEAR_EXTS) { ASSERT(realloc); page_idx = 0; erp_idx++; erp = erp_idx < nlists ? erp + 1 : NULL; break; } else { page_idx -= erp->er_extoff; break; } } *idxp = page_idx; *erp_idxp = erp_idx; return(erp); } /* * Allocate and initialize an indirection array once the space needed * for incore extents increases above XFS_IEXT_BUFSZ. */ void xfs_iext_irec_init( xfs_ifork_t *ifp) /* inode fork pointer */ { xfs_ext_irec_t *erp; /* indirection array pointer */ xfs_extnum_t nextents; /* number of extents in file */ ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ASSERT(nextents <= XFS_LINEAR_EXTS); erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); if (nextents == 0) { ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); } else if (!ifp->if_real_bytes) { xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ); } erp->er_extbuf = ifp->if_u1.if_extents; erp->er_extcount = nextents; erp->er_extoff = 0; ifp->if_flags |= XFS_IFEXTIREC; ifp->if_real_bytes = XFS_IEXT_BUFSZ; ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t); ifp->if_u1.if_ext_irec = erp; return; } /* * Allocate and initialize a new entry in the indirection array. */ xfs_ext_irec_t * xfs_iext_irec_new( xfs_ifork_t *ifp, /* inode fork pointer */ int erp_idx) /* index for new irec */ { xfs_ext_irec_t *erp; /* indirection array pointer */ int i; /* loop counter */ int nlists; /* number of irec's (ex lists) */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; /* Resize indirection array */ xfs_iext_realloc_indirect(ifp, ++nlists * sizeof(xfs_ext_irec_t)); /* * Move records down in the array so the * new page can use erp_idx. */ erp = ifp->if_u1.if_ext_irec; for (i = nlists - 1; i > erp_idx; i--) { memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t)); } ASSERT(i == erp_idx); /* Initialize new extent record */ erp = ifp->if_u1.if_ext_irec; erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); erp[erp_idx].er_extcount = 0; erp[erp_idx].er_extoff = erp_idx > 0 ? erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0; return (&erp[erp_idx]); } /* * Remove a record from the indirection array. */ void xfs_iext_irec_remove( xfs_ifork_t *ifp, /* inode fork pointer */ int erp_idx) /* irec index to remove */ { xfs_ext_irec_t *erp; /* indirection array pointer */ int i; /* loop counter */ int nlists; /* number of irec's (ex lists) */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; erp = &ifp->if_u1.if_ext_irec[erp_idx]; if (erp->er_extbuf) { xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -erp->er_extcount); kmem_free(erp->er_extbuf); } /* Compact extent records */ erp = ifp->if_u1.if_ext_irec; for (i = erp_idx; i < nlists - 1; i++) { memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t)); } /* * Manually free the last extent record from the indirection * array. A call to xfs_iext_realloc_indirect() with a size * of zero would result in a call to xfs_iext_destroy() which * would in turn call this function again, creating a nasty * infinite loop. */ if (--nlists) { xfs_iext_realloc_indirect(ifp, nlists * sizeof(xfs_ext_irec_t)); } else { kmem_free(ifp->if_u1.if_ext_irec); } ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; } /* * This is called to clean up large amounts of unused memory allocated * by the indirection array. Before compacting anything though, verify * that the indirection array is still needed and switch back to the * linear extent list (or even the inline buffer) if possible. The * compaction policy is as follows: * * Full Compaction: Extents fit into a single page (or inline buffer) * Partial Compaction: Extents occupy less than 50% of allocated space * No Compaction: Extents occupy at least 50% of allocated space */ void xfs_iext_irec_compact( xfs_ifork_t *ifp) /* inode fork pointer */ { xfs_extnum_t nextents; /* number of extents in file */ int nlists; /* number of irec's (ex lists) */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (nextents == 0) { xfs_iext_destroy(ifp); } else if (nextents <= XFS_INLINE_EXTS) { xfs_iext_indirect_to_direct(ifp); xfs_iext_direct_to_inline(ifp, nextents); } else if (nextents <= XFS_LINEAR_EXTS) { xfs_iext_indirect_to_direct(ifp); } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { xfs_iext_irec_compact_pages(ifp); } } /* * Combine extents from neighboring extent pages. */ void xfs_iext_irec_compact_pages( xfs_ifork_t *ifp) /* inode fork pointer */ { xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */ int erp_idx = 0; /* indirection array index */ int nlists; /* number of irec's (ex lists) */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; while (erp_idx < nlists - 1) { erp = &ifp->if_u1.if_ext_irec[erp_idx]; erp_next = erp + 1; if (erp_next->er_extcount <= (XFS_LINEAR_EXTS - erp->er_extcount)) { memcpy(&erp->er_extbuf[erp->er_extcount], erp_next->er_extbuf, erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); erp->er_extcount += erp_next->er_extcount; /* * Free page before removing extent record * so er_extoffs don't get modified in * xfs_iext_irec_remove. */ kmem_free(erp_next->er_extbuf); erp_next->er_extbuf = NULL; xfs_iext_irec_remove(ifp, erp_idx + 1); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; } else { erp_idx++; } } } /* * This is called to update the er_extoff field in the indirection * array when extents have been added or removed from one of the * extent lists. erp_idx contains the irec index to begin updating * at and ext_diff contains the number of extents that were added * or removed. */ void xfs_iext_irec_update_extoffs( xfs_ifork_t *ifp, /* inode fork pointer */ int erp_idx, /* irec index to update */ int ext_diff) /* number of new extents */ { int i; /* loop counter */ int nlists; /* number of irec's (ex lists */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; for (i = erp_idx; i < nlists; i++) { ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff; } } xfsprogs-3.1.9ubuntu2/libxfs/cache.c0000664000000000000000000003536711256276416014342 0ustar /* * Copyright (c) 2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #define CACHE_DEBUG 1 #undef CACHE_DEBUG #define CACHE_DEBUG 1 #undef CACHE_ABORT /* #define CACHE_ABORT 1 */ #define CACHE_SHAKE_COUNT 64 static unsigned int cache_generic_bulkrelse(struct cache *, struct list_head *); struct cache * cache_init( unsigned int hashsize, struct cache_operations *cache_operations) { struct cache * cache; unsigned int i, maxcount; maxcount = hashsize * HASH_CACHE_RATIO; if (!(cache = malloc(sizeof(struct cache)))) return NULL; if (!(cache->c_hash = calloc(hashsize, sizeof(struct cache_hash)))) { free(cache); return NULL; } cache->c_count = 0; cache->c_max = 0; cache->c_hits = 0; cache->c_misses = 0; cache->c_maxcount = maxcount; cache->c_hashsize = hashsize; cache->hash = cache_operations->hash; cache->alloc = cache_operations->alloc; cache->flush = cache_operations->flush; cache->relse = cache_operations->relse; cache->compare = cache_operations->compare; cache->bulkrelse = cache_operations->bulkrelse ? cache_operations->bulkrelse : cache_generic_bulkrelse; pthread_mutex_init(&cache->c_mutex, NULL); for (i = 0; i < hashsize; i++) { list_head_init(&cache->c_hash[i].ch_list); cache->c_hash[i].ch_count = 0; pthread_mutex_init(&cache->c_hash[i].ch_mutex, NULL); } for (i = 0; i <= CACHE_MAX_PRIORITY; i++) { list_head_init(&cache->c_mrus[i].cm_list); cache->c_mrus[i].cm_count = 0; pthread_mutex_init(&cache->c_mrus[i].cm_mutex, NULL); } return cache; } void cache_expand( struct cache * cache) { pthread_mutex_lock(&cache->c_mutex); #ifdef CACHE_DEBUG fprintf(stderr, "doubling cache size to %d\n", 2 * cache->c_maxcount); #endif cache->c_maxcount *= 2; pthread_mutex_unlock(&cache->c_mutex); } void cache_walk( struct cache * cache, cache_walk_t visit) { struct cache_hash * hash; struct list_head * head; struct list_head * pos; unsigned int i; for (i = 0; i < cache->c_hashsize; i++) { hash = &cache->c_hash[i]; head = &hash->ch_list; pthread_mutex_lock(&hash->ch_mutex); for (pos = head->next; pos != head; pos = pos->next) visit((struct cache_node *)pos); pthread_mutex_unlock(&hash->ch_mutex); } } #ifdef CACHE_ABORT #define cache_abort() abort() #else #define cache_abort() do { } while (0) #endif #ifdef CACHE_DEBUG static void cache_zero_check( struct cache_node * node) { if (node->cn_count > 0) { fprintf(stderr, "%s: refcount is %u, not zero (node=%p)\n", __FUNCTION__, node->cn_count, node); cache_abort(); } } #define cache_destroy_check(c) cache_walk((c), cache_zero_check) #else #define cache_destroy_check(c) do { } while (0) #endif void cache_destroy( struct cache * cache) { unsigned int i; cache_destroy_check(cache); for (i = 0; i < cache->c_hashsize; i++) { list_head_destroy(&cache->c_hash[i].ch_list); pthread_mutex_destroy(&cache->c_hash[i].ch_mutex); } for (i = 0; i <= CACHE_MAX_PRIORITY; i++) { list_head_destroy(&cache->c_mrus[i].cm_list); pthread_mutex_destroy(&cache->c_mrus[i].cm_mutex); } pthread_mutex_destroy(&cache->c_mutex); free(cache->c_hash); free(cache); } static unsigned int cache_generic_bulkrelse( struct cache * cache, struct list_head * list) { struct cache_node * node; unsigned int count = 0; while (!list_empty(list)) { node = list_entry(list->next, struct cache_node, cn_mru); pthread_mutex_destroy(&node->cn_mutex); list_del_init(&node->cn_mru); cache->relse(node); count++; } return count; } /* * We've hit the limit on cache size, so we need to start reclaiming * nodes we've used. The MRU specified by the priority is shaken. * Returns new priority at end of the call (in case we call again). */ static unsigned int cache_shake( struct cache * cache, unsigned int priority, int all) { struct cache_mru *mru; struct cache_hash * hash; struct list_head temp; struct list_head * head; struct list_head * pos; struct list_head * n; struct cache_node * node; unsigned int count; ASSERT(priority <= CACHE_MAX_PRIORITY); if (priority > CACHE_MAX_PRIORITY) priority = 0; mru = &cache->c_mrus[priority]; count = 0; list_head_init(&temp); head = &mru->cm_list; pthread_mutex_lock(&mru->cm_mutex); for (pos = head->prev, n = pos->prev; pos != head; pos = n, n = pos->prev) { node = list_entry(pos, struct cache_node, cn_mru); if (pthread_mutex_trylock(&node->cn_mutex) != 0) continue; hash = cache->c_hash + node->cn_hashidx; if (pthread_mutex_trylock(&hash->ch_mutex) != 0) { pthread_mutex_unlock(&node->cn_mutex); continue; } ASSERT(node->cn_count == 0); ASSERT(node->cn_priority == priority); node->cn_priority = -1; list_move(&node->cn_mru, &temp); list_del_init(&node->cn_hash); hash->ch_count--; mru->cm_count--; pthread_mutex_unlock(&hash->ch_mutex); pthread_mutex_unlock(&node->cn_mutex); count++; if (!all && count == CACHE_SHAKE_COUNT) break; } pthread_mutex_unlock(&mru->cm_mutex); if (count > 0) { cache->bulkrelse(cache, &temp); pthread_mutex_lock(&cache->c_mutex); cache->c_count -= count; pthread_mutex_unlock(&cache->c_mutex); } return (count == CACHE_SHAKE_COUNT) ? priority : ++priority; } /* * Allocate a new hash node (updating atomic counter in the process), * unless doing so will push us over the maximum cache size. */ static struct cache_node * cache_node_allocate( struct cache * cache, cache_key_t key) { unsigned int nodesfree; struct cache_node * node; pthread_mutex_lock(&cache->c_mutex); nodesfree = (cache->c_count < cache->c_maxcount); if (nodesfree) { cache->c_count++; if (cache->c_count > cache->c_max) cache->c_max = cache->c_count; } cache->c_misses++; pthread_mutex_unlock(&cache->c_mutex); if (!nodesfree) return NULL; node = cache->alloc(key); if (node == NULL) { /* uh-oh */ pthread_mutex_lock(&cache->c_mutex); cache->c_count--; pthread_mutex_unlock(&cache->c_mutex); return NULL; } pthread_mutex_init(&node->cn_mutex, NULL); list_head_init(&node->cn_mru); node->cn_count = 1; node->cn_priority = 0; return node; } int cache_overflowed( struct cache * cache) { return (cache->c_maxcount == cache->c_max); } /* * Lookup in the cache hash table. With any luck we'll get a cache * hit, in which case this will all be over quickly and painlessly. * Otherwise, we allocate a new node, taking care not to expand the * cache beyond the requested maximum size (shrink it if it would). * Returns one if hit in cache, otherwise zero. A node is _always_ * returned, however. */ int cache_node_get( struct cache * cache, cache_key_t key, struct cache_node ** nodep) { struct cache_node * node = NULL; struct cache_hash * hash; struct cache_mru * mru; struct list_head * head; struct list_head * pos; unsigned int hashidx; int priority = 0; hashidx = cache->hash(key, cache->c_hashsize); hash = cache->c_hash + hashidx; head = &hash->ch_list; for (;;) { pthread_mutex_lock(&hash->ch_mutex); for (pos = head->next; pos != head; pos = pos->next) { node = list_entry(pos, struct cache_node, cn_hash); if (!cache->compare(node, key)) continue; /* * node found, bump node's reference count, remove it * from its MRU list, and update stats. */ pthread_mutex_lock(&node->cn_mutex); if (node->cn_count == 0) { ASSERT(node->cn_priority >= 0); ASSERT(!list_empty(&node->cn_mru)); mru = &cache->c_mrus[node->cn_priority]; pthread_mutex_lock(&mru->cm_mutex); mru->cm_count--; list_del_init(&node->cn_mru); pthread_mutex_unlock(&mru->cm_mutex); } node->cn_count++; pthread_mutex_unlock(&node->cn_mutex); pthread_mutex_unlock(&hash->ch_mutex); pthread_mutex_lock(&cache->c_mutex); cache->c_hits++; pthread_mutex_unlock(&cache->c_mutex); *nodep = node; return 0; } pthread_mutex_unlock(&hash->ch_mutex); /* * not found, allocate a new entry */ node = cache_node_allocate(cache, key); if (node) break; priority = cache_shake(cache, priority, 0); /* * We start at 0; if we free CACHE_SHAKE_COUNT we get * back the same priority, if not we get back priority+1. * If we exceed CACHE_MAX_PRIORITY all slots are full; grow it. */ if (priority > CACHE_MAX_PRIORITY) { priority = 0; cache_expand(cache); } } node->cn_hashidx = hashidx; /* add new node to appropriate hash */ pthread_mutex_lock(&hash->ch_mutex); hash->ch_count++; list_add(&node->cn_hash, &hash->ch_list); pthread_mutex_unlock(&hash->ch_mutex); *nodep = node; return 1; } void cache_node_put( struct cache * cache, struct cache_node * node) { struct cache_mru * mru; pthread_mutex_lock(&node->cn_mutex); #ifdef CACHE_DEBUG if (node->cn_count < 1) { fprintf(stderr, "%s: node put on refcount %u (node=%p)\n", __FUNCTION__, node->cn_count, node); cache_abort(); } if (!list_empty(&node->cn_mru)) { fprintf(stderr, "%s: node put on node (%p) in MRU list\n", __FUNCTION__, node); cache_abort(); } #endif node->cn_count--; if (node->cn_count == 0) { /* add unreferenced node to appropriate MRU for shaker */ mru = &cache->c_mrus[node->cn_priority]; pthread_mutex_lock(&mru->cm_mutex); mru->cm_count++; list_add(&node->cn_mru, &mru->cm_list); pthread_mutex_unlock(&mru->cm_mutex); } pthread_mutex_unlock(&node->cn_mutex); } void cache_node_set_priority( struct cache * cache, struct cache_node * node, int priority) { if (priority < 0) priority = 0; else if (priority > CACHE_MAX_PRIORITY) priority = CACHE_MAX_PRIORITY; pthread_mutex_lock(&node->cn_mutex); ASSERT(node->cn_count > 0); node->cn_priority = priority; pthread_mutex_unlock(&node->cn_mutex); } int cache_node_get_priority( struct cache_node * node) { int priority; pthread_mutex_lock(&node->cn_mutex); priority = node->cn_priority; pthread_mutex_unlock(&node->cn_mutex); return priority; } /* * Purge a specific node from the cache. Reference count must be zero. */ int cache_node_purge( struct cache * cache, cache_key_t key, struct cache_node * node) { struct list_head * head; struct list_head * pos; struct list_head * n; struct cache_hash * hash; struct cache_mru * mru; int count = -1; hash = cache->c_hash + cache->hash(key, cache->c_hashsize); head = &hash->ch_list; pthread_mutex_lock(&hash->ch_mutex); for (pos = head->next, n = pos->next; pos != head; pos = n, n = pos->next) { if ((struct cache_node *)pos != node) continue; pthread_mutex_lock(&node->cn_mutex); count = node->cn_count; if (count != 0) { pthread_mutex_unlock(&node->cn_mutex); break; } mru = &cache->c_mrus[node->cn_priority]; pthread_mutex_lock(&mru->cm_mutex); list_del_init(&node->cn_mru); mru->cm_count--; pthread_mutex_unlock(&mru->cm_mutex); pthread_mutex_unlock(&node->cn_mutex); pthread_mutex_destroy(&node->cn_mutex); list_del_init(&node->cn_hash); hash->ch_count--; cache->relse(node); break; } pthread_mutex_unlock(&hash->ch_mutex); if (count == 0) { pthread_mutex_lock(&cache->c_mutex); cache->c_count--; pthread_mutex_unlock(&cache->c_mutex); } #ifdef CACHE_DEBUG if (count >= 1) { fprintf(stderr, "%s: refcount was %u, not zero (node=%p)\n", __FUNCTION__, count, node); cache_abort(); } if (count == -1) { fprintf(stderr, "%s: purge node not found! (node=%p)\n", __FUNCTION__, node); cache_abort(); } #endif return (count == 0); } /* * Purge all nodes from the cache. All reference counts must be zero. */ void cache_purge( struct cache * cache) { int i; for (i = 0; i <= CACHE_MAX_PRIORITY; i++) cache_shake(cache, i, 1); #ifdef CACHE_DEBUG if (cache->c_count != 0) { /* flush referenced nodes to disk */ cache_flush(cache); fprintf(stderr, "%s: shake on cache %p left %u nodes!?\n", __FUNCTION__, cache, cache->c_count); cache_abort(); } #endif } /* * Flush all nodes in the cache to disk. */ void cache_flush( struct cache * cache) { struct cache_hash * hash; struct list_head * head; struct list_head * pos; struct cache_node * node; int i; if (!cache->flush) return; for (i = 0; i < cache->c_hashsize; i++) { hash = &cache->c_hash[i]; pthread_mutex_lock(&hash->ch_mutex); head = &hash->ch_list; for (pos = head->next; pos != head; pos = pos->next) { node = (struct cache_node *)pos; pthread_mutex_lock(&node->cn_mutex); cache->flush(node); pthread_mutex_unlock(&node->cn_mutex); } pthread_mutex_unlock(&hash->ch_mutex); } } #define HASH_REPORT (3 * HASH_CACHE_RATIO) void cache_report( FILE *fp, const char *name, struct cache *cache) { int i; unsigned long count, index, total; unsigned long hash_bucket_lengths[HASH_REPORT + 2]; if ((cache->c_hits + cache->c_misses) == 0) return; /* report cache summary */ fprintf(fp, "%s: %p\n" "Max supported entries = %u\n" "Max utilized entries = %u\n" "Active entries = %u\n" "Hash table size = %u\n" "Hits = %llu\n" "Misses = %llu\n" "Hit ratio = %5.2f\n", name, cache, cache->c_maxcount, cache->c_max, cache->c_count, cache->c_hashsize, cache->c_hits, cache->c_misses, (double)cache->c_hits * 100 / (cache->c_hits + cache->c_misses) ); for (i = 0; i <= CACHE_MAX_PRIORITY; i++) fprintf(fp, "MRU %d entries = %6u (%3u%%)\n", i, cache->c_mrus[i].cm_count, cache->c_mrus[i].cm_count * 100 / cache->c_count); /* report hash bucket lengths */ bzero(hash_bucket_lengths, sizeof(hash_bucket_lengths)); for (i = 0; i < cache->c_hashsize; i++) { count = cache->c_hash[i].ch_count; if (count > HASH_REPORT) index = HASH_REPORT + 1; else index = count; hash_bucket_lengths[index]++; } total = 0; for (i = 0; i < HASH_REPORT + 1; i++) { total += i * hash_bucket_lengths[i]; if (hash_bucket_lengths[i] == 0) continue; fprintf(fp, "Hash buckets with %2d entries %6ld (%3ld%%)\n", i, hash_bucket_lengths[i], (i * hash_bucket_lengths[i] * 100) / cache->c_count); } if (hash_bucket_lengths[i]) /* last report bucket is the overflow bucket */ fprintf(fp, "Hash buckets with >%2d entries %6ld (%3ld%%)\n", i - 1, hash_bucket_lengths[i], ((cache->c_count - total) * 100) / cache->c_count); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_sf.c0000664000000000000000000010310011650373061015454 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Prototypes for internal functions. */ static void xfs_dir2_sf_addname_easy(xfs_da_args_t *args, xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t offset, int new_isize); static void xfs_dir2_sf_addname_hard(xfs_da_args_t *args, int objchange, int new_isize); static int xfs_dir2_sf_addname_pick(xfs_da_args_t *args, int objchange, xfs_dir2_sf_entry_t **sfepp, xfs_dir2_data_aoff_t *offsetp); #ifdef DEBUG static void xfs_dir2_sf_check(xfs_da_args_t *args); #else #define xfs_dir2_sf_check(args) #endif /* DEBUG */ #if XFS_BIG_INUMS static void xfs_dir2_sf_toino4(xfs_da_args_t *args); static void xfs_dir2_sf_toino8(xfs_da_args_t *args); #endif /* XFS_BIG_INUMS */ /* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the * space currently present in the inode. If it won't fit, the output * size is too big (but not accurate). */ int /* size for sf form */ xfs_dir2_block_sfsize( xfs_inode_t *dp, /* incore inode pointer */ xfs_dir2_block_t *block, /* block directory data */ xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */ { xfs_dir2_dataptr_t addr; /* data entry address */ xfs_dir2_leaf_entry_t *blp; /* leaf area of the block */ xfs_dir2_block_tail_t *btp; /* tail area of the block */ int count; /* shortform entry count */ xfs_dir2_data_entry_t *dep; /* data entry in the block */ int i; /* block entry index */ int i8count; /* count of big-inode entries */ int isdot; /* entry is "." */ int isdotdot; /* entry is ".." */ xfs_mount_t *mp; /* mount structure pointer */ int namelen; /* total name bytes */ xfs_ino_t parent = 0; /* parent inode number */ int size=0; /* total computed size */ mp = dp->i_mount; count = i8count = namelen = 0; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Iterate over the block's data entries by using the leaf pointers. */ for (i = 0; i < be32_to_cpu(btp->count); i++) { if ((addr = be32_to_cpu(blp[i].address)) == XFS_DIR2_NULL_DATAPTR) continue; /* * Calculate the pointer to the entry at hand. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); /* * Detect . and .., so we can special-case them. * . is not included in sf directories. * .. is included by just the parent inode number. */ isdot = dep->namelen == 1 && dep->name[0] == '.'; isdotdot = dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.'; #if XFS_BIG_INUMS if (!isdot) i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; #endif if (!isdot && !isdotdot) { count++; namelen += dep->namelen; } else if (isdotdot) parent = be64_to_cpu(dep->inumber); /* * Calculate the new size, see if we should give up yet. */ size = xfs_dir2_sf_hdr_size(i8count) + /* header */ count + /* namelen */ count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */ namelen + /* name */ (i8count ? /* inumber */ (uint)sizeof(xfs_dir2_ino8_t) * count : (uint)sizeof(xfs_dir2_ino4_t) * count); if (size > XFS_IFORK_DSIZE(dp)) return size; /* size value is a failure */ } /* * Create the output header, if it worked. */ sfhp->count = count; sfhp->i8count = i8count; xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); return size; } /* * Convert a block format directory to shortform. * Caller has already checked that it will fit, and built us a header. */ int /* error */ xfs_dir2_block_to_sf( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *bp, /* block buffer */ int size, /* shortform directory size */ xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ { xfs_dir2_block_t *block; /* block structure */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused data pointer */ char *endptr; /* end of data entries */ int error; /* error return value */ int logflags; /* inode logging flags */ xfs_mount_t *mp; /* filesystem mount point */ char *ptr; /* current data pointer */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ xfs_ino_t temp; trace_xfs_dir2_block_to_sf(args); dp = args->dp; mp = dp->i_mount; /* * Make a copy of the block data, so we can shrink the inode * and add local data. */ block = kmem_alloc(mp->m_dirblksize, KM_SLEEP); memcpy(block, bp->data, mp->m_dirblksize); logflags = XFS_ILOG_CORE; if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { ASSERT(error != ENOSPC); goto out; } /* * The buffer is now unconditionally gone, whether * xfs_dir2_shrink_inode worked or not. * * Convert the inode to local format. */ dp->i_df.if_flags &= ~XFS_IFEXTENTS; dp->i_df.if_flags |= XFS_IFINLINE; dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; ASSERT(dp->i_df.if_bytes == 0); xfs_idata_realloc(dp, size, XFS_DATA_FORK); logflags |= XFS_ILOG_DDATA; /* * Copy the header into the newly allocate local space. */ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); dp->i_d.di_size = size; /* * Set up to loop over the block's entries. */ btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; endptr = (char *)xfs_dir2_block_leaf_p(btp); sfep = xfs_dir2_sf_firstentry(sfp); /* * Loop over the active and unused entries. * Stop when we reach the leaf/tail portion of the block. */ while (ptr < endptr) { /* * If it's unused, just skip over it. */ dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ptr += be16_to_cpu(dup->length); continue; } dep = (xfs_dir2_data_entry_t *)ptr; /* * Skip . */ if (dep->namelen == 1 && dep->name[0] == '.') ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino); /* * Skip .., but make sure the inode number is right. */ else if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') ASSERT(be64_to_cpu(dep->inumber) == xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); /* * Normal entry, copy it into shortform. */ else { sfep->namelen = dep->namelen; xfs_dir2_sf_put_offset(sfep, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)block)); memcpy(sfep->name, dep->name, dep->namelen); temp = be64_to_cpu(dep->inumber); xfs_dir2_sf_put_inumber(sfp, &temp, xfs_dir2_sf_inumberp(sfep)); sfep = xfs_dir2_sf_nextentry(sfp, sfep); } ptr += xfs_dir2_data_entsize(dep->namelen); } ASSERT((char *)sfep - (char *)sfp == size); xfs_dir2_sf_check(args); out: xfs_trans_log_inode(args->trans, dp, logflags); kmem_free(block); return error; } /* * Add a name to a shortform directory. * There are two algorithms, "easy" and "hard" which we decide on * before changing anything. * Convert to block form if necessary, if the new entry won't fit. */ int /* error */ xfs_dir2_sf_addname( xfs_da_args_t *args) /* operation arguments */ { int add_entsize; /* size of the new entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ int incr_isize; /* total change in size */ int new_isize; /* di_size after adding name */ int objchange; /* changing to 8-byte inodes */ xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */ int old_isize; /* di_size before adding name */ int pick; /* which algorithm to use */ xfs_dir2_sf_t *sfp; /* shortform structure */ xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ trace_xfs_dir2_sf_addname(args); ASSERT(xfs_dir2_sf_lookup(args) == ENOENT); dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); /* * Make sure the shortform value has some of its header. */ if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); return XFS_ERROR(EIO); } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Compute entry (and change in) size. */ add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); incr_isize = add_entsize; objchange = 0; #if XFS_BIG_INUMS /* * Do we have to change to 8 byte inodes? */ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { /* * Yes, adjust the entry size and the total size. */ add_entsize += (uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t); incr_isize += (sfp->hdr.count + 2) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); objchange = 1; } #endif old_isize = (int)dp->i_d.di_size; new_isize = old_isize + incr_isize; /* * Won't fit as shortform any more (due to size), * or the pick routine says it won't (due to offset values). */ if (new_isize > XFS_IFORK_DSIZE(dp) || (pick = xfs_dir2_sf_addname_pick(args, objchange, &sfep, &offset)) == 0) { /* * Just checking or no space reservation, it doesn't fit. */ if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) return XFS_ERROR(ENOSPC); /* * Convert to block form then add the name. */ error = xfs_dir2_sf_to_block(args); if (error) return error; return xfs_dir2_block_addname(args); } /* * Just checking, it fits. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; /* * Do it the easy way - just add it at the end. */ if (pick == 1) xfs_dir2_sf_addname_easy(args, sfep, offset, new_isize); /* * Do it the hard way - look for a place to insert the new entry. * Convert to 8 byte inode numbers first if necessary. */ else { ASSERT(pick == 2); #if XFS_BIG_INUMS if (objchange) xfs_dir2_sf_toino8(args); #endif xfs_dir2_sf_addname_hard(args, objchange, new_isize); } xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); return 0; } /* * Add the new entry the "easy" way. * This is copying the old directory and adding the new entry at the end. * Since it's sorted by "offset" we need room after the last offset * that's already there, and then room to convert to a block directory. * This is already checked by the pick routine. */ static void xfs_dir2_sf_addname_easy( xfs_da_args_t *args, /* operation arguments */ xfs_dir2_sf_entry_t *sfep, /* pointer to new entry */ xfs_dir2_data_aoff_t offset, /* offset to use for new ent */ int new_isize) /* new directory size */ { int byteoff; /* byte offset in sf dir */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_sf_t *sfp; /* shortform structure */ dp = args->dp; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; byteoff = (int)((char *)sfep - (char *)sfp); /* * Grow the in-inode space. */ xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), XFS_DATA_FORK); /* * Need to set up again due to realloc of the inode data. */ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff); /* * Fill in the new entry. */ sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_inumber(sfp, &args->inumber, xfs_dir2_sf_inumberp(sfep)); /* * Update the header and inode. */ sfp->hdr.count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) sfp->hdr.i8count++; #endif dp->i_d.di_size = new_isize; xfs_dir2_sf_check(args); } /* * Add the new entry the "hard" way. * The caller has already converted to 8 byte inode numbers if necessary, * in which case we need to leave the i8count at 1. * Find a hole that the new entry will fit into, and copy * the first part of the entries, the new entry, and the last part of * the entries. */ /* ARGSUSED */ static void xfs_dir2_sf_addname_hard( xfs_da_args_t *args, /* operation arguments */ int objchange, /* changing inode number size */ int new_isize) /* new directory size */ { int add_datasize; /* data size need for new ent */ char *buf; /* buffer for old */ xfs_inode_t *dp; /* incore directory inode */ int eof; /* reached end of old dir */ int nbytes; /* temp for byte copies */ xfs_dir2_data_aoff_t new_offset; /* next offset value */ xfs_dir2_data_aoff_t offset; /* current offset value */ int old_isize; /* previous di_size */ xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */ xfs_dir2_sf_t *oldsfp; /* original shortform dir */ xfs_dir2_sf_entry_t *sfep; /* entry in new dir */ xfs_dir2_sf_t *sfp; /* new shortform dir */ /* * Copy the old directory to the stack buffer. */ dp = args->dp; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; old_isize = (int)dp->i_d.di_size; buf = kmem_alloc(old_isize, KM_SLEEP); oldsfp = (xfs_dir2_sf_t *)buf; memcpy(oldsfp, sfp, old_isize); /* * Loop over the old directory finding the place we're going * to insert the new entry. * If it's going to end up at the end then oldsfep will point there. */ for (offset = XFS_DIR2_DATA_FIRST_OFFSET, oldsfep = xfs_dir2_sf_firstentry(oldsfp), add_datasize = xfs_dir2_data_entsize(args->namelen), eof = (char *)oldsfep == &buf[old_isize]; !eof; offset = new_offset + xfs_dir2_data_entsize(oldsfep->namelen), oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep), eof = (char *)oldsfep == &buf[old_isize]) { new_offset = xfs_dir2_sf_get_offset(oldsfep); if (offset + add_datasize <= new_offset) break; } /* * Get rid of the old directory, then allocate space for * the new one. We do this so xfs_idata_realloc won't copy * the data. */ xfs_idata_realloc(dp, -old_isize, XFS_DATA_FORK); xfs_idata_realloc(dp, new_isize, XFS_DATA_FORK); /* * Reset the pointer since the buffer was reallocated. */ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; /* * Copy the first part of the directory, including the header. */ nbytes = (int)((char *)oldsfep - (char *)oldsfp); memcpy(sfp, oldsfp, nbytes); sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + nbytes); /* * Fill in the new entry, and update the header counts. */ sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_inumber(sfp, &args->inumber, xfs_dir2_sf_inumberp(sfep)); sfp->hdr.count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) sfp->hdr.i8count++; #endif /* * If there's more left to copy, do that. */ if (!eof) { sfep = xfs_dir2_sf_nextentry(sfp, sfep); memcpy(sfep, oldsfep, old_isize - nbytes); } kmem_free(buf); dp->i_d.di_size = new_isize; xfs_dir2_sf_check(args); } /* * Decide if the new entry will fit at all. * If it will fit, pick between adding the new entry to the end (easy) * or somewhere else (hard). * Return 0 (won't fit), 1 (easy), 2 (hard). */ /*ARGSUSED*/ static int /* pick result */ xfs_dir2_sf_addname_pick( xfs_da_args_t *args, /* operation arguments */ int objchange, /* inode # size changes */ xfs_dir2_sf_entry_t **sfepp, /* out(1): new entry ptr */ xfs_dir2_data_aoff_t *offsetp) /* out(1): new offset */ { xfs_inode_t *dp; /* incore directory inode */ int holefit; /* found hole it will fit in */ int i; /* entry number */ xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_data_aoff_t offset; /* data block offset */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ int size; /* entry's data size */ int used; /* data bytes used */ dp = args->dp; mp = dp->i_mount; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; size = xfs_dir2_data_entsize(args->namelen); offset = XFS_DIR2_DATA_FIRST_OFFSET; sfep = xfs_dir2_sf_firstentry(sfp); holefit = 0; /* * Loop over sf entries. * Keep track of data offset and whether we've seen a place * to insert the new entry. */ for (i = 0; i < sfp->hdr.count; i++) { if (!holefit) holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); offset = xfs_dir2_sf_get_offset(sfep) + xfs_dir2_data_entsize(sfep->namelen); sfep = xfs_dir2_sf_nextentry(sfp, sfep); } /* * Calculate data bytes used excluding the new entry, if this * was a data block (block form directory). */ used = offset + (sfp->hdr.count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (uint)sizeof(xfs_dir2_block_tail_t); /* * If it won't fit in a block form then we can't insert it, * we'll go back, convert to block, then try the insert and convert * to leaf. */ if (used + (holefit ? 0 : size) > mp->m_dirblksize) return 0; /* * If changing the inode number size, do it the hard way. */ #if XFS_BIG_INUMS if (objchange) { return 2; } #else ASSERT(objchange == 0); #endif /* * If it won't fit at the end then do it the hard way (use the hole). */ if (used + size > mp->m_dirblksize) return 2; /* * Do it the easy way. */ *sfepp = sfep; *offsetp = offset; return 1; } #ifdef DEBUG /* * Check consistency of shortform directory, assert if bad. */ static void xfs_dir2_sf_check( xfs_da_args_t *args) /* operation arguments */ { xfs_inode_t *dp; /* incore directory inode */ int i; /* entry number */ int i8count; /* number of big inode#s */ xfs_ino_t ino; /* entry inode number */ int offset; /* data offset */ xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ dp = args->dp; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; offset = XFS_DIR2_DATA_FIRST_OFFSET; ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + xfs_dir2_data_entsize(sfep->namelen); } ASSERT(i8count == sfp->hdr.i8count); ASSERT(XFS_BIG_INUMS || i8count == 0); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); ASSERT(offset + (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (uint)sizeof(xfs_dir2_block_tail_t) <= dp->i_mount->m_dirblksize); } #endif /* DEBUG */ /* * Create a new (shortform) directory. */ int /* error, always 0 */ xfs_dir2_sf_create( xfs_da_args_t *args, /* operation arguments */ xfs_ino_t pino) /* parent inode number */ { xfs_inode_t *dp; /* incore directory inode */ int i8count; /* parent inode is an 8-byte number */ xfs_dir2_sf_t *sfp; /* shortform structure */ int size; /* directory size */ trace_xfs_dir2_sf_create(args); dp = args->dp; ASSERT(dp != NULL); ASSERT(dp->i_d.di_size == 0); /* * If it's currently a zero-length extent file, * convert it to local format. */ if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); dp->i_df.if_flags |= XFS_IFINLINE; } ASSERT(dp->i_df.if_flags & XFS_IFINLINE); ASSERT(dp->i_df.if_bytes == 0); i8count = pino > XFS_DIR2_MAX_SHORT_INUM; size = xfs_dir2_sf_hdr_size(i8count); /* * Make a buffer for the data. */ xfs_idata_realloc(dp, size, XFS_DATA_FORK); /* * Fill in the header, */ sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; sfp->hdr.i8count = i8count; /* * Now can put in the inode number, since i8count is set. */ xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); sfp->hdr.count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); return 0; } /* * Lookup an entry in a shortform directory. * Returns EEXIST if found, ENOENT if not found. */ int /* error */ xfs_dir2_sf_lookup( xfs_da_args_t *args) /* operation arguments */ { xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ enum xfs_dacmp cmp; /* comparison result */ xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ trace_xfs_dir2_sf_lookup(args); xfs_dir2_sf_check(args); dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); /* * Bail out if the directory is way too short. */ if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); return XFS_ERROR(EIO); } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Special case for . */ if (args->namelen == 1 && args->name[0] == '.') { args->inumber = dp->i_ino; args->cmpresult = XFS_CMP_EXACT; return XFS_ERROR(EEXIST); } /* * Special case for .. */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); args->cmpresult = XFS_CMP_EXACT; return XFS_ERROR(EEXIST); } /* * Loop over all the entries trying to match ours. */ ci_sfep = NULL; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { /* * Compare name and if it's an exact match, return the inode * number. If it's the first case-insensitive match, store the * inode number and continue looking for an exact match. */ cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, sfep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; args->inumber = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); ci_sfep = sfep; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); /* * Here, we can only be doing a lookup (not a rename or replace). * If a case-insensitive match was not found, return ENOENT. */ if (!ci_sfep) return XFS_ERROR(ENOENT); /* otherwise process the CI match as required by the caller */ error = xfs_dir_cilookup_result(args, ci_sfep->name, ci_sfep->namelen); return XFS_ERROR(error); } /* * Remove an entry from a shortform directory. */ int /* error */ xfs_dir2_sf_removename( xfs_da_args_t *args) { int byteoff; /* offset of removed entry */ xfs_inode_t *dp; /* incore directory inode */ int entsize; /* this entry's size */ int i; /* shortform entry index */ int newsize; /* new inode size */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_removename(args); dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); oldsize = (int)dp->i_d.di_size; /* * Bail out if the directory is way too short. */ if (oldsize < offsetof(xfs_dir2_sf_hdr_t, parent)) { ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); return XFS_ERROR(EIO); } ASSERT(dp->i_df.if_bytes == oldsize); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Loop over the old directory entries. * Find the one we're deleting. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { ASSERT(xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)) == args->inumber); break; } } /* * Didn't find it. */ if (i == sfp->hdr.count) return XFS_ERROR(ENOENT); /* * Calculate sizes. */ byteoff = (int)((char *)sfep - (char *)sfp); entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); newsize = oldsize - entsize; /* * Copy the part if any after the removed entry, sliding it down. */ if (byteoff + entsize < oldsize) memmove((char *)sfp + byteoff, (char *)sfp + byteoff + entsize, oldsize - (byteoff + entsize)); /* * Fix up the header and file size. */ sfp->hdr.count--; dp->i_d.di_size = newsize; /* * Reallocate, making it smaller. */ xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; #if XFS_BIG_INUMS /* * Are we changing inode number size? */ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) { if (sfp->hdr.i8count == 1) xfs_dir2_sf_toino4(args); else sfp->hdr.i8count--; } #endif xfs_dir2_sf_check(args); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); return 0; } /* * Replace the inode number of an entry in a shortform directory. */ int /* error */ xfs_dir2_sf_replace( xfs_da_args_t *args) /* operation arguments */ { xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ #if XFS_BIG_INUMS || defined(DEBUG) xfs_ino_t ino=0; /* entry old inode number */ #endif #if XFS_BIG_INUMS int i8elevated; /* sf_toino8 set i8count=1 */ #endif xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_replace(args); dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); /* * Bail out if the shortform directory is way too small. */ if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); return XFS_ERROR(EIO); } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); #if XFS_BIG_INUMS /* * New inode number is large, and need to convert to 8-byte inodes. */ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { int error; /* error return value */ int newsize; /* new inode size */ newsize = dp->i_df.if_bytes + (sfp->hdr.count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); /* * Won't fit as shortform, convert to block then do replace. */ if (newsize > XFS_IFORK_DSIZE(dp)) { error = xfs_dir2_sf_to_block(args); if (error) { return error; } return xfs_dir2_block_replace(args); } /* * Still fits, convert to 8-byte now. */ xfs_dir2_sf_toino8(args); i8elevated = 1; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; } else i8elevated = 0; #endif ASSERT(args->namelen != 1 || args->name[0] != '.'); /* * Replace ..'s entry. */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { #if XFS_BIG_INUMS || defined(DEBUG) ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); ASSERT(args->inumber != ino); #endif xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); } /* * Normal entry, look for the name. */ else { for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { #if XFS_BIG_INUMS || defined(DEBUG) ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); ASSERT(args->inumber != ino); #endif xfs_dir2_sf_put_inumber(sfp, &args->inumber, xfs_dir2_sf_inumberp(sfep)); break; } } /* * Didn't find it. */ if (i == sfp->hdr.count) { ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); #if XFS_BIG_INUMS if (i8elevated) xfs_dir2_sf_toino4(args); #endif return XFS_ERROR(ENOENT); } } #if XFS_BIG_INUMS /* * See if the old number was large, the new number is small. */ if (ino > XFS_DIR2_MAX_SHORT_INUM && args->inumber <= XFS_DIR2_MAX_SHORT_INUM) { /* * And the old count was one, so need to convert to small. */ if (sfp->hdr.i8count == 1) xfs_dir2_sf_toino4(args); else sfp->hdr.i8count--; } /* * See if the old number was small, the new number is large. */ if (ino <= XFS_DIR2_MAX_SHORT_INUM && args->inumber > XFS_DIR2_MAX_SHORT_INUM) { /* * add to the i8count unless we just converted to 8-byte * inodes (which does an implied i8count = 1) */ ASSERT(sfp->hdr.i8count != 0); if (!i8elevated) sfp->hdr.i8count++; } #endif xfs_dir2_sf_check(args); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); return 0; } #if XFS_BIG_INUMS /* * Convert from 8-byte inode numbers to 4-byte inode numbers. * The last 8-byte inode number is gone, but the count is still 1. */ static void xfs_dir2_sf_toino4( xfs_da_args_t *args) /* operation arguments */ { char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ xfs_dir2_sf_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ xfs_dir2_sf_t *sfp; /* new sf directory */ trace_xfs_dir2_sf_toino4(args); dp = args->dp; /* * Copy the old directory to the buffer. * Then nuke it from the inode, and add the new buffer to the inode. * Don't want xfs_idata_realloc copying the data here. */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(oldsfp->hdr.i8count == 1); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize - (oldsfp->hdr.count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ oldsfp = (xfs_dir2_sf_t *)buf; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 0; ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); ino = xfs_dir2_sf_get_inumber(oldsfp, xfs_dir2_sf_inumberp(oldsfep)); xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); } /* * Clean up the inode. */ kmem_free(buf); dp->i_d.di_size = newsize; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); } /* * Convert from 4-byte inode numbers to 8-byte inode numbers. * The new 8-byte inode number is not there yet, we leave with the * count 1 but no corresponding entry. */ static void xfs_dir2_sf_toino8( xfs_da_args_t *args) /* operation arguments */ { char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ xfs_dir2_sf_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ xfs_dir2_sf_t *sfp; /* new sf directory */ trace_xfs_dir2_sf_toino8(args); dp = args->dp; /* * Copy the old directory to the buffer. * Then nuke it from the inode, and add the new buffer to the inode. * Don't want xfs_idata_realloc copying the data here. */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(oldsfp->hdr.i8count == 0); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize + (oldsfp->hdr.count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ oldsfp = (xfs_dir2_sf_t *)buf; sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 1; ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); ino = xfs_dir2_sf_get_inumber(oldsfp, xfs_dir2_sf_inumberp(oldsfep)); xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); } /* * Clean up the inode. */ kmem_free(buf); dp->i_d.di_size = newsize; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); } #endif /* XFS_BIG_INUMS */ xfsprogs-3.1.9ubuntu2/libxfs/xfs_alloc_btree.c0000664000000000000000000002577211650373061016421 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include STATIC struct xfs_btree_cur * xfs_allocbt_dup_cursor( struct xfs_btree_cur *cur) { return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_private.a.agbp, cur->bc_private.a.agno, cur->bc_btnum); } STATIC void xfs_allocbt_set_root( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr, int inc) { struct xfs_buf *agbp = cur->bc_private.a.agbp; struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int btnum = cur->bc_btnum; struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); ASSERT(ptr->s != 0); agf->agf_roots[btnum] = ptr->s; be32_add_cpu(&agf->agf_levels[btnum], inc); pag->pagf_levels[btnum] += inc; xfs_perag_put(pag); xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); } STATIC int xfs_allocbt_alloc_block( struct xfs_btree_cur *cur, union xfs_btree_ptr *start, union xfs_btree_ptr *new, int length, int *stat) { int error; xfs_agblock_t bno; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); /* Allocate the new block from the freelist. If we can't, give up. */ error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, &bno, 1); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } if (bno == NULLAGBLOCK) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } xfs_trans_agbtree_delta(cur->bc_tp, 1); new->s = cpu_to_be32(bno); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; } STATIC int xfs_allocbt_free_block( struct xfs_btree_cur *cur, struct xfs_buf *bp) { struct xfs_buf *agbp = cur->bc_private.a.agbp; struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); xfs_agblock_t bno; int error; bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); if (error) return error; /* * Since blocks move to the free list without the coordination used in * xfs_bmap_finish, we can't allow block to be available for * reallocation and non-transaction writing (user data) until we know * that the transaction that moved it to the free list is permanently * on disk. We track the blocks by declaring these blocks as "busy"; * the busy list is maintained on a per-ag basis and each transaction * records which entries should be removed when the iclog commits to * disk. If a busy block is allocated, the iclog is pushed up to the * LSN that freed the block. */ xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); xfs_trans_agbtree_delta(cur->bc_tp, -1); return 0; } /* * Update the longest extent in the AGF */ STATIC void xfs_allocbt_update_lastrec( struct xfs_btree_cur *cur, struct xfs_btree_block *block, union xfs_btree_rec *rec, int ptr, int reason) { struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); struct xfs_perag *pag; __be32 len; int numrecs; ASSERT(cur->bc_btnum == XFS_BTNUM_CNT); switch (reason) { case LASTREC_UPDATE: /* * If this is the last leaf block and it's the last record, * then update the size of the longest extent in the AG. */ if (ptr != xfs_btree_get_numrecs(block)) return; len = rec->alloc.ar_blockcount; break; case LASTREC_INSREC: if (be32_to_cpu(rec->alloc.ar_blockcount) <= be32_to_cpu(agf->agf_longest)) return; len = rec->alloc.ar_blockcount; break; case LASTREC_DELREC: numrecs = xfs_btree_get_numrecs(block); if (ptr <= numrecs) return; ASSERT(ptr == numrecs + 1); if (numrecs) { xfs_alloc_rec_t *rrp; rrp = XFS_ALLOC_REC_ADDR(cur->bc_mp, block, numrecs); len = rrp->ar_blockcount; } else { len = 0; } break; default: ASSERT(0); return; } agf->agf_longest = len; pag = xfs_perag_get(cur->bc_mp, seqno); pag->pagf_longest = be32_to_cpu(len); xfs_perag_put(pag); xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST); } STATIC int xfs_allocbt_get_minrecs( struct xfs_btree_cur *cur, int level) { return cur->bc_mp->m_alloc_mnr[level != 0]; } STATIC int xfs_allocbt_get_maxrecs( struct xfs_btree_cur *cur, int level) { return cur->bc_mp->m_alloc_mxr[level != 0]; } STATIC void xfs_allocbt_init_key_from_rec( union xfs_btree_key *key, union xfs_btree_rec *rec) { ASSERT(rec->alloc.ar_startblock != 0); key->alloc.ar_startblock = rec->alloc.ar_startblock; key->alloc.ar_blockcount = rec->alloc.ar_blockcount; } STATIC void xfs_allocbt_init_rec_from_key( union xfs_btree_key *key, union xfs_btree_rec *rec) { ASSERT(key->alloc.ar_startblock != 0); rec->alloc.ar_startblock = key->alloc.ar_startblock; rec->alloc.ar_blockcount = key->alloc.ar_blockcount; } STATIC void xfs_allocbt_init_rec_from_cur( struct xfs_btree_cur *cur, union xfs_btree_rec *rec) { ASSERT(cur->bc_rec.a.ar_startblock != 0); rec->alloc.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); rec->alloc.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); } STATIC void xfs_allocbt_init_ptr_from_cur( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); ASSERT(agf->agf_roots[cur->bc_btnum] != 0); ptr->s = agf->agf_roots[cur->bc_btnum]; } STATIC __int64_t xfs_allocbt_key_diff( struct xfs_btree_cur *cur, union xfs_btree_key *key) { xfs_alloc_rec_incore_t *rec = &cur->bc_rec.a; xfs_alloc_key_t *kp = &key->alloc; __int64_t diff; if (cur->bc_btnum == XFS_BTNUM_BNO) { return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock; } diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount; if (diff) return diff; return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock; } #ifdef DEBUG STATIC int xfs_allocbt_keys_inorder( struct xfs_btree_cur *cur, union xfs_btree_key *k1, union xfs_btree_key *k2) { if (cur->bc_btnum == XFS_BTNUM_BNO) { return be32_to_cpu(k1->alloc.ar_startblock) < be32_to_cpu(k2->alloc.ar_startblock); } else { return be32_to_cpu(k1->alloc.ar_blockcount) < be32_to_cpu(k2->alloc.ar_blockcount) || (k1->alloc.ar_blockcount == k2->alloc.ar_blockcount && be32_to_cpu(k1->alloc.ar_startblock) < be32_to_cpu(k2->alloc.ar_startblock)); } } STATIC int xfs_allocbt_recs_inorder( struct xfs_btree_cur *cur, union xfs_btree_rec *r1, union xfs_btree_rec *r2) { if (cur->bc_btnum == XFS_BTNUM_BNO) { return be32_to_cpu(r1->alloc.ar_startblock) + be32_to_cpu(r1->alloc.ar_blockcount) <= be32_to_cpu(r2->alloc.ar_startblock); } else { return be32_to_cpu(r1->alloc.ar_blockcount) < be32_to_cpu(r2->alloc.ar_blockcount) || (r1->alloc.ar_blockcount == r2->alloc.ar_blockcount && be32_to_cpu(r1->alloc.ar_startblock) < be32_to_cpu(r2->alloc.ar_startblock)); } } #endif /* DEBUG */ #ifdef XFS_BTREE_TRACE ktrace_t *xfs_allocbt_trace_buf; STATIC void xfs_allocbt_trace_enter( struct xfs_btree_cur *cur, const char *func, char *s, int type, int line, __psunsigned_t a0, __psunsigned_t a1, __psunsigned_t a2, __psunsigned_t a3, __psunsigned_t a4, __psunsigned_t a5, __psunsigned_t a6, __psunsigned_t a7, __psunsigned_t a8, __psunsigned_t a9, __psunsigned_t a10) { ktrace_enter(xfs_allocbt_trace_buf, (void *)(__psint_t)type, (void *)func, (void *)s, NULL, (void *)cur, (void *)a0, (void *)a1, (void *)a2, (void *)a3, (void *)a4, (void *)a5, (void *)a6, (void *)a7, (void *)a8, (void *)a9, (void *)a10); } STATIC void xfs_allocbt_trace_cursor( struct xfs_btree_cur *cur, __uint32_t *s0, __uint64_t *l0, __uint64_t *l1) { *s0 = cur->bc_private.a.agno; *l0 = cur->bc_rec.a.ar_startblock; *l1 = cur->bc_rec.a.ar_blockcount; } STATIC void xfs_allocbt_trace_key( struct xfs_btree_cur *cur, union xfs_btree_key *key, __uint64_t *l0, __uint64_t *l1) { *l0 = be32_to_cpu(key->alloc.ar_startblock); *l1 = be32_to_cpu(key->alloc.ar_blockcount); } STATIC void xfs_allocbt_trace_record( struct xfs_btree_cur *cur, union xfs_btree_rec *rec, __uint64_t *l0, __uint64_t *l1, __uint64_t *l2) { *l0 = be32_to_cpu(rec->alloc.ar_startblock); *l1 = be32_to_cpu(rec->alloc.ar_blockcount); *l2 = 0; } #endif /* XFS_BTREE_TRACE */ static const struct xfs_btree_ops xfs_allocbt_ops = { .rec_len = sizeof(xfs_alloc_rec_t), .key_len = sizeof(xfs_alloc_key_t), .dup_cursor = xfs_allocbt_dup_cursor, .set_root = xfs_allocbt_set_root, .alloc_block = xfs_allocbt_alloc_block, .free_block = xfs_allocbt_free_block, .update_lastrec = xfs_allocbt_update_lastrec, .get_minrecs = xfs_allocbt_get_minrecs, .get_maxrecs = xfs_allocbt_get_maxrecs, .init_key_from_rec = xfs_allocbt_init_key_from_rec, .init_rec_from_key = xfs_allocbt_init_rec_from_key, .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder, #endif #ifdef XFS_BTREE_TRACE .trace_enter = xfs_allocbt_trace_enter, .trace_cursor = xfs_allocbt_trace_cursor, .trace_key = xfs_allocbt_trace_key, .trace_record = xfs_allocbt_trace_record, #endif }; /* * Allocate a new allocation btree cursor. */ struct xfs_btree_cur * /* new alloc btree cursor */ xfs_allocbt_init_cursor( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *agbp, /* buffer for agf structure */ xfs_agnumber_t agno, /* allocation group number */ xfs_btnum_t btnum) /* btree identifier */ { struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); struct xfs_btree_cur *cur; ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]); cur->bc_btnum = btnum; cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_ops = &xfs_allocbt_ops; if (btnum == XFS_BTNUM_CNT) cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; return cur; } /* * Calculate number of records in an alloc btree block. */ int xfs_allocbt_maxrecs( struct xfs_mount *mp, int blocklen, int leaf) { blocklen -= XFS_ALLOC_BLOCK_LEN(mp); if (leaf) return blocklen / sizeof(xfs_alloc_rec_t); return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t)); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_bmap.c0000664000000000000000000050070411650373061015056 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #ifdef DEBUG STATIC void xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork); #endif kmem_zone_t *xfs_bmap_free_item_zone; /* * Prototypes for internal bmap routines. */ /* * Called from xfs_bmap_add_attrfork to handle extents format files. */ STATIC int /* error */ xfs_bmap_add_attrfork_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ xfs_bmap_free_t *flist, /* blocks to free at commit */ int *flags); /* inode logging flags */ /* * Called from xfs_bmap_add_attrfork to handle local format files. */ STATIC int /* error */ xfs_bmap_add_attrfork_local( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ xfs_bmap_free_t *flist, /* blocks to free at commit */ int *flags); /* inode logging flags */ /* * Called by xfs_bmapi to update file extent records and the btree * after allocating space (or doing a delayed allocation). */ STATIC int /* error */ xfs_bmap_add_extent( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ int whichfork, /* data or attr fork */ int rsvd); /* OK to allocate reserved blocks */ /* * Called by xfs_bmap_add_extent to handle cases converting a delayed * allocation to a real allocation. */ STATIC int /* error */ xfs_bmap_add_extent_delay_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ int rsvd); /* OK to allocate reserved blocks */ /* * Called by xfs_bmap_add_extent to handle cases converting a hole * to a delayed allocation. */ STATIC int /* error */ xfs_bmap_add_extent_hole_delay( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp,/* inode logging flags */ int rsvd); /* OK to allocate reserved blocks */ /* * Called by xfs_bmap_add_extent to handle cases converting a hole * to a real allocation. */ STATIC int /* error */ xfs_bmap_add_extent_hole_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp, /* inode logging flags */ int whichfork); /* data or attr fork */ /* * Called by xfs_bmap_add_extent to handle cases converting an unwritten * allocation to a real allocation or vice versa. */ STATIC int /* error */ xfs_bmap_add_extent_unwritten_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp); /* inode logging flags */ /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int /* error */ xfs_bmap_alloc( xfs_bmalloca_t *ap); /* bmap alloc argument struct */ /* * Transform a btree format file with only one leaf node, where the * extents list will fit in the inode, into an extents format file. * Since the file extents are already in-core, all we have to do is * give up the space for the btree root and pitch the leaf block. */ STATIC int /* error */ xfs_bmap_btree_to_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_btree_cur_t *cur, /* btree cursor */ int *logflagsp, /* inode logging flags */ int whichfork); /* data or attr fork */ /* * Called by xfs_bmapi to update file extent records and the btree * after removing space (or undoing a delayed allocation). */ STATIC int /* error */ xfs_bmap_del_extent( xfs_inode_t *ip, /* incore inode pointer */ xfs_trans_t *tp, /* current trans pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_bmap_free_t *flist, /* list of extents to be freed */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp,/* inode logging flags */ int whichfork, /* data or attr fork */ int rsvd); /* OK to allocate reserved blocks */ /* * Convert an extents-format file into a btree-format file. * The new file will have a root block (in the inode) and a single child block. */ STATIC int /* error */ xfs_bmap_extents_to_btree( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first-block-allocated */ xfs_bmap_free_t *flist, /* blocks freed in xaction */ xfs_btree_cur_t **curp, /* cursor returned to caller */ int wasdel, /* converting a delayed alloc */ int *logflagsp, /* inode logging flags */ int whichfork); /* data or attr fork */ /* * Convert a local file to an extents file. * This code is sort of bogus, since the file data needs to get * logged so it won't be lost. The bmap-level manipulations are ok, though. */ STATIC int /* error */ xfs_bmap_local_to_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated in xaction */ xfs_extlen_t total, /* total blocks needed by transaction */ int *logflagsp, /* inode logging flags */ int whichfork); /* data or attr fork */ /* * Check the last inode extent to determine whether this allocation will result * in blocks being allocated at the end of the file. When we allocate new data * blocks at the end of the file which do not start at the previous data block, * we will try to align the new blocks at stripe unit boundaries. */ STATIC int /* error */ xfs_bmap_isaeof( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t off, /* file offset in fsblocks */ int whichfork, /* data or attribute fork */ char *aeof); /* return value */ /* * Compute the worst-case number of indirect blocks that will be used * for ip's delayed extent of length "len". */ STATIC xfs_filblks_t xfs_bmap_worst_indlen( xfs_inode_t *ip, /* incore inode pointer */ xfs_filblks_t len); /* delayed extent length */ #ifdef DEBUG /* * Perform various validation checks on the values being returned * from xfs_bmapi(). */ STATIC void xfs_bmap_validate_ret( xfs_fileoff_t bno, xfs_filblks_t len, int flags, xfs_bmbt_irec_t *mval, int nmap, int ret_nmap); #else #define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) #endif /* DEBUG */ STATIC int xfs_bmap_count_tree( xfs_mount_t *mp, xfs_trans_t *tp, xfs_ifork_t *ifp, xfs_fsblock_t blockno, int levelin, int *count); STATIC void xfs_bmap_count_leaves( xfs_ifork_t *ifp, xfs_extnum_t idx, int numrecs, int *count); STATIC void xfs_bmap_disk_count_leaves( struct xfs_mount *mp, struct xfs_btree_block *block, int numrecs, int *count); /* * Bmap internal routines. */ STATIC int /* error */ xfs_bmbt_lookup_eq( struct xfs_btree_cur *cur, xfs_fileoff_t off, xfs_fsblock_t bno, xfs_filblks_t len, int *stat) /* success/failure */ { cur->bc_rec.b.br_startoff = off; cur->bc_rec.b.br_startblock = bno; cur->bc_rec.b.br_blockcount = len; return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); } STATIC int /* error */ xfs_bmbt_lookup_ge( struct xfs_btree_cur *cur, xfs_fileoff_t off, xfs_fsblock_t bno, xfs_filblks_t len, int *stat) /* success/failure */ { cur->bc_rec.b.br_startoff = off; cur->bc_rec.b.br_startblock = bno; cur->bc_rec.b.br_blockcount = len; return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); } /* * Update the record referred to by cur to the value given * by [off, bno, len, state]. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int xfs_bmbt_update( struct xfs_btree_cur *cur, xfs_fileoff_t off, xfs_fsblock_t bno, xfs_filblks_t len, xfs_exntst_t state) { union xfs_btree_rec rec; xfs_bmbt_disk_set_allf(&rec.bmbt, off, bno, len, state); return xfs_btree_update(cur, &rec); } /* * Called from xfs_bmap_add_attrfork to handle btree format files. */ STATIC int /* error */ xfs_bmap_add_attrfork_btree( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ xfs_bmap_free_t *flist, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ int error; /* error return value */ xfs_mount_t *mp; /* file system mount struct */ int stat; /* newroot status */ mp = ip->i_mount; if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); cur->bc_private.b.flist = flist; cur->bc_private.b.firstblock = *firstblock; if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) goto error0; /* must be at least one entry */ XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); if ((error = xfs_btree_new_iroot(cur, flags, &stat))) goto error0; if (stat == 0) { xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return XFS_ERROR(ENOSPC); } *firstblock = cur->bc_private.b.firstblock; cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); } return 0; error0: xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } /* * Called from xfs_bmap_add_attrfork to handle extents format files. */ STATIC int /* error */ xfs_bmap_add_attrfork_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ xfs_bmap_free_t *flist, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* bmap btree cursor */ int error; /* error return value */ if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, flags, XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); } return error; } /* * Called from xfs_bmap_add_attrfork to handle local format files. */ STATIC int /* error */ xfs_bmap_add_attrfork_local( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ xfs_bmap_free_t *flist, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_da_args_t dargs; /* args for dir/attr code */ int error; /* error return value */ xfs_mount_t *mp; /* mount structure pointer */ if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) return 0; if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { mp = ip->i_mount; memset(&dargs, 0, sizeof(dargs)); dargs.dp = ip; dargs.firstblock = firstblock; dargs.flist = flist; dargs.total = mp->m_dirblkfsbs; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; error = xfs_dir2_sf_to_block(&dargs); } else error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, XFS_DATA_FORK); return error; } /* * Called by xfs_bmapi to update file extent records and the btree * after allocating space (or doing a delayed allocation). */ STATIC int /* error */ xfs_bmap_add_extent( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ int whichfork, /* data or attr fork */ int rsvd) /* OK to use reserved data blocks */ { xfs_btree_cur_t *cur; /* btree cursor or null */ xfs_filblks_t da_new; /* new count del alloc blocks used */ xfs_filblks_t da_old; /* old count del alloc blocks used */ int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork ptr */ int logflags; /* returned value */ xfs_extnum_t nextents; /* number of extents in file now */ XFS_STATS_INC(xs_add_exlist); cur = *curp; ifp = XFS_IFORK_PTR(ip, whichfork); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ASSERT(idx <= nextents); da_old = da_new = 0; error = 0; /* * This is the first extent added to a new/empty file. * Special case this one, so other routines get to assume there are * already extents in the list. */ if (nextents == 0) { xfs_iext_insert(ip, 0, 1, new, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); ASSERT(cur == NULL); ifp->if_lastex = 0; if (!isnullstartblock(new->br_startblock)) { XFS_IFORK_NEXT_SET(ip, whichfork, 1); logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else logflags = 0; } /* * Any kind of new delayed allocation goes here. */ else if (isnullstartblock(new->br_startblock)) { if (cur) ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, &logflags, rsvd))) goto done; } /* * Real allocation off the end of the file. */ else if (idx == nextents) { if (cur) ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, &logflags, whichfork))) goto done; } else { xfs_bmbt_irec_t prev; /* old extent at offset idx */ /* * Get the record referred to by idx. */ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); /* * If it's a real allocation record, and the new allocation ends * after the start of the referred to record, then we're filling * in a delayed or unwritten allocation with a real one, or * converting real back to unwritten. */ if (!isnullstartblock(new->br_startblock) && new->br_startoff + new->br_blockcount > prev.br_startoff) { if (prev.br_state != XFS_EXT_UNWRITTEN && isnullstartblock(prev.br_startblock)) { da_old = startblockval(prev.br_startblock); if (cur) ASSERT(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL); if ((error = xfs_bmap_add_extent_delay_real(ip, idx, &cur, new, &da_new, first, flist, &logflags, rsvd))) goto done; } else if (new->br_state == XFS_EXT_NORM) { ASSERT(new->br_state == XFS_EXT_NORM); if ((error = xfs_bmap_add_extent_unwritten_real( ip, idx, &cur, new, &logflags))) goto done; } else { ASSERT(new->br_state == XFS_EXT_UNWRITTEN); if ((error = xfs_bmap_add_extent_unwritten_real( ip, idx, &cur, new, &logflags))) goto done; } ASSERT(*curp == cur || *curp == NULL); } /* * Otherwise we're filling in a hole with an allocation. */ else { if (cur) ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, &logflags, whichfork))) goto done; } } ASSERT(*curp == cur || *curp == NULL); /* * Convert to a btree if necessary. */ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, flist, &cur, da_old > 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto done; } /* * Adjust for changes in reserved delayed indirect blocks. * Nothing to do for disk quotas here. */ if (da_old || da_new) { xfs_filblks_t nblks; nblks = da_new; if (cur) nblks += cur->bc_private.b.allocated; ASSERT(nblks <= da_old); if (nblks < da_old) xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, (int64_t)(da_old - nblks), rsvd); } /* * Clear out the allocated field, done with it now in any case. */ if (cur) { cur->bc_private.b.allocated = 0; *curp = cur; } done: #ifdef DEBUG if (!error) xfs_bmap_check_leaf_extents(*curp, ip, whichfork); #endif *logflagsp = logflags; return error; } /* * Called by xfs_bmap_add_extent to handle cases converting a delayed * allocation to a real allocation. */ STATIC int /* error */ xfs_bmap_add_extent_delay_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ int *logflagsp, /* inode logging flags */ int rsvd) /* OK to use reserved data block allocation */ { xfs_btree_cur_t *cur; /* btree cursor */ int diff; /* temp value */ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ int error; /* error return value */ int i; /* temp state */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ int rval=0; /* return value (logging flags) */ int state = 0;/* state bits, accessed thru macros */ xfs_filblks_t temp=0; /* value for dnew calculations */ xfs_filblks_t temp2=0;/* value for dnew calculations */ int tmp_rval; /* partial logging flags */ #define LEFT r[0] #define RIGHT r[1] #define PREV r[2] /* * Set up a bunch of variables to make the tests simpler. */ cur = *curp; ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &PREV); new_endoff = new->br_startoff + new->br_blockcount; ASSERT(PREV.br_startoff <= new->br_startoff); ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); /* * Set flags determining what part of the previous delayed allocation * extent is being replaced by a real allocation. */ if (PREV.br_startoff == new->br_startoff) state |= BMAP_LEFT_FILLING; if (PREV.br_startoff + PREV.br_blockcount == new_endoff) state |= BMAP_RIGHT_FILLING; /* * Check and set flags if this segment has a left neighbor. * Don't set contiguous if the combined extent would be too large. */ if (idx > 0) { state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); if (isnullstartblock(LEFT.br_startblock)) state |= BMAP_LEFT_DELAY; } if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && LEFT.br_state == new->br_state && LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) state |= BMAP_LEFT_CONTIG; /* * Check and set flags if this segment has a right neighbor. * Don't set contiguous if the combined extent would be too large. * Also check for all-three-contiguous being too large. */ if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); if (isnullstartblock(RIGHT.br_startblock)) state |= BMAP_RIGHT_DELAY; } if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && new_endoff == RIGHT.br_startoff && new->br_startblock + new->br_blockcount == RIGHT.br_startblock && new->br_state == RIGHT.br_state && new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) != (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING) || LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN)) state |= BMAP_RIGHT_CONTIG; error = 0; /* * Switch out based on the FILLING and CONTIG state bits. */ switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The left and right neighbors are both contiguous with new. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount, LEFT.br_state))) goto done; } *dnew = 0; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The left neighbor is contiguous, the right is not. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); ip->i_df.if_lastex = idx - 1; xfs_iext_remove(ip, idx, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount, LEFT.br_state))) goto done; } *dnew = 0; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The right neighbor is contiguous, the left is not. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; xfs_iext_remove(ip, idx + 1, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, new->br_startblock, PREV.br_blockcount + RIGHT.br_blockcount, PREV.br_state))) goto done; } *dnew = 0; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: /* * Filling in all of a previously delayed allocation extent. * Neither the left nor right neighbors are contiguous with * the new one. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } *dnew = 0; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: /* * Filling in the first part of a previous delayed allocation. * The left neighbor is contiguous. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); temp = PREV.br_blockcount - new->br_blockcount; trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); ip->i_df.if_lastex = idx - 1; if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + new->br_blockcount, LEFT.br_state))) goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; break; case BMAP_LEFT_FILLING: /* * Filling in the first part of a previous delayed allocation. * The left neighbor is not contiguous. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startoff(ep, new_endoff); temp = PREV.br_blockcount - new->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; if (error) goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx + 1); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); *dnew = temp; break; case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in the last part of a previous delayed allocation. * The right neighbor is contiguous with the new allocation. */ temp = PREV.br_blockcount - new->br_blockcount; trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, RIGHT.br_state); trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); ip->i_df.if_lastex = idx + 1; if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, RIGHT.br_state))) goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; break; case BMAP_RIGHT_FILLING: /* * Filling in the last part of a previous delayed allocation. * The right neighbor is not contiguous. */ temp = PREV.br_blockcount - new->br_blockcount; trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; if (error) goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; break; case 0: /* * Filling in the middle part of a previous delayed allocation. * Contiguity is impossible here. * This case is avoided almost all the time. */ temp = new->br_startoff - PREV.br_startoff; trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); r[0] = *new; r[1].br_state = PREV.br_state; r[1].br_startblock = 0; r[1].br_startoff = new_endoff; temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_blockcount = temp2; xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; if (error) goto done; } temp = xfs_bmap_worst_indlen(ip, temp); temp2 = xfs_bmap_worst_indlen(ip, temp2); diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); if (diff > 0 && xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) { /* * Ick gross gag me with a spoon. */ ASSERT(0); /* want to see if this ever happens! */ while (diff > 0) { if (temp) { temp--; diff--; if (!diff || !xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } if (temp2) { temp2--; diff--; if (!diff || !xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } } } ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), nullstartblock((int)temp2)); trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); *dnew = temp + temp2; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_LEFT_CONTIG: case BMAP_RIGHT_CONTIG: /* * These cases are all impossible. */ ASSERT(0); } *curp = cur; done: *logflagsp = rval; return error; #undef LEFT #undef RIGHT #undef PREV } /* * Called by xfs_bmap_add_extent to handle cases converting an unwritten * allocation to a real allocation or vice versa. */ STATIC int /* error */ xfs_bmap_add_extent_unwritten_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ int error; /* error return value */ int i; /* temp state */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_exntst_t newext; /* new extent state */ xfs_exntst_t oldext; /* old extent state */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ int rval=0; /* return value (logging flags) */ int state = 0;/* state bits, accessed thru macros */ #define LEFT r[0] #define RIGHT r[1] #define PREV r[2] /* * Set up a bunch of variables to make the tests simpler. */ error = 0; cur = *curp; ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &PREV); newext = new->br_state; oldext = (newext == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; ASSERT(PREV.br_state == oldext); new_endoff = new->br_startoff + new->br_blockcount; ASSERT(PREV.br_startoff <= new->br_startoff); ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); /* * Set flags determining what part of the previous oldext allocation * extent is being replaced by a newext allocation. */ if (PREV.br_startoff == new->br_startoff) state |= BMAP_LEFT_FILLING; if (PREV.br_startoff + PREV.br_blockcount == new_endoff) state |= BMAP_RIGHT_FILLING; /* * Check and set flags if this segment has a left neighbor. * Don't set contiguous if the combined extent would be too large. */ if (idx > 0) { state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); if (isnullstartblock(LEFT.br_startblock)) state |= BMAP_LEFT_DELAY; } if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && LEFT.br_state == newext && LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) state |= BMAP_LEFT_CONTIG; /* * Check and set flags if this segment has a right neighbor. * Don't set contiguous if the combined extent would be too large. * Also check for all-three-contiguous being too large. */ if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); if (isnullstartblock(RIGHT.br_startblock)) state |= BMAP_RIGHT_DELAY; } if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && new_endoff == RIGHT.br_startoff && new->br_startblock + new->br_blockcount == RIGHT.br_startblock && newext == RIGHT.br_state && new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) != (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING) || LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN)) state |= BMAP_RIGHT_CONTIG; /* * Switch out based on the FILLING and CONTIG state bits. */ switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The left and right neighbors are both contiguous with new. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents -= 2; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount, LEFT.br_state))) goto done; } break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The left neighbor is contiguous, the right is not. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); ip->i_df.if_lastex = idx - 1; xfs_iext_remove(ip, idx, 1, state); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + PREV.br_blockcount, LEFT.br_state))) goto done; } break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The right neighbor is contiguous, the left is not. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); xfs_bmbt_set_state(ep, newext); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; xfs_iext_remove(ip, idx + 1, 1, state); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, RIGHT.br_startblock, RIGHT.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext))) goto done; } break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: /* * Setting all of a previous oldext extent to newext. * Neither the left nor right neighbors are contiguous with * the new one. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_state(ep, newext); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount, newext))) goto done; } break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: /* * Setting the first part of a previous oldext extent to newext. * The left neighbor is contiguous. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx - 1; if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff + new->br_blockcount, PREV.br_startblock + new->br_blockcount, PREV.br_blockcount - new->br_blockcount, oldext))) goto done; if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; if (xfs_bmbt_update(cur, LEFT.br_startoff, LEFT.br_startblock, LEFT.br_blockcount + new->br_blockcount, LEFT.br_state)) goto done; } break; case BMAP_LEFT_FILLING: /* * Setting the first part of a previous oldext extent to newext. * The left neighbor is not contiguous. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); xfs_bmbt_set_startoff(ep, new_endoff); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff + new->br_blockcount, PREV.br_startblock + new->br_blockcount, PREV.br_blockcount - new->br_blockcount, oldext))) goto done; cur->bc_rec.b = *new; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } break; case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting the last part of a previous oldext extent to newext. * The right neighbor is contiguous with the new allocation. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext); trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); ip->i_df.if_lastex = idx + 1; if (cur == NULL) rval = XFS_ILOG_DEXT; else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount - new->br_blockcount, oldext))) goto done; if ((error = xfs_btree_increment(cur, 0, &i))) goto done; if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext))) goto done; } break; case BMAP_RIGHT_FILLING: /* * Setting the last part of a previous oldext extent to newext. * The right neighbor is not contiguous. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount - new->br_blockcount, oldext))) goto done; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = XFS_EXT_NORM; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } break; case 0: /* * Setting the middle part of a previous oldext extent to * newext. Contiguity is impossible here. * One extent becomes three extents. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, new->br_startoff - PREV.br_startoff); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); r[0] = *new; r[1].br_startoff = new_endoff; r[1].br_blockcount = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_startblock = new->br_startblock + new->br_blockcount; r[1].br_state = oldext; xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents += 2; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, PREV.br_startblock, PREV.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); /* new right extent - oldext */ if ((error = xfs_bmbt_update(cur, r[1].br_startoff, r[1].br_startblock, r[1].br_blockcount, r[1].br_state))) goto done; /* new left extent - oldext */ cur->bc_rec.b = PREV; cur->bc_rec.b.br_blockcount = new->br_startoff - PREV.br_startoff; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); /* * Reset the cursor to the position of the new extent * we are about to insert as we can't trust it after * the previous insert. */ if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); /* new middle extent - newext */ cur->bc_rec.b.br_state = new->br_state; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: case BMAP_LEFT_CONTIG: case BMAP_RIGHT_CONTIG: /* * These cases are all impossible. */ ASSERT(0); } *curp = cur; done: *logflagsp = rval; return error; #undef LEFT #undef RIGHT #undef PREV } /* * Called by xfs_bmap_add_extent to handle cases converting a hole * to a delayed allocation. */ /*ARGSUSED*/ STATIC int /* error */ xfs_bmap_add_extent_hole_delay( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp, /* inode logging flags */ int rsvd) /* OK to allocate reserved blocks */ { xfs_bmbt_rec_host_t *ep; /* extent record for idx */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_irec_t left; /* left neighbor extent entry */ xfs_filblks_t newlen=0; /* new indirect size */ xfs_filblks_t oldlen=0; /* old indirect size */ xfs_bmbt_irec_t right; /* right neighbor extent entry */ int state; /* state bits, accessed thru macros */ xfs_filblks_t temp=0; /* temp for indirect calculations */ ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); ep = xfs_iext_get_ext(ifp, idx); state = 0; ASSERT(isnullstartblock(new->br_startblock)); /* * Check and set flags if this segment has a left neighbor */ if (idx > 0) { state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); if (isnullstartblock(left.br_startblock)) state |= BMAP_LEFT_DELAY; } /* * Check and set flags if the current (right) segment exists. * If it doesn't exist, we're converting the hole at end-of-file. */ if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(ep, &right); if (isnullstartblock(right.br_startblock)) state |= BMAP_RIGHT_DELAY; } /* * Set contiguity flags on the left and right neighbors. * Don't let extents get too large, even if the pieces are contiguous. */ if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && left.br_startoff + left.br_blockcount == new->br_startoff && left.br_blockcount + new->br_blockcount <= MAXEXTLEN) state |= BMAP_LEFT_CONTIG; if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && new->br_startoff + new->br_blockcount == right.br_startoff && new->br_blockcount + right.br_blockcount <= MAXEXTLEN && (!(state & BMAP_LEFT_CONTIG) || (left.br_blockcount + new->br_blockcount + right.br_blockcount <= MAXEXTLEN))) state |= BMAP_RIGHT_CONTIG; /* * Switch out based on the contiguity flags. */ switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with delayed allocations * on the left and on the right. * Merge all three into a single extent record. */ temp = left.br_blockcount + new->br_blockcount + right.br_blockcount; trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = startblockval(left.br_startblock) + startblockval(new->br_startblock) + startblockval(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), nullstartblock((int)newlen)); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); xfs_iext_remove(ip, idx, 1, state); ip->i_df.if_lastex = idx - 1; break; case BMAP_LEFT_CONTIG: /* * New allocation is contiguous with a delayed allocation * on the left. * Merge the new allocation with the left neighbor. */ temp = left.br_blockcount + new->br_blockcount; trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = startblockval(left.br_startblock) + startblockval(new->br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), nullstartblock((int)newlen)); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); ip->i_df.if_lastex = idx - 1; break; case BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with a delayed allocation * on the right. * Merge the new allocation with the right neighbor. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); temp = new->br_blockcount + right.br_blockcount; oldlen = startblockval(new->br_startblock) + startblockval(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_allf(ep, new->br_startoff, nullstartblock((int)newlen), temp, right.br_state); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; break; case 0: /* * New allocation is not contiguous with another * delayed allocation. * Insert a new entry. */ oldlen = newlen = 0; xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; break; } if (oldlen != newlen) { ASSERT(oldlen > newlen); xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, (int64_t)(oldlen - newlen), rsvd); /* * Nothing to do for disk quota accounting here. */ } *logflagsp = 0; return 0; } /* * Called by xfs_bmap_add_extent to handle cases converting a hole * to a real allocation. */ STATIC int /* error */ xfs_bmap_add_extent_hole_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* extent number to update/insert */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ int *logflagsp, /* inode logging flags */ int whichfork) /* data or attr fork */ { xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ int error; /* error return value */ int i; /* temp state */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_irec_t left; /* left neighbor extent entry */ xfs_bmbt_irec_t right; /* right neighbor extent entry */ int rval=0; /* return value (logging flags) */ int state; /* state bits, accessed thru macros */ ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); ep = xfs_iext_get_ext(ifp, idx); state = 0; if (whichfork == XFS_ATTR_FORK) state |= BMAP_ATTRFORK; /* * Check and set flags if this segment has a left neighbor. */ if (idx > 0) { state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); if (isnullstartblock(left.br_startblock)) state |= BMAP_LEFT_DELAY; } /* * Check and set flags if this segment has a current value. * Not true if we're inserting into the "hole" at eof. */ if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(ep, &right); if (isnullstartblock(right.br_startblock)) state |= BMAP_RIGHT_DELAY; } /* * We're inserting a real allocation between "left" and "right". * Set the contiguity flags. Don't let extents get too large. */ if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && left.br_startoff + left.br_blockcount == new->br_startoff && left.br_startblock + left.br_blockcount == new->br_startblock && left.br_state == new->br_state && left.br_blockcount + new->br_blockcount <= MAXEXTLEN) state |= BMAP_LEFT_CONTIG; if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && new->br_startoff + new->br_blockcount == right.br_startoff && new->br_startblock + new->br_blockcount == right.br_startblock && new->br_state == right.br_state && new->br_blockcount + right.br_blockcount <= MAXEXTLEN && (!(state & BMAP_LEFT_CONTIG) || left.br_blockcount + new->br_blockcount + right.br_blockcount <= MAXEXTLEN)) state |= BMAP_RIGHT_CONTIG; error = 0; /* * Select which case we're in here, and implement it. */ switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with real allocations on the * left and on the right. * Merge all three into a single extent record. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount + right.br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); xfs_iext_remove(ip, idx, 1, state); ifp->if_lastex = idx - 1; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); if (cur == NULL) { rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, right.br_startblock, right.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, left.br_blockcount + new->br_blockcount + right.br_blockcount, left.br_state))) goto done; } break; case BMAP_LEFT_CONTIG: /* * New allocation is contiguous with a real allocation * on the left. * Merge the new allocation with the left neighbor. */ trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount); trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); ifp->if_lastex = idx - 1; if (cur == NULL) { rval = xfs_ilog_fext(whichfork); } else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, left.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, left.br_blockcount + new->br_blockcount, left.br_state))) goto done; } break; case BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with a real allocation * on the right. * Merge the new allocation with the right neighbor. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, new->br_blockcount + right.br_blockcount, right.br_state); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ifp->if_lastex = idx; if (cur == NULL) { rval = xfs_ilog_fext(whichfork); } else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, right.br_startblock, right.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); if ((error = xfs_bmbt_update(cur, new->br_startoff, new->br_startblock, new->br_blockcount + right.br_blockcount, right.br_state))) goto done; } break; case 0: /* * New allocation is not contiguous with another * real allocation. * Insert a new entry. */ xfs_iext_insert(ip, idx, 1, new, state); ifp->if_lastex = idx; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); if (cur == NULL) { rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, new->br_startblock, new->br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 0, done); cur->bc_rec.b.br_state = new->br_state; if ((error = xfs_btree_insert(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } break; } done: *logflagsp = rval; return error; } /* * Adjust the size of the new extent based on di_extsize and rt extsize. */ STATIC int xfs_bmap_extsize_align( xfs_mount_t *mp, xfs_bmbt_irec_t *gotp, /* next extent pointer */ xfs_bmbt_irec_t *prevp, /* previous extent pointer */ xfs_extlen_t extsz, /* align to this extent size */ int rt, /* is this a realtime inode? */ int eof, /* is extent at end-of-file? */ int delay, /* creating delalloc extent? */ int convert, /* overwriting unwritten extent? */ xfs_fileoff_t *offp, /* in/out: aligned offset */ xfs_extlen_t *lenp) /* in/out: aligned length */ { xfs_fileoff_t orig_off; /* original offset */ xfs_extlen_t orig_alen; /* original length */ xfs_fileoff_t orig_end; /* original off+len */ xfs_fileoff_t nexto; /* next file offset */ xfs_fileoff_t prevo; /* previous file offset */ xfs_fileoff_t align_off; /* temp for offset */ xfs_extlen_t align_alen; /* temp for length */ xfs_extlen_t temp; /* temp for calculations */ if (convert) return 0; orig_off = align_off = *offp; orig_alen = align_alen = *lenp; orig_end = orig_off + orig_alen; /* * If this request overlaps an existing extent, then don't * attempt to perform any additional alignment. */ if (!delay && !eof && (orig_off >= gotp->br_startoff) && (orig_end <= gotp->br_startoff + gotp->br_blockcount)) { return 0; } /* * If the file offset is unaligned vs. the extent size * we need to align it. This will be possible unless * the file was previously written with a kernel that didn't * perform this alignment, or if a truncate shot us in the * foot. */ temp = do_mod(orig_off, extsz); if (temp) { align_alen += temp; align_off -= temp; } /* * Same adjustment for the end of the requested area. */ if ((temp = (align_alen % extsz))) { align_alen += extsz - temp; } /* * If the previous block overlaps with this proposed allocation * then move the start forward without adjusting the length. */ if (prevp->br_startoff != NULLFILEOFF) { if (prevp->br_startblock == HOLESTARTBLOCK) prevo = prevp->br_startoff; else prevo = prevp->br_startoff + prevp->br_blockcount; } else prevo = 0; if (align_off != orig_off && align_off < prevo) align_off = prevo; /* * If the next block overlaps with this proposed allocation * then move the start back without adjusting the length, * but not before offset 0. * This may of course make the start overlap previous block, * and if we hit the offset 0 limit then the next block * can still overlap too. */ if (!eof && gotp->br_startoff != NULLFILEOFF) { if ((delay && gotp->br_startblock == HOLESTARTBLOCK) || (!delay && gotp->br_startblock == DELAYSTARTBLOCK)) nexto = gotp->br_startoff + gotp->br_blockcount; else nexto = gotp->br_startoff; } else nexto = NULLFILEOFF; if (!eof && align_off + align_alen != orig_end && align_off + align_alen > nexto) align_off = nexto > align_alen ? nexto - align_alen : 0; /* * If we're now overlapping the next or previous extent that * means we can't fit an extsz piece in this hole. Just move * the start forward to the first valid spot and set * the length so we hit the end. */ if (align_off != orig_off && align_off < prevo) align_off = prevo; if (align_off + align_alen != orig_end && align_off + align_alen > nexto && nexto != NULLFILEOFF) { ASSERT(nexto > prevo); align_alen = nexto - align_off; } /* * If realtime, and the result isn't a multiple of the realtime * extent size we need to remove blocks until it is. */ if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { /* * We're not covering the original request, or * we won't be able to once we fix the length. */ if (orig_off < align_off || orig_end > align_off + align_alen || align_alen - temp < orig_alen) return XFS_ERROR(EINVAL); /* * Try to fix it by moving the start up. */ if (align_off + temp <= orig_off) { align_alen -= temp; align_off += temp; } /* * Try to fix it by moving the end in. */ else if (align_off + align_alen - temp >= orig_end) align_alen -= temp; /* * Set the start to the minimum then trim the length. */ else { align_alen -= orig_off - align_off; align_off = orig_off; align_alen -= align_alen % mp->m_sb.sb_rextsize; } /* * Result doesn't cover the request, fail it. */ if (orig_off < align_off || orig_end > align_off + align_alen) return XFS_ERROR(EINVAL); } else { ASSERT(orig_off >= align_off); ASSERT(orig_end <= align_off + align_alen); } #ifdef DEBUG if (!eof && gotp->br_startoff != NULLFILEOFF) ASSERT(align_off + align_alen <= gotp->br_startoff); if (prevp->br_startoff != NULLFILEOFF) ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount); #endif *lenp = align_alen; *offp = align_off; return 0; } #define XFS_ALLOC_GAP_UNITS 4 STATIC void xfs_bmap_adjacent( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_fsblock_t adjust; /* adjustment to block numbers */ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_mount_t *mp; /* mount point structure */ int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ #define ISVALID(x,y) \ (rt ? \ (x) < mp->m_sb.sb_rblocks : \ XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) mp = ap->ip->i_mount; nullfb = ap->firstblock == NULLFSBLOCK; rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); /* * If allocating at eof, and there's a previous real block, * try to use its last block as our starting point. */ if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF && !isnullstartblock(ap->prevp->br_startblock) && ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount, ap->prevp->br_startblock)) { ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount; /* * Adjust for the gap between prevp and us. */ adjust = ap->off - (ap->prevp->br_startoff + ap->prevp->br_blockcount); if (adjust && ISVALID(ap->rval + adjust, ap->prevp->br_startblock)) ap->rval += adjust; } /* * If not at eof, then compare the two neighbor blocks. * Figure out whether either one gives us a good starting point, * and pick the better one. */ else if (!ap->eof) { xfs_fsblock_t gotbno; /* right side block number */ xfs_fsblock_t gotdiff=0; /* right side difference */ xfs_fsblock_t prevbno; /* left side block number */ xfs_fsblock_t prevdiff=0; /* left side difference */ /* * If there's a previous (left) block, select a requested * start block based on it. */ if (ap->prevp->br_startoff != NULLFILEOFF && !isnullstartblock(ap->prevp->br_startblock) && (prevbno = ap->prevp->br_startblock + ap->prevp->br_blockcount) && ISVALID(prevbno, ap->prevp->br_startblock)) { /* * Calculate gap to end of previous block. */ adjust = prevdiff = ap->off - (ap->prevp->br_startoff + ap->prevp->br_blockcount); /* * Figure the startblock based on the previous block's * end and the gap size. * Heuristic! * If the gap is large relative to the piece we're * allocating, or using it gives us an invalid block * number, then just use the end of the previous block. */ if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && ISVALID(prevbno + prevdiff, ap->prevp->br_startblock)) prevbno += adjust; else prevdiff += adjust; /* * If the firstblock forbids it, can't use it, * must use default. */ if (!rt && !nullfb && XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) prevbno = NULLFSBLOCK; } /* * No previous block or can't follow it, just default. */ else prevbno = NULLFSBLOCK; /* * If there's a following (right) block, select a requested * start block based on it. */ if (!isnullstartblock(ap->gotp->br_startblock)) { /* * Calculate gap to start of next block. */ adjust = gotdiff = ap->gotp->br_startoff - ap->off; /* * Figure the startblock based on the next block's * start and the gap size. */ gotbno = ap->gotp->br_startblock; /* * Heuristic! * If the gap is large relative to the piece we're * allocating, or using it gives us an invalid block * number, then just use the start of the next block * offset by our length. */ if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && ISVALID(gotbno - gotdiff, gotbno)) gotbno -= adjust; else if (ISVALID(gotbno - ap->alen, gotbno)) { gotbno -= ap->alen; gotdiff += adjust - ap->alen; } else gotdiff += adjust; /* * If the firstblock forbids it, can't use it, * must use default. */ if (!rt && !nullfb && XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) gotbno = NULLFSBLOCK; } /* * No next block, just default. */ else gotbno = NULLFSBLOCK; /* * If both valid, pick the better one, else the only good * one, else ap->rval is already set (to 0 or the inode block). */ if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) ap->rval = prevdiff <= gotdiff ? prevbno : gotbno; else if (prevbno != NULLFSBLOCK) ap->rval = prevbno; else if (gotbno != NULLFSBLOCK) ap->rval = gotbno; } #undef ISVALID } STATIC int xfs_bmap_btalloc_nullfb( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args, xfs_extlen_t *blen) { struct xfs_mount *mp = ap->ip->i_mount; struct xfs_perag *pag; xfs_agnumber_t ag, startag; int notinit = 0; int error; if (ap->userdata && xfs_inode_is_filestream(ap->ip)) args->type = XFS_ALLOCTYPE_NEAR_BNO; else args->type = XFS_ALLOCTYPE_START_BNO; args->total = ap->total; /* * Search for an allocation group with a single extent large enough * for the request. If one isn't found, then adjust the minimum * allocation size to the largest space found. */ startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); if (startag == NULLAGNUMBER) startag = ag = 0; pag = xfs_perag_get(mp, ag); while (*blen < ap->alen) { if (!pag->pagf_init) { error = xfs_alloc_pagf_init(mp, args->tp, ag, XFS_ALLOC_FLAG_TRYLOCK); if (error) { xfs_perag_put(pag); return error; } } /* * See xfs_alloc_fix_freelist... */ if (pag->pagf_init) { xfs_extlen_t longest; longest = xfs_alloc_longest_free_extent(mp, pag); if (*blen < longest) *blen = longest; } else notinit = 1; if (xfs_inode_is_filestream(ap->ip)) { if (*blen >= ap->alen) break; if (ap->userdata) { /* * If startag is an invalid AG, we've * come here once before and * xfs_filestream_new_ag picked the * best currently available. * * Don't continue looping, since we * could loop forever. */ if (startag == NULLAGNUMBER) break; error = xfs_filestream_new_ag(ap, &ag); xfs_perag_put(pag); if (error) return error; /* loop again to set 'blen'*/ startag = NULLAGNUMBER; pag = xfs_perag_get(mp, ag); continue; } } if (++ag == mp->m_sb.sb_agcount) ag = 0; if (ag == startag) break; xfs_perag_put(pag); pag = xfs_perag_get(mp, ag); } xfs_perag_put(pag); /* * Since the above loop did a BUF_TRYLOCK, it is * possible that there is space for this request. */ if (notinit || *blen < ap->minlen) args->minlen = ap->minlen; /* * If the best seen length is less than the request * length, use the best as the minimum. */ else if (*blen < ap->alen) args->minlen = *blen; /* * Otherwise we've seen an extent as big as alen, * use that as the minimum. */ else args->minlen = ap->alen; /* * set the failure fallback case to look in the selected * AG as the stream may have moved. */ if (xfs_inode_is_filestream(ap->ip)) ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); return 0; } STATIC int xfs_bmap_btalloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_mount_t *mp; /* mount point structure */ xfs_alloctype_t atype = 0; /* type for allocation routines */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_agnumber_t ag; xfs_alloc_arg_t args; xfs_extlen_t blen; xfs_extlen_t nextminlen = 0; int nullfb; /* true if ap->firstblock isn't set */ int isaligned; int tryagain; int error; mp = ap->ip->i_mount; align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; if (unlikely(align)) { error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, 0, ap->eof, 0, ap->conv, &ap->off, &ap->alen); ASSERT(!error); ASSERT(ap->alen); } nullfb = ap->firstblock == NULLFSBLOCK; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); if (nullfb) { if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { ag = xfs_filestream_lookup_ag(ap->ip); ag = (ag != NULLAGNUMBER) ? ag : 0; ap->rval = XFS_AGB_TO_FSB(mp, ag, 0); } else { ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } } else ap->rval = ap->firstblock; xfs_bmap_adjacent(ap); /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. */ if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; /* * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; args.tp = ap->tp; args.mp = mp; args.fsbno = ap->rval; args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); args.firstblock = ap->firstblock; blen = 0; if (nullfb) { error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); if (error) return error; } else if (ap->low) { if (xfs_inode_is_filestream(ap->ip)) args.type = XFS_ALLOCTYPE_FIRST_AG; else args.type = XFS_ALLOCTYPE_START_BNO; args.total = args.minlen = ap->minlen; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.total = ap->total; args.minlen = ap->minlen; } /* apply extent size hints if obtained earlier */ if (unlikely(align)) { args.prod = align; if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) args.mod = (xfs_extlen_t)(args.prod - args.mod); } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { args.prod = 1; args.mod = 0; } else { args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) args.mod = (xfs_extlen_t)(args.prod - args.mod); } /* * If we are not low on available data blocks, and the * underlying logical volume manager is a stripe, and * the file offset is zero then try to allocate data * blocks on stripe unit boundary. * NOTE: ap->aeof is only set if the allocation length * is >= the stripe unit and the allocation offset is * at the end of file. */ if (!ap->low && ap->aeof) { if (!ap->off) { args.alignment = mp->m_dalign; atype = args.type; isaligned = 1; /* * Adjust for alignment */ if (blen > args.alignment && blen <= ap->alen) args.minlen = blen - args.alignment; args.minalignslop = 0; } else { /* * First try an exact bno allocation. * If it fails then do a near or start bno * allocation with alignment turned on. */ atype = args.type; tryagain = 1; args.type = XFS_ALLOCTYPE_THIS_BNO; args.alignment = 1; /* * Compute the minlen+alignment for the * next case. Set slop so that the value * of minlen+alignment+slop doesn't go up * between the calls. */ if (blen > mp->m_dalign && blen <= ap->alen) nextminlen = blen - mp->m_dalign; else nextminlen = args.minlen; if (nextminlen + mp->m_dalign > args.minlen + 1) args.minalignslop = nextminlen + mp->m_dalign - args.minlen - 1; else args.minalignslop = 0; } } else { args.alignment = 1; args.minalignslop = 0; } args.minleft = ap->minleft; args.wasdel = ap->wasdel; args.isfl = 0; args.userdata = ap->userdata; if ((error = xfs_alloc_vextent(&args))) return error; if (tryagain && args.fsbno == NULLFSBLOCK) { /* * Exact allocation failed. Now try with alignment * turned on. */ args.type = atype; args.fsbno = ap->rval; args.alignment = mp->m_dalign; args.minlen = nextminlen; args.minalignslop = 0; isaligned = 1; if ((error = xfs_alloc_vextent(&args))) return error; } if (isaligned && args.fsbno == NULLFSBLOCK) { /* * allocation failed, so turn off alignment and * try again. */ args.type = atype; args.fsbno = ap->rval; args.alignment = 0; if ((error = xfs_alloc_vextent(&args))) return error; } if (args.fsbno == NULLFSBLOCK && nullfb && args.minlen > ap->minlen) { args.minlen = ap->minlen; args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = ap->rval; if ((error = xfs_alloc_vextent(&args))) return error; } if (args.fsbno == NULLFSBLOCK && nullfb) { args.fsbno = 0; args.type = XFS_ALLOCTYPE_FIRST_AG; args.total = ap->minlen; args.minleft = 0; if ((error = xfs_alloc_vextent(&args))) return error; ap->low = 1; } if (args.fsbno != NULLFSBLOCK) { ap->firstblock = ap->rval = args.fsbno; ASSERT(nullfb || fb_agno == args.agno || (ap->low && fb_agno < args.agno)); ap->alen = args.len; ap->ip->i_d.di_nblocks += args.len; xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); if (ap->wasdel) ap->ip->i_delayed_blks -= args.len; /* * Adjust the disk quota also. This was reserved * earlier. */ xfs_trans_mod_dquot_byino(ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : XFS_TRANS_DQ_BCOUNT, (long) args.len); } else { ap->rval = NULLFSBLOCK; ap->alen = 0; } return 0; } /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int xfs_bmap_alloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) return xfs_bmap_rtalloc(ap); return xfs_bmap_btalloc(ap); } /* * Transform a btree format file with only one leaf node, where the * extents list will fit in the inode, into an extents format file. * Since the file extents are already in-core, all we have to do is * give up the space for the btree root and pitch the leaf block. */ STATIC int /* error */ xfs_bmap_btree_to_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_btree_cur_t *cur, /* btree cursor */ int *logflagsp, /* inode logging flags */ int whichfork) /* data or attr fork */ { /* REFERENCED */ struct xfs_btree_block *cblock;/* child btree block */ xfs_fsblock_t cbno; /* child block number */ xfs_buf_t *cbp; /* child block's buffer */ int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork data */ xfs_mount_t *mp; /* mount point structure */ __be64 *pp; /* ptr to block address */ struct xfs_btree_block *rblock;/* root btree block */ mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_flags & XFS_IFEXTENTS); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); rblock = ifp->if_broot; ASSERT(be16_to_cpu(rblock->bb_level) == 1); ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); cbno = be64_to_cpu(*pp); *logflagsp = 0; #ifdef DEBUG if ((error = xfs_btree_check_lptr(cur, cbno, 1))) return error; #endif if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF))) return error; cblock = XFS_BUF_TO_BLOCK(cbp); if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); if (cur->bc_bufs[0] == cbp) cur->bc_bufs[0] = NULL; xfs_iroot_realloc(ip, -1, whichfork); ASSERT(ifp->if_broot == NULL); ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); return 0; } /* * Called by xfs_bmapi to update file extent records and the btree * after removing space (or undoing a delayed allocation). */ STATIC int /* error */ xfs_bmap_del_extent( xfs_inode_t *ip, /* incore inode pointer */ xfs_trans_t *tp, /* current transaction pointer */ xfs_extnum_t idx, /* extent number to update/delete */ xfs_bmap_free_t *flist, /* list of extents to be freed */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *del, /* data to remove from extents */ int *logflagsp, /* inode logging flags */ int whichfork, /* data or attr fork */ int rsvd) /* OK to allocate reserved blocks */ { xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ xfs_fsblock_t del_endblock=0; /* first block past del */ xfs_fileoff_t del_endoff; /* first offset past del */ int delay; /* current block is delayed allocated */ int do_fx; /* free extent at end of routine */ xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ int error; /* error return value */ int flags; /* inode logging flags */ xfs_bmbt_irec_t got; /* current extent entry */ xfs_fileoff_t got_endoff; /* first offset past got */ int i; /* temp state */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_mount_t *mp; /* mount structure */ xfs_filblks_t nblks; /* quota/sb block count */ xfs_bmbt_irec_t new; /* new record to be inserted */ /* REFERENCED */ uint qfield; /* quota field to update */ xfs_filblks_t temp; /* for indirect length calculations */ xfs_filblks_t temp2; /* for indirect length calculations */ int state = 0; XFS_STATS_INC(xs_del_exlist); if (whichfork == XFS_ATTR_FORK) state |= BMAP_ATTRFORK; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT((idx >= 0) && (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); ASSERT(del->br_blockcount > 0); ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_get_all(ep, &got); ASSERT(got.br_startoff <= del->br_startoff); del_endoff = del->br_startoff + del->br_blockcount; got_endoff = got.br_startoff + got.br_blockcount; ASSERT(got_endoff >= del_endoff); delay = isnullstartblock(got.br_startblock); ASSERT(isnullstartblock(del->br_startblock) == delay); flags = 0; qfield = 0; error = 0; /* * If deleting a real allocation, must free up the disk space. */ if (!delay) { flags = XFS_ILOG_CORE; /* * Realtime allocation. Free it and record di_nblocks update. */ if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { xfs_fsblock_t bno; xfs_filblks_t len; ASSERT(do_mod(del->br_blockcount, mp->m_sb.sb_rextsize) == 0); ASSERT(do_mod(del->br_startblock, mp->m_sb.sb_rextsize) == 0); bno = del->br_startblock; len = del->br_blockcount; do_div(bno, mp->m_sb.sb_rextsize); do_div(len, mp->m_sb.sb_rextsize); if ((error = xfs_rtfree_extent(ip->i_transp, bno, (xfs_extlen_t)len))) goto done; do_fx = 0; nblks = len * mp->m_sb.sb_rextsize; qfield = XFS_TRANS_DQ_RTBCOUNT; } /* * Ordinary allocation. */ else { do_fx = 1; nblks = del->br_blockcount; qfield = XFS_TRANS_DQ_BCOUNT; } /* * Set up del_endblock and cur for later. */ del_endblock = del->br_startblock + del->br_blockcount; if (cur) { if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, got.br_blockcount, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); } da_old = da_new = 0; } else { da_old = startblockval(got.br_startblock); da_new = 0; nblks = 0; do_fx = 0; } /* * Set flag value to use in switch statement. * Left-contig is 2, right-contig is 1. */ switch (((got.br_startoff == del->br_startoff) << 1) | (got_endoff == del_endoff)) { case 3: /* * Matches the whole extent. Delete the entry. */ xfs_iext_remove(ip, idx, 1, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); ifp->if_lastex = idx; if (delay) break; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); flags |= XFS_ILOG_CORE; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_btree_delete(cur, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); break; case 2: /* * Deleting the first part of the extent. */ trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startoff(ep, del_endoff); temp = got.br_blockcount - del->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); ifp->if_lastex = idx; if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); da_new = temp; break; } xfs_bmbt_set_startblock(ep, del_endblock); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); if (!cur) { flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, got.br_blockcount - del->br_blockcount, got.br_state))) goto done; break; case 1: /* * Deleting the last part of the extent. */ temp = got.br_blockcount - del->br_blockcount; trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); ifp->if_lastex = idx; if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); da_new = temp; break; } trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); if (!cur) { flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, got.br_blockcount - del->br_blockcount, got.br_state))) goto done; break; case 0: /* * Deleting the middle of the extent. */ temp = del->br_startoff - got.br_startoff; trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); new.br_startoff = del_endoff; temp2 = got_endoff - del_endoff; new.br_blockcount = temp2; new.br_state = got.br_state; if (!delay) { new.br_startblock = del_endblock; flags |= XFS_ILOG_CORE; if (cur) { if ((error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, temp, got.br_state))) goto done; if ((error = xfs_btree_increment(cur, 0, &i))) goto done; cur->bc_rec.b = new; error = xfs_btree_insert(cur, &i); if (error && error != ENOSPC) goto done; /* * If get no-space back from btree insert, * it tried a split, and we have a zero * block reservation. * Fix up our state and return the error. */ if (error == ENOSPC) { /* * Reset the cursor, don't trust * it after any insert operation. */ if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, temp, &i))) goto done; XFS_WANT_CORRUPTED_GOTO(i == 1, done); /* * Update the btree record back * to the original value. */ if ((error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, got.br_blockcount, got.br_state))) goto done; /* * Reset the extent record back * to the original value. */ xfs_bmbt_set_blockcount(ep, got.br_blockcount); flags = 0; error = XFS_ERROR(ENOSPC); goto done; } XFS_WANT_CORRUPTED_GOTO(i == 1, done); } else flags |= xfs_ilog_fext(whichfork); XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); } else { ASSERT(whichfork == XFS_DATA_FORK); temp = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); temp2 = xfs_bmap_worst_indlen(ip, temp2); new.br_startblock = nullstartblock((int)temp2); da_new = temp + temp2; while (da_new > da_old) { if (temp) { temp--; da_new--; xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); } if (da_new == da_old) break; if (temp2) { temp2--; da_new--; new.br_startblock = nullstartblock((int)temp2); } } } trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); xfs_iext_insert(ip, idx + 1, 1, &new, state); ifp->if_lastex = idx + 1; break; } /* * If we need to, add to list of extents to delete. */ if (do_fx) xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, mp); /* * Adjust inode # blocks in the file. */ if (nblks) ip->i_d.di_nblocks -= nblks; /* * Adjust quota data. */ if (qfield) xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks); /* * Account for change in delayed indirect blocks. * Nothing to do for disk quota accounting here. */ ASSERT(da_old >= da_new); if (da_old > da_new) { xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, (int64_t)(da_old - da_new), rsvd); } done: *logflagsp = flags; return error; } /* * Remove the entry "free" from the free item list. Prev points to the * previous entry, unless "free" is the head of the list. */ void xfs_bmap_del_free( xfs_bmap_free_t *flist, /* free item list header */ xfs_bmap_free_item_t *prev, /* previous item on list, if any */ xfs_bmap_free_item_t *free) /* list item to be freed */ { if (prev) prev->xbfi_next = free->xbfi_next; else flist->xbf_first = free->xbfi_next; flist->xbf_count--; kmem_zone_free(xfs_bmap_free_item_zone, free); } /* * Convert an extents-format file into a btree-format file. * The new file will have a root block (in the inode) and a single child block. */ STATIC int /* error */ xfs_bmap_extents_to_btree( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first-block-allocated */ xfs_bmap_free_t *flist, /* blocks freed in xaction */ xfs_btree_cur_t **curp, /* cursor returned to caller */ int wasdel, /* converting a delayed alloc */ int *logflagsp, /* inode logging flags */ int whichfork) /* data or attr fork */ { struct xfs_btree_block *ablock; /* allocated (child) bt block */ xfs_buf_t *abp; /* buffer for ablock */ xfs_alloc_arg_t args; /* allocation arguments */ xfs_bmbt_rec_t *arp; /* child record pointer */ struct xfs_btree_block *block; /* btree root block */ xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ xfs_extnum_t i, cnt; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_key_t *kp; /* root block key pointer */ xfs_mount_t *mp; /* mount structure */ xfs_extnum_t nextents; /* number of file extents */ xfs_bmbt_ptr_t *pp; /* root block address pointer */ ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); /* * Make space in the inode incore. */ xfs_iroot_realloc(ip, 1, whichfork); ifp->if_flags |= XFS_IFBROOT; /* * Fill in the root. */ block = ifp->if_broot; block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); block->bb_level = cpu_to_be16(1); block->bb_numrecs = cpu_to_be16(1); block->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); block->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); /* * Need a cursor. Can't allocate until bb_level is filled in. */ mp = ip->i_mount; cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; cur->bc_private.b.flist = flist; cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; /* * Convert to a btree with two levels, one record in root. */ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); args.tp = tp; args.mp = mp; args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); } else if (flist->xbf_low) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = *firstblock; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = *firstblock; } args.minlen = args.maxlen = args.prod = 1; args.total = args.minleft = args.alignment = args.mod = args.isfl = args.minalignslop = 0; args.wasdel = wasdel; *logflagsp = 0; if ((error = xfs_alloc_vextent(&args))) { xfs_iroot_realloc(ip, -1, whichfork); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } /* * Allocation can't fail, the space was reserved. */ ASSERT(args.fsbno != NULLFSBLOCK); ASSERT(*firstblock == NULLFSBLOCK || args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) || (flist->xbf_low && args.agno > XFS_FSB_TO_AGNO(mp, *firstblock))); *firstblock = cur->bc_private.b.firstblock = args.fsbno; cur->bc_private.b.allocated++; ip->i_d.di_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); /* * Fill in the child block. */ ablock = XFS_BUF_TO_BLOCK(abp); ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); ablock->bb_level = 0; ablock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); ablock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); for (cnt = i = 0; i < nextents; i++) { ep = xfs_iext_get_ext(ifp, i); if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) { arp->l0 = cpu_to_be64(ep->l0); arp->l1 = cpu_to_be64(ep->l1); arp++; cnt++; } } ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); xfs_btree_set_numrecs(ablock, cnt); /* * Fill in the root key and pointer. */ kp = XFS_BMBT_KEY_ADDR(mp, block, 1); arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, be16_to_cpu(block->bb_level))); *pp = cpu_to_be64(args.fsbno); /* * Do all this logging at the end so that * the root is at the right level. */ xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS); xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); ASSERT(*curp == NULL); *curp = cur; *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); return 0; } /* * Calculate the default attribute fork offset for newly created inodes. */ uint xfs_default_attroffset( struct xfs_inode *ip) { struct xfs_mount *mp = ip->i_mount; uint offset; if (mp->m_sb.sb_inodesize == 256) { offset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); } else { offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); } ASSERT(offset < XFS_LITINO(mp)); return offset; } /* * Helper routine to reset inode di_forkoff field when switching * attribute fork from local to extent format - we reset it where * possible to make space available for inline data fork extents. */ STATIC void xfs_bmap_forkoff_reset( xfs_mount_t *mp, xfs_inode_t *ip, int whichfork) { if (whichfork == XFS_ATTR_FORK && ip->i_d.di_format != XFS_DINODE_FMT_DEV && ip->i_d.di_format != XFS_DINODE_FMT_UUID && ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; if (dfl_forkoff > ip->i_d.di_forkoff) { ip->i_d.di_forkoff = dfl_forkoff; ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t); ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t); } } } /* * Convert a local file to an extents file. * This code is out of bounds for data forks of regular files, * since the file data needs to get logged so things will stay consistent. * (The bmap-level manipulations are ok, though). */ STATIC int /* error */ xfs_bmap_local_to_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated in xaction */ xfs_extlen_t total, /* total blocks needed by transaction */ int *logflagsp, /* inode logging flags */ int whichfork) /* data or attr fork */ { int error; /* error return value */ int flags; /* logging flags returned */ xfs_ifork_t *ifp; /* inode fork pointer */ /* * We don't want to deal with the case of keeping inode data inline yet. * So sending the data fork of a regular inode is invalid. */ ASSERT(!((ip->i_d.di_mode & S_IFMT) == S_IFREG && whichfork == XFS_DATA_FORK)); ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); flags = 0; error = 0; if (ifp->if_bytes) { xfs_alloc_arg_t args; /* allocation arguments */ xfs_buf_t *bp; /* buffer for extent block */ xfs_bmbt_rec_host_t *ep;/* extent record pointer */ args.tp = tp; args.mp = ip->i_mount; args.firstblock = *firstblock; ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); /* * Allocate a block. We know we need only one, since the * file currently fits in an inode. */ if (*firstblock == NULLFSBLOCK) { args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); args.type = XFS_ALLOCTYPE_START_BNO; } else { args.fsbno = *firstblock; args.type = XFS_ALLOCTYPE_NEAR_BNO; } args.total = total; args.mod = args.minleft = args.alignment = args.wasdel = args.isfl = args.minalignslop = 0; args.minlen = args.maxlen = args.prod = 1; if ((error = xfs_alloc_vextent(&args))) goto done; /* * Can't fail, the space was reserved. */ ASSERT(args.fsbno != NULLFSBLOCK); ASSERT(args.len == 1); *firstblock = args.fsbno; bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, ifp->if_bytes); xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); xfs_bmap_forkoff_reset(args.mp, ip, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); xfs_iext_add(ifp, 0, 1); ep = xfs_iext_get_ext(ifp, 0); xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); trace_xfs_bmap_post_update(ip, 0, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, _THIS_IP_); XFS_IFORK_NEXT_SET(ip, whichfork, 1); ip->i_d.di_nblocks = 1; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); flags |= xfs_ilog_fext(whichfork); } else { ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); } ifp->if_flags &= ~XFS_IFINLINE; ifp->if_flags |= XFS_IFEXTENTS; XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); flags |= XFS_ILOG_CORE; done: *logflagsp = flags; return error; } /* * Search the extent records for the entry containing block bno. * If bno lies in a hole, point to the next entry. If bno lies * past eof, *eofp will be set, and *prevp will contain the last * entry (null if none). Else, *lastxp will be set to the index * of the found entry; *gotp will contain the entry. */ STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_multi_extents( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number searched for */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_bmbt_rec_host_t *ep; /* extent record pointer */ xfs_extnum_t lastx; /* last extent index */ /* * Initialize the extent entry structure to catch access to * uninitialized br_startblock field. */ gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; gotp->br_state = XFS_EXT_INVALID; #if XFS_BIG_BLKNOS gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; #else gotp->br_startblock = 0xffffa5a5; #endif prevp->br_startoff = NULLFILEOFF; ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); if (lastx > 0) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); } if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { xfs_bmbt_get_all(ep, gotp); *eofp = 0; } else { if (lastx > 0) { *gotp = *prevp; } *eofp = 1; ep = NULL; } *lastxp = lastx; return ep; } /* * Search the extents list for the inode, for the extent containing bno. * If bno lies in a hole, point to the next entry. If bno lies past eof, * *eofp will be set, and *prevp will contain the last entry (null if none). * Else, *lastxp will be set to the index of the found * entry; *gotp will contain the entry. */ xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t bno, /* block number searched for */ int fork, /* data or attr fork */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ XFS_STATS_INC(xs_look_exlist); ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, "Access to block zero in inode %llu " "start_block: %llx start_off: %llx " "blkcnt: %llx extent-state: %x lastx: %x\n", (unsigned long long)ip->i_ino, (unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_blockcount, gotp->br_state, *lastxp); *lastxp = NULLEXTNUM; *eofp = 1; return NULL; } return ep; } /* * Compute the worst-case number of indirect blocks that will be used * for ip's delayed extent of length "len". */ STATIC xfs_filblks_t xfs_bmap_worst_indlen( xfs_inode_t *ip, /* incore inode pointer */ xfs_filblks_t len) /* delayed extent length */ { int level; /* btree level number */ int maxrecs; /* maximum record count at this level */ xfs_mount_t *mp; /* mount structure */ xfs_filblks_t rval; /* return value */ mp = ip->i_mount; maxrecs = mp->m_bmap_dmxr[0]; for (level = 0, rval = 0; level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); level++) { len += maxrecs - 1; do_div(len, maxrecs); rval += len; if (len == 1) return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - level - 1; if (level == 0) maxrecs = mp->m_bmap_dmxr[1]; } return rval; } /* * Convert inode from non-attributed to attributed. * Must not be in a transaction, ip must not be locked. */ int /* error code */ xfs_bmap_add_attrfork( xfs_inode_t *ip, /* incore inode pointer */ int size, /* space new attribute needs */ int rsvd) /* xact may use reserved blks */ { xfs_fsblock_t firstblock; /* 1st block/ag allocated */ xfs_bmap_free_t flist; /* freed extent records */ xfs_mount_t *mp; /* mount structure */ xfs_trans_t *tp; /* transaction pointer */ int blks; /* space reservation */ int version = 1; /* superblock attr version */ int committed; /* xaction was committed */ int logflags; /* logging flags */ int error; /* error return value */ ASSERT(XFS_IFORK_Q(ip) == 0); ASSERT(ip->i_df.if_ext_max == XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); mp = ip->i_mount; ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); blks = XFS_ADDAFORK_SPACE_RES(mp); if (rsvd) tp->t_flags |= XFS_TRANS_RESERVE; if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT))) goto error0; xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : XFS_QMOPT_RES_REGBLKS); if (error) { xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); return error; } if (XFS_IFORK_Q(ip)) goto error1; if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { /* * For inodes coming from pre-6.2 filesystems. */ ASSERT(ip->i_d.di_aformat == 0); ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; } ASSERT(ip->i_d.di_anextents == 0); xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_DEV: ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; break; case XFS_DINODE_FMT_UUID: ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; break; case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); if (!ip->i_d.di_forkoff) ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3; else if (mp->m_flags & XFS_MOUNT_ATTR2) version = 2; break; default: ASSERT(0); error = XFS_ERROR(EINVAL); goto error1; } ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); ASSERT(ip->i_afp == NULL); ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); ip->i_afp->if_flags = XFS_IFEXTENTS; logflags = 0; xfs_bmap_init(&flist, &firstblock); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, &logflags); break; case XFS_DINODE_FMT_EXTENTS: error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, &flist, &logflags); break; case XFS_DINODE_FMT_BTREE: error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist, &logflags); break; default: error = 0; break; } if (logflags) xfs_trans_log_inode(tp, ip, logflags); if (error) goto error2; if (!xfs_sb_version_hasattr(&mp->m_sb) || (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { __int64_t sbfields = 0; spin_lock(&mp->m_sb_lock); if (!xfs_sb_version_hasattr(&mp->m_sb)) { xfs_sb_version_addattr(&mp->m_sb); sbfields |= XFS_SB_VERSIONNUM; } if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { xfs_sb_version_addattr2(&mp->m_sb); sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); } if (sbfields) { spin_unlock(&mp->m_sb_lock); xfs_mod_sb(tp, sbfields); } else spin_unlock(&mp->m_sb_lock); } if ((error = xfs_bmap_finish(&tp, &flist, &committed))) goto error2; error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); ASSERT(ip->i_df.if_ext_max == XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); return error; error2: xfs_bmap_cancel(&flist); error1: xfs_iunlock(ip, XFS_ILOCK_EXCL); error0: xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); ASSERT(ip->i_df.if_ext_max == XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); return error; } /* * Add the extent to the list of extents to be free at transaction end. * The list is maintained sorted (by block number). */ /* ARGSUSED */ void xfs_bmap_add_free( xfs_fsblock_t bno, /* fs block number of extent */ xfs_filblks_t len, /* length of extent */ xfs_bmap_free_t *flist, /* list of extents */ xfs_mount_t *mp) /* mount point structure */ { xfs_bmap_free_item_t *cur; /* current (next) element */ xfs_bmap_free_item_t *new; /* new element */ xfs_bmap_free_item_t *prev; /* previous element */ #ifdef DEBUG xfs_agnumber_t agno; xfs_agblock_t agbno; ASSERT(bno != NULLFSBLOCK); ASSERT(len > 0); ASSERT(len <= MAXEXTLEN); ASSERT(!isnullstartblock(bno)); agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); ASSERT(agno < mp->m_sb.sb_agcount); ASSERT(agbno < mp->m_sb.sb_agblocks); ASSERT(len < mp->m_sb.sb_agblocks); ASSERT(agbno + len <= mp->m_sb.sb_agblocks); #endif ASSERT(xfs_bmap_free_item_zone != NULL); new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); new->xbfi_startblock = bno; new->xbfi_blockcount = (xfs_extlen_t)len; for (prev = NULL, cur = flist->xbf_first; cur != NULL; prev = cur, cur = cur->xbfi_next) { if (cur->xbfi_startblock >= bno) break; } if (prev) prev->xbfi_next = new; else flist->xbf_first = new; new->xbfi_next = cur; flist->xbf_count++; } /* * Compute and fill in the value of the maximum depth of a bmap btree * in this filesystem. Done once, during mount. */ void xfs_bmap_compute_maxlevels( xfs_mount_t *mp, /* file system mount structure */ int whichfork) /* data or attr fork */ { int level; /* btree level */ uint maxblocks; /* max blocks at this level */ uint maxleafents; /* max leaf entries possible */ int maxrootrecs; /* max records in root block */ int minleafrecs; /* min records in leaf block */ int minnoderecs; /* min records in node block */ int sz; /* root block size */ /* * The maximum number of extents in a file, hence the maximum * number of leaf entries, is controlled by the type of di_nextents * (a signed 32-bit number, xfs_extnum_t), or by di_anextents * (a signed 16-bit number, xfs_aextnum_t). * * Note that we can no longer assume that if we are in ATTR1 that * the fork offset of all the inodes will be * (xfs_default_attroffset(ip) >> 3) because we could have mounted * with ATTR2 and then mounted back with ATTR1, keeping the * di_forkoff's fixed but probably at various positions. Therefore, * for both ATTR1 and ATTR2 we have to assume the worst case scenario * of a minimum size available. */ if (whichfork == XFS_DATA_FORK) { maxleafents = MAXEXTNUM; sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); } else { maxleafents = MAXAEXTNUM; sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); } maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0); minleafrecs = mp->m_bmap_dmnr[0]; minnoderecs = mp->m_bmap_dmnr[1]; maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; for (level = 1; maxblocks > 1; level++) { if (maxblocks <= maxrootrecs) maxblocks = 1; else maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; } mp->m_bm_maxlevels[whichfork] = level; } /* * Free up any items left in the list. */ void xfs_bmap_cancel( xfs_bmap_free_t *flist) /* list of bmap_free_items */ { xfs_bmap_free_item_t *free; /* free list item */ xfs_bmap_free_item_t *next; if (flist->xbf_count == 0) return; ASSERT(flist->xbf_first != NULL); for (free = flist->xbf_first; free; free = next) { next = free->xbfi_next; xfs_bmap_del_free(flist, NULL, free); } ASSERT(flist->xbf_count == 0); } /* * Returns the file-relative block number of the first unused block(s) * in the file with at least "len" logically contiguous blocks free. * This is the lowest-address hole if the file has holes, else the first block * past the end of file. * Return 0 if the file is currently local (in-inode). */ int /* error */ xfs_bmap_first_unused( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ xfs_extlen_t len, /* size of hole to find */ xfs_fileoff_t *first_unused, /* unused block */ int whichfork) /* data or attr fork */ { int error; /* error return value */ int idx; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_fileoff_t lastaddr; /* last block number seen */ xfs_fileoff_t lowest; /* lowest useful block */ xfs_fileoff_t max; /* starting useful block */ xfs_fileoff_t off; /* offset for this block */ xfs_extnum_t nextents; /* number of extent entries */ ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { *first_unused = 0; return 0; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; lowest = *first_unused; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); off = xfs_bmbt_get_startoff(ep); /* * See if the hole before this extent will work. */ if (off >= lowest + len && off - max >= len) { *first_unused = max; return 0; } lastaddr = off + xfs_bmbt_get_blockcount(ep); max = XFS_FILEOFF_MAX(lastaddr, lowest); } *first_unused = max; return 0; } /* * Returns the file-relative block number of the last block + 1 before * last_block (input value) in the file. * This is not based on i_size, it is based on the extent records. * Returns 0 for local files, as they do not have extent records. */ int /* error */ xfs_bmap_last_before( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ xfs_fileoff_t *last_block, /* last block */ int whichfork) /* data or attr fork */ { xfs_fileoff_t bno; /* input file offset */ int eof; /* hit end of file */ xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_bmbt_irec_t got; /* current extent value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last extent used */ xfs_bmbt_irec_t prev; /* previous extent value */ if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return XFS_ERROR(EIO); if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { *last_block = 0; return 0; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; bno = *last_block - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (eof || xfs_bmbt_get_startoff(ep) > bno) { if (prev.br_startoff == NULLFILEOFF) *last_block = 0; else *last_block = prev.br_startoff + prev.br_blockcount; } /* * Otherwise *last_block is already the right answer. */ return 0; } /* * Returns the file-relative block number of the first block past eof in * the file. This is not based on i_size, it is based on the extent records. * Returns 0 for local files, as they do not have extent records. */ int /* error */ xfs_bmap_last_offset( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ xfs_fileoff_t *last_block, /* last block */ int whichfork) /* data or attr fork */ { xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t nextents; /* number of extent entries */ if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return XFS_ERROR(EIO); if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { *last_block = 0; return 0; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (!nextents) { *last_block = 0; return 0; } ep = xfs_iext_get_ext(ifp, nextents - 1); *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep); return 0; } /* * Returns whether the selected fork of the inode has exactly one * block or not. For the data fork we check this matches di_size, * implying the file's range is 0..bsize-1. */ int /* 1=>1 block, 0=>otherwise */ xfs_bmap_one_block( xfs_inode_t *ip, /* incore inode */ int whichfork) /* data or attr fork */ { xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ xfs_ifork_t *ifp; /* inode fork pointer */ int rval; /* return value */ xfs_bmbt_irec_t s; /* internal version of extent */ #ifndef DEBUG if (whichfork == XFS_DATA_FORK) { return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ? (ip->i_size == ip->i_mount->m_sb.sb_blocksize) : (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); } #endif /* !DEBUG */ if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) return 0; if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) return 0; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_flags & XFS_IFEXTENTS); ep = xfs_iext_get_ext(ifp, 0); xfs_bmbt_get_all(ep, &s); rval = s.br_startoff == 0 && s.br_blockcount == 1; if (rval && whichfork == XFS_DATA_FORK) ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize); return rval; } STATIC int xfs_bmap_sanity_check( struct xfs_mount *mp, struct xfs_buf *bp, int level) { struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC || be16_to_cpu(block->bb_level) != level || be16_to_cpu(block->bb_numrecs) == 0 || be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) return 0; return 1; } /* * Read in the extents to if_extents. * All inode fields are set up by caller, we just traverse the btree * and copy the records in. If the file system cannot contain unwritten * extents, the records are checked for no "state" flags. */ int /* error */ xfs_bmap_read_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ int whichfork) /* data or attr fork */ { struct xfs_btree_block *block; /* current btree block */ xfs_fsblock_t bno; /* block # of "block" */ xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ xfs_extnum_t i, j; /* index into the extents list */ xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ __be64 *pp; /* pointer to block address */ /* REFERENCED */ xfs_extnum_t room; /* number of entries there's room for */ bno = NULLFSBLOCK; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE : XFS_EXTFMT_INODE(ip); block = ifp->if_broot; /* * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. */ level = be16_to_cpu(block->bb_level); ASSERT(level > 0); pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); bno = be64_to_cpu(*pp); ASSERT(bno != NULLDFSBNO); ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* * Go down the tree until leaf level is reached, following the first * pointer (leftmost) at each level. */ while (level-- > 0) { if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) return error; block = XFS_BUF_TO_BLOCK(bp); XFS_WANT_CORRUPTED_GOTO( xfs_bmap_sanity_check(mp, bp, level), error0); if (level == 0) break; pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); bno = be64_to_cpu(*pp); XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); xfs_trans_brelse(tp, bp); } /* * Here with bp and block set to the leftmost leaf node in the tree. */ room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); i = 0; /* * Loop over all leaf nodes. Copy information to the extent records. */ for (;;) { xfs_bmbt_rec_t *frp; xfs_fsblock_t nextbno; xfs_extnum_t num_recs; xfs_extnum_t start; num_recs = xfs_btree_get_numrecs(block); if (unlikely(i + num_recs > room)) { ASSERT(i + num_recs <= room); xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, (btree extents).", (unsigned long long) ip->i_ino); XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", XFS_ERRLEVEL_LOW, ip->i_mount); goto error0; } XFS_WANT_CORRUPTED_GOTO( xfs_bmap_sanity_check(mp, bp, 0), error0); /* * Read-ahead the next leaf block, if any. */ nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); if (nextbno != NULLFSBLOCK) xfs_btree_reada_bufl(mp, nextbno, 1); /* * Copy records into the extent records. */ frp = XFS_BMBT_REC_ADDR(mp, block, 1); start = i; for (j = 0; j < num_recs; j++, i++, frp++) { xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); trp->l0 = be64_to_cpu(frp->l0); trp->l1 = be64_to_cpu(frp->l1); } if (exntf == XFS_EXTFMT_NOSTATE) { /* * Check all attribute bmap btree records and * any "older" data bmap btree records for a * set bit in the "extent flag" position. */ if (unlikely(xfs_check_nostate_extents(ifp, start, num_recs))) { XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", XFS_ERRLEVEL_LOW, ip->i_mount); goto error0; } } xfs_trans_brelse(tp, bp); bno = nextbno; /* * If we've reached the end, stop. */ if (bno == NULLFSBLOCK) break; if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) return error; block = XFS_BUF_TO_BLOCK(bp); } ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); return 0; error0: xfs_trans_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } #ifdef DEBUG /* * Add bmap trace insert entries for all the contents of the extent records. */ void xfs_bmap_trace_exlist( xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t cnt, /* count of entries in the list */ int whichfork, /* data or attr fork */ unsigned long caller_ip) { xfs_extnum_t idx; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ int state = 0; if (whichfork == XFS_ATTR_FORK) state |= BMAP_ATTRFORK; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); for (idx = 0; idx < cnt; idx++) trace_xfs_extlist(ip, idx, whichfork, caller_ip); } /* * Validate that the bmbt_irecs being returned from bmapi are valid * given the callers original parameters. Specifically check the * ranges of the returned irecs to ensure that they only extent beyond * the given parameters if the XFS_BMAPI_ENTIRE flag was set. */ STATIC void xfs_bmap_validate_ret( xfs_fileoff_t bno, xfs_filblks_t len, int flags, xfs_bmbt_irec_t *mval, int nmap, int ret_nmap) { int i; /* index to map values */ ASSERT(ret_nmap <= nmap); for (i = 0; i < ret_nmap; i++) { ASSERT(mval[i].br_blockcount > 0); if (!(flags & XFS_BMAPI_ENTIRE)) { ASSERT(mval[i].br_startoff >= bno); ASSERT(mval[i].br_blockcount <= len); ASSERT(mval[i].br_startoff + mval[i].br_blockcount <= bno + len); } else { ASSERT(mval[i].br_startoff < bno + len); ASSERT(mval[i].br_startoff + mval[i].br_blockcount > bno); } ASSERT(i == 0 || mval[i - 1].br_startoff + mval[i - 1].br_blockcount == mval[i].br_startoff); if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY)) ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && mval[i].br_startblock != HOLESTARTBLOCK); ASSERT(mval[i].br_state == XFS_EXT_NORM || mval[i].br_state == XFS_EXT_UNWRITTEN); } } #endif /* DEBUG */ /* * Map file blocks to filesystem blocks. * File range is given by the bno/len pair. * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) * into a hole or past eof. * Only allocates blocks from a single allocation group, * to avoid locking problems. * The returned value in "firstblock" from the first call in a transaction * must be remembered and presented to subsequent calls in "firstblock". * An upper bound for the number of blocks to be allocated is supplied to * the first call in "total"; if no allocation group has that many free * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). */ int /* error */ xfs_bmapi( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ xfs_fileoff_t bno, /* starting file offs. mapped */ xfs_filblks_t len, /* length to map in file */ int flags, /* XFS_BMAPI_... */ xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_extlen_t total, /* total blocks needed */ xfs_bmbt_irec_t *mval, /* output: map values */ int *nmap, /* i/o: mval size/count */ xfs_bmap_free_t *flist) /* i/o: list extents to free */ { xfs_fsblock_t abno; /* allocated block number */ xfs_extlen_t alen; /* allocated extent length */ xfs_fileoff_t aoff; /* allocated file offset */ xfs_bmalloca_t bma = { 0 }; /* args for xfs_bmap_alloc */ xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_fileoff_t end; /* end of mapped file region */ int eof; /* we've hit the end of extents */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return */ xfs_bmbt_irec_t got; /* current file extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extlen_t indlen; /* indirect blocks length */ xfs_extnum_t lastx; /* last useful extent number */ int logflags; /* flags for transaction logging */ xfs_extlen_t minleft; /* min blocks left after allocation */ xfs_extlen_t minlen; /* min allocation size */ xfs_mount_t *mp; /* xfs mount structure */ int n; /* current extent index */ int nallocs; /* number of extents alloc'd */ xfs_extnum_t nextents; /* number of extents in file */ xfs_fileoff_t obno; /* old block number (offset) */ xfs_bmbt_irec_t prev; /* previous file extent record */ int tmp_logflags; /* temp flags holder */ int whichfork; /* data or attr fork */ char inhole; /* current location is hole in file */ char wasdelay; /* old extent was delayed */ char wr; /* this is a write request */ char rt; /* this is a realtime file */ #ifdef DEBUG xfs_fileoff_t orig_bno; /* original block number value */ int orig_flags; /* original flags arg value */ xfs_filblks_t orig_len; /* original value of len arg */ xfs_bmbt_irec_t *orig_mval; /* original value of mval */ int orig_nmap; /* original value of *nmap */ orig_bno = bno; orig_len = len; orig_flags = flags; orig_mval = mval; orig_nmap = *nmap; #endif ASSERT(*nmap >= 1); ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; mp = ip->i_mount; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); if ((wr = (flags & XFS_BMAPI_WRITE)) != 0) XFS_STATS_INC(xs_blk_mapw); else XFS_STATS_INC(xs_blk_mapr); /* * IGSTATE flag is used to combine extents which * differ only due to the state of the extents. * This technique is used from xfs_getbmap() * when the caller does not wish to see the * separation (which is the default). * * This technique is also used when writing a * buffer which has been partially written, * (usually by being flushed during a chunkread), * to ensure one write takes place. This also * prevents a change in the xfs inode extents at * this time, intentionally. This change occurs * on completion of the write operation, in * xfs_strat_comp(), where the xfs_bmapi() call * is transactioned, and the extents combined. */ if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ wr = 0; /* no allocations are allowed */ ASSERT(wr || !(flags & XFS_BMAPI_DELAY)); logflags = 0; nallocs = 0; cur = NULL; if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { ASSERT(wr && tp); if ((error = xfs_bmap_local_to_extents(tp, ip, firstblock, total, &logflags, whichfork))) goto error0; } if (wr && *firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; else minleft = 1; } else minleft = 0; if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) goto error0; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); n = 0; end = bno + len; obno = bno; bma.ip = NULL; while (bno < end && n < *nmap) { /* * Reading past eof, act as though there's a hole * up to end. */ if (eof && !wr) got.br_startoff = end; inhole = eof || got.br_startoff > bno; wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && isnullstartblock(got.br_startblock); /* * First, deal with the hole before the allocated space * that we found, if any. */ if (wr && (inhole || wasdelay)) { /* * For the wasdelay case, we could also just * allocate the stuff asked for in this bmap call * but that wouldn't be as good. */ if (wasdelay) { alen = (xfs_extlen_t)got.br_blockcount; aoff = got.br_startoff; if (lastx != NULLEXTNUM && lastx) { ep = xfs_iext_get_ext(ifp, lastx - 1); xfs_bmbt_get_all(ep, &prev); } } else { alen = (xfs_extlen_t) XFS_FILBLKS_MIN(len, MAXEXTLEN); if (!eof) alen = (xfs_extlen_t) XFS_FILBLKS_MIN(alen, got.br_startoff - bno); aoff = bno; } minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; if (flags & XFS_BMAPI_DELAY) { xfs_extlen_t extsz; /* Figure out the extent size, adjust alen */ extsz = xfs_get_extsz_hint(ip); if (extsz) { error = xfs_bmap_extsize_align(mp, &got, &prev, extsz, rt, eof, flags&XFS_BMAPI_DELAY, flags&XFS_BMAPI_CONVERT, &aoff, &alen); ASSERT(!error); } if (rt) extsz = alen / mp->m_sb.sb_rextsize; /* * Make a transaction-less quota reservation for * delayed allocation blocks. This number gets * adjusted later. We return if we haven't * allocated blocks already inside this loop. */ error = xfs_trans_reserve_quota_nblks( NULL, ip, (long)alen, 0, rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); if (error) { if (n == 0) { *nmap = 0; ASSERT(cur == NULL); return error; } break; } /* * Split changing sb for alen and indlen since * they could be coming from different places. */ indlen = (xfs_extlen_t) xfs_bmap_worst_indlen(ip, alen); ASSERT(indlen > 0); if (rt) { error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, -((int64_t)extsz), (flags & XFS_BMAPI_RSVBLOCKS)); } else { error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, -((int64_t)alen), (flags & XFS_BMAPI_RSVBLOCKS)); } if (!error) { error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, -((int64_t)indlen), (flags & XFS_BMAPI_RSVBLOCKS)); if (error && rt) xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, (int64_t)extsz, (flags & XFS_BMAPI_RSVBLOCKS)); else if (error) xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, (int64_t)alen, (flags & XFS_BMAPI_RSVBLOCKS)); } if (error) { if (XFS_IS_QUOTA_ON(mp)) /* unreserve the blocks now */ (void) xfs_trans_unreserve_quota_nblks( NULL, ip, (long)alen, 0, rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); break; } ip->i_delayed_blks += alen; abno = nullstartblock(indlen); } else { /* * If first time, allocate and fill in * once-only bma fields. */ if (bma.ip == NULL) { bma.tp = tp; bma.ip = ip; bma.prevp = &prev; bma.gotp = &got; bma.total = total; bma.userdata = 0; } /* Indicate if this is the first user data * in the file, or just any user data. */ if (!(flags & XFS_BMAPI_METADATA)) { bma.userdata = (aoff == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; } /* * Fill in changeable bma fields. */ bma.eof = eof; bma.firstblock = *firstblock; bma.alen = alen; bma.off = aoff; bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.minlen = minlen; bma.low = flist->xbf_low; bma.minleft = minleft; /* * Only want to do the alignment at the * eof if it is userdata and allocation length * is larger than a stripe unit. */ if (mp->m_dalign && alen >= mp->m_dalign && (!(flags & XFS_BMAPI_METADATA)) && (whichfork == XFS_DATA_FORK)) { if ((error = xfs_bmap_isaeof(ip, aoff, whichfork, &bma.aeof))) goto error0; } else bma.aeof = 0; /* * Call allocator. */ if ((error = xfs_bmap_alloc(&bma))) goto error0; /* * Copy out result fields. */ abno = bma.rval; if ((flist->xbf_low = bma.low)) minleft = 0; alen = bma.alen; aoff = bma.off; ASSERT(*firstblock == NULLFSBLOCK || XFS_FSB_TO_AGNO(mp, *firstblock) == XFS_FSB_TO_AGNO(mp, bma.firstblock) || (flist->xbf_low && XFS_FSB_TO_AGNO(mp, *firstblock) < XFS_FSB_TO_AGNO(mp, bma.firstblock))); *firstblock = bma.firstblock; if (cur) cur->bc_private.b.firstblock = *firstblock; if (abno == NULLFSBLOCK) break; if ((ifp->if_flags & XFS_IFBROOT) && !cur) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; cur->bc_private.b.flist = flist; } /* * Bump the number of extents we've allocated * in this call. */ nallocs++; } if (cur) cur->bc_private.b.flags = wasdelay ? XFS_BTCUR_BPRV_WASDEL : 0; got.br_startoff = aoff; got.br_startblock = abno; got.br_blockcount = alen; got.br_state = XFS_EXT_NORM; /* assume normal */ /* * Determine state of extent, and the filesystem. * A wasdelay extent has been initialized, so * shouldn't be flagged as unwritten. */ if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) { if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) got.br_state = XFS_EXT_UNWRITTEN; } error = xfs_bmap_add_extent(ip, lastx, &cur, &got, firstblock, flist, &tmp_logflags, whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); logflags |= tmp_logflags; if (error) goto error0; lastx = ifp->if_lastex; ep = xfs_iext_get_ext(ifp, lastx); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); xfs_bmbt_get_all(ep, &got); ASSERT(got.br_startoff <= aoff); ASSERT(got.br_startoff + got.br_blockcount >= aoff + alen); #ifdef DEBUG if (flags & XFS_BMAPI_DELAY) { ASSERT(isnullstartblock(got.br_startblock)); ASSERT(startblockval(got.br_startblock) > 0); } ASSERT(got.br_state == XFS_EXT_NORM || got.br_state == XFS_EXT_UNWRITTEN); #endif /* * Fall down into the found allocated space case. */ } else if (inhole) { /* * Reading in a hole. */ mval->br_startoff = bno; mval->br_startblock = HOLESTARTBLOCK; mval->br_blockcount = XFS_FILBLKS_MIN(len, got.br_startoff - bno); mval->br_state = XFS_EXT_NORM; bno += mval->br_blockcount; len -= mval->br_blockcount; mval++; n++; continue; } /* * Then deal with the allocated space we found. */ ASSERT(ep != NULL); if (!(flags & XFS_BMAPI_ENTIRE) && (got.br_startoff + got.br_blockcount > obno)) { if (obno > bno) bno = obno; ASSERT((bno >= obno) || (n == 0)); ASSERT(bno < end); mval->br_startoff = bno; if (isnullstartblock(got.br_startblock)) { ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } else mval->br_startblock = got.br_startblock + (bno - got.br_startoff); /* * Return the minimum of what we got and what we * asked for for the length. We can use the len * variable here because it is modified below * and we could have been there before coming * here if the first part of the allocation * didn't overlap what was asked for. */ mval->br_blockcount = XFS_FILBLKS_MIN(end - bno, got.br_blockcount - (bno - got.br_startoff)); mval->br_state = got.br_state; ASSERT(mval->br_blockcount <= len); } else { *mval = got; if (isnullstartblock(mval->br_startblock)) { ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } } /* * Check if writing previously allocated but * unwritten extents. */ if (wr && ((mval->br_state == XFS_EXT_UNWRITTEN && ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) || (mval->br_state == XFS_EXT_NORM && ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) == (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) { /* * Modify (by adding) the state flag, if writing. */ ASSERT(mval->br_blockcount <= len); if ((ifp->if_flags & XFS_IFBROOT) && !cur) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; cur->bc_private.b.flist = flist; } mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx, &cur, mval, firstblock, flist, &tmp_logflags, whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); logflags |= tmp_logflags; if (error) goto error0; lastx = ifp->if_lastex; ep = xfs_iext_get_ext(ifp, lastx); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); xfs_bmbt_get_all(ep, &got); /* * We may have combined previously unwritten * space with written space, so generate * another request. */ if (mval->br_blockcount < len) continue; } ASSERT((flags & XFS_BMAPI_ENTIRE) || ((mval->br_startoff + mval->br_blockcount) <= end)); ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= len) || (mval->br_startoff < obno)); bno = mval->br_startoff + mval->br_blockcount; len = end - bno; if (n > 0 && mval->br_startoff == mval[-1].br_startoff) { ASSERT(mval->br_startblock == mval[-1].br_startblock); ASSERT(mval->br_blockcount > mval[-1].br_blockcount); ASSERT(mval->br_state == mval[-1].br_state); mval[-1].br_blockcount = mval->br_blockcount; mval[-1].br_state = mval->br_state; } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK && mval[-1].br_startblock != DELAYSTARTBLOCK && mval[-1].br_startblock != HOLESTARTBLOCK && mval->br_startblock == mval[-1].br_startblock + mval[-1].br_blockcount && ((flags & XFS_BMAPI_IGSTATE) || mval[-1].br_state == mval->br_state)) { ASSERT(mval->br_startoff == mval[-1].br_startoff + mval[-1].br_blockcount); mval[-1].br_blockcount += mval->br_blockcount; } else if (n > 0 && mval->br_startblock == DELAYSTARTBLOCK && mval[-1].br_startblock == DELAYSTARTBLOCK && mval->br_startoff == mval[-1].br_startoff + mval[-1].br_blockcount) { mval[-1].br_blockcount += mval->br_blockcount; mval[-1].br_state = mval->br_state; } else if (!((n == 0) && ((mval->br_startoff + mval->br_blockcount) <= obno))) { mval++; n++; } /* * If we're done, stop now. Stop when we've allocated * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise * the transaction may get too big. */ if (bno >= end || n >= *nmap || nallocs >= *nmap) break; /* * Else go on to the next record. */ ep = xfs_iext_get_ext(ifp, ++lastx); prev = got; if (lastx >= nextents) eof = 1; else xfs_bmbt_get_all(ep, &got); } ifp->if_lastex = lastx; *nmap = n; /* * Transform from btree to extents, give it cur. */ if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { ASSERT(wr && cur); error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; } ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); error = 0; error0: /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. */ if ((logflags & xfs_ilog_fext(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) logflags &= ~xfs_ilog_fext(whichfork); else if ((logflags & xfs_ilog_fbroot(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) logflags &= ~xfs_ilog_fbroot(whichfork); /* * Log whatever the flags say, even if error. Otherwise we might miss * detecting a case where the data is changed, there's an error, * and it's not logged so we don't shutdown when we should. */ if (logflags) { ASSERT(tp && wr); xfs_trans_log_inode(tp, ip, logflags); } if (cur) { if (!error) { ASSERT(*firstblock == NULLFSBLOCK || XFS_FSB_TO_AGNO(mp, *firstblock) == XFS_FSB_TO_AGNO(mp, cur->bc_private.b.firstblock) || (flist->xbf_low && XFS_FSB_TO_AGNO(mp, *firstblock) < XFS_FSB_TO_AGNO(mp, cur->bc_private.b.firstblock))); *firstblock = cur->bc_private.b.firstblock; } xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); } if (!error) xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, orig_nmap, *nmap); return error; } /* * Map file blocks to filesystem blocks, simple version. * One block (extent) only, read-only. * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. * For the other flag values, the effect is as if XFS_BMAPI_METADATA * was set and all the others were clear. */ int /* error */ xfs_bmapi_single( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ int whichfork, /* data or attr fork */ xfs_fsblock_t *fsb, /* output: mapped block */ xfs_fileoff_t bno) /* starting file offs. mapped */ { int eof; /* we've hit the end of extents */ int error; /* error return */ xfs_bmbt_irec_t got; /* current file extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last useful extent number */ xfs_bmbt_irec_t prev; /* previous file extent record */ ifp = XFS_IFORK_PTR(ip, whichfork); if (unlikely( XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) { XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return XFS_ERROR(EIO); XFS_STATS_INC(xs_blk_mapr); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; (void)xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); /* * Reading past eof, act as though there's a hole * up to end. */ if (eof || got.br_startoff > bno) { *fsb = NULLFSBLOCK; return 0; } ASSERT(!isnullstartblock(got.br_startblock)); ASSERT(bno < got.br_startoff + got.br_blockcount); *fsb = got.br_startblock + (bno - got.br_startoff); ifp->if_lastex = lastx; return 0; } /* * Unmap (remove) blocks from a file. * If nexts is nonzero then the number of extents to remove is limited to * that value. If not all extents in the block range can be removed then * *done is set. */ int /* error */ xfs_bunmapi( xfs_trans_t *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t bno, /* starting offset to unmap */ xfs_filblks_t len, /* length to unmap in file */ int flags, /* misc flags */ xfs_extnum_t nexts, /* number of extents max */ xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *done) /* set if not done yet */ { xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_irec_t del; /* extent being deleted */ int eof; /* is deleting at eof */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ xfs_bmbt_irec_t got; /* current extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ int isrt; /* freeing in rt area */ xfs_extnum_t lastx; /* last extent index used */ int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ xfs_mount_t *mp; /* mount structure */ xfs_extnum_t nextents; /* number of file extents */ xfs_bmbt_irec_t prev; /* previous extent record */ xfs_fileoff_t start; /* first file offset deleted */ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ int rsvd; /* OK to allocate reserved blocks */ xfs_fsblock_t sum; trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; ifp = XFS_IFORK_PTR(ip, whichfork); if (unlikely( XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; ASSERT(len > 0); ASSERT(nexts >= 0); ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (nextents == 0) { *done = 1; return 0; } XFS_STATS_INC(xs_blk_unmap); isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); start = bno; bno = start + len - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); /* * Check to see if the given block number is past the end of the * file, back up to the last block if so... */ if (eof) { ep = xfs_iext_get_ext(ifp, --lastx); xfs_bmbt_get_all(ep, &got); bno = got.br_startoff + got.br_blockcount - 1; } logflags = 0; if (ifp->if_flags & XFS_IFBROOT) { ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; cur->bc_private.b.flist = flist; cur->bc_private.b.flags = 0; } else cur = NULL; extno = 0; while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 && (nexts == 0 || extno < nexts)) { /* * Is the found extent after a hole in which bno lives? * Just back up to the previous extent, if so. */ if (got.br_startoff > bno) { if (--lastx < 0) break; ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); } /* * Is the last block of this extent before the range * we're supposed to delete? If so, we're done. */ bno = XFS_FILEOFF_MIN(bno, got.br_startoff + got.br_blockcount - 1); if (bno < start) break; /* * Then deal with the (possibly delayed) allocated space * we found. */ ASSERT(ep != NULL); del = got; wasdel = isnullstartblock(del.br_startblock); if (got.br_startoff < start) { del.br_startoff = start; del.br_blockcount -= start - got.br_startoff; if (!wasdel) del.br_startblock += start - got.br_startoff; } if (del.br_startoff + del.br_blockcount > bno + 1) del.br_blockcount = bno + 1 - del.br_startoff; sum = del.br_startblock + del.br_blockcount; if (isrt && (mod = do_mod(sum, mp->m_sb.sb_rextsize))) { /* * Realtime extent not lined up at the end. * The extent could have been split into written * and unwritten pieces, or we could just be * unmapping part of it. But we can't really * get rid of part of a realtime extent. */ if (del.br_state == XFS_EXT_UNWRITTEN || !xfs_sb_version_hasextflgbit(&mp->m_sb)) { /* * This piece is unwritten, or we're not * using unwritten extents. Skip over it. */ ASSERT(bno >= mod); bno -= mod > del.br_blockcount ? del.br_blockcount : mod; if (bno < got.br_startoff) { if (--lastx >= 0) xfs_bmbt_get_all(xfs_iext_get_ext( ifp, lastx), &got); } continue; } /* * It's written, turn it unwritten. * This is better than zeroing it. */ ASSERT(del.br_state == XFS_EXT_NORM); ASSERT(xfs_trans_get_block_res(tp) > 0); /* * If this spans a realtime extent boundary, * chop it back to the start of the one we end at. */ if (del.br_blockcount > mod) { del.br_startoff += del.br_blockcount - mod; del.br_startblock += del.br_blockcount - mod; del.br_blockcount = mod; } del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx, &cur, &del, firstblock, flist, &logflags, XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; } if (isrt && (mod = do_mod(del.br_startblock, mp->m_sb.sb_rextsize))) { /* * Realtime extent is lined up at the end but not * at the front. We'll get rid of full extents if * we can. */ mod = mp->m_sb.sb_rextsize - mod; if (del.br_blockcount > mod) { del.br_blockcount -= mod; del.br_startoff += mod; del.br_startblock += mod; } else if ((del.br_startoff == start && (del.br_state == XFS_EXT_UNWRITTEN || xfs_trans_get_block_res(tp) == 0)) || !xfs_sb_version_hasextflgbit(&mp->m_sb)) { /* * Can't make it unwritten. There isn't * a full extent here so just skip it. */ ASSERT(bno >= del.br_blockcount); bno -= del.br_blockcount; if (bno < got.br_startoff) { if (--lastx >= 0) xfs_bmbt_get_all(--ep, &got); } continue; } else if (del.br_state == XFS_EXT_UNWRITTEN) { /* * This one is already unwritten. * It must have a written left neighbor. * Unwrite the killed part of that one and * try again. */ ASSERT(lastx > 0); xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), &prev); ASSERT(prev.br_state == XFS_EXT_NORM); ASSERT(!isnullstartblock(prev.br_startblock)); ASSERT(del.br_startblock == prev.br_startblock + prev.br_blockcount); if (prev.br_startoff < start) { mod = start - prev.br_startoff; prev.br_blockcount -= mod; prev.br_startblock += mod; prev.br_startoff = start; } prev.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx - 1, &cur, &prev, firstblock, flist, &logflags, XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; } else { ASSERT(del.br_state == XFS_EXT_NORM); del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent(ip, lastx, &cur, &del, firstblock, flist, &logflags, XFS_DATA_FORK, 0); if (error) goto error0; goto nodelete; } } if (wasdel) { ASSERT(startblockval(del.br_startblock) > 0); /* Update realtime/data freespace, unreserve quota */ if (isrt) { xfs_filblks_t rtexts; rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, (int64_t)rtexts, rsvd); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); } else { xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, (int64_t)del.br_blockcount, rsvd); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); } ip->i_delayed_blks -= del.br_blockcount; if (cur) cur->bc_private.b.flags |= XFS_BTCUR_BPRV_WASDEL; } else if (cur) cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; /* * If it's the case where the directory code is running * with no block reservation, and the deleted block is in * the middle of its extent, and the resulting insert * of an extent would cause transformation to btree format, * then reject it. The calling code will then swap * blocks around instead. * We have to do this now, rather than waiting for the * conversion to btree format, since the transaction * will be dirty. */ if (!wasdel && xfs_trans_get_block_res(tp) == 0 && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max && del.br_startoff > got.br_startoff && del.br_startoff + del.br_blockcount < got.br_startoff + got.br_blockcount) { error = XFS_ERROR(ENOSPC); goto error0; } error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, &tmp_logflags, whichfork, rsvd); logflags |= tmp_logflags; if (error) goto error0; bno = del.br_startoff - 1; nodelete: lastx = ifp->if_lastex; /* * If not done go on to the next (previous) record. * Reset ep in case the extents array was re-alloced. */ ep = xfs_iext_get_ext(ifp, lastx); if (bno != (xfs_fileoff_t)-1 && bno >= start) { if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || xfs_bmbt_get_startoff(ep) > bno) { if (--lastx >= 0) ep = xfs_iext_get_ext(ifp, lastx); } if (lastx >= 0) xfs_bmbt_get_all(ep, &got); extno++; } } ifp->if_lastex = lastx; *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); /* * Convert to a btree if necessary. */ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { ASSERT(cur == NULL); error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; } /* * transform from btree to extents, give it cur */ else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { ASSERT(cur != NULL); error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; } /* * transform from extents to local? */ ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); error = 0; error0: /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. */ if ((logflags & xfs_ilog_fext(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) logflags &= ~xfs_ilog_fext(whichfork); else if ((logflags & xfs_ilog_fbroot(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) logflags &= ~xfs_ilog_fbroot(whichfork); /* * Log inode even in the error case, if the transaction * is dirty we'll need to shut down the filesystem. */ if (logflags) xfs_trans_log_inode(tp, ip, logflags); if (cur) { if (!error) { *firstblock = cur->bc_private.b.firstblock; cur->bc_private.b.allocated = 0; } xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); } return error; } /* * Check the last inode extent to determine whether this allocation will result * in blocks being allocated at the end of the file. When we allocate new data * blocks at the end of the file which do not start at the previous data block, * we will try to align the new blocks at stripe unit boundaries. */ STATIC int /* error */ xfs_bmap_isaeof( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t off, /* file offset in fsblocks */ int whichfork, /* data or attribute fork */ char *aeof) /* return value */ { int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ xfs_extnum_t nextents; /* number of file extents */ xfs_bmbt_irec_t s; /* expanded extent record */ ASSERT(whichfork == XFS_DATA_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(NULL, ip, whichfork))) return error; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (nextents == 0) { *aeof = 1; return 0; } /* * Go to the last extent */ lastrec = xfs_iext_get_ext(ifp, nextents - 1); xfs_bmbt_get_all(lastrec, &s); /* * Check we are allocating in the last extent (for delayed allocations) * or past the last extent for non-delayed allocations. */ *aeof = (off >= s.br_startoff && off < s.br_startoff + s.br_blockcount && isnullstartblock(s.br_startblock)) || off >= s.br_startoff + s.br_blockcount; return 0; } /* * Check if the endoff is outside the last extent. If so the caller will grow * the allocation to a stripe unit boundary. */ int /* error */ xfs_bmap_eof( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t endoff, /* file offset in fsblocks */ int whichfork, /* data or attribute fork */ int *eof) /* result value */ { xfs_fsblock_t blockcount; /* extent block count */ int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ xfs_extnum_t nextents; /* number of file extents */ xfs_fileoff_t startoff; /* extent starting file offset */ ASSERT(whichfork == XFS_DATA_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(NULL, ip, whichfork))) return error; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); if (nextents == 0) { *eof = 1; return 0; } /* * Go to the last extent */ lastrec = xfs_iext_get_ext(ifp, nextents - 1); startoff = xfs_bmbt_get_startoff(lastrec); blockcount = xfs_bmbt_get_blockcount(lastrec); *eof = endoff >= startoff + blockcount; return 0; } /* * Count fsblocks of the given fork. */ int /* error */ xfs_bmap_count_blocks( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ int whichfork, /* data or attr fork */ int *count) /* out: count of blocks */ { struct xfs_btree_block *block; /* current btree block */ xfs_fsblock_t bno; /* block # of "block" */ xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ __be64 *pp; /* pointer to block address */ bno = NULLFSBLOCK; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { xfs_bmap_count_leaves(ifp, 0, ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), count); return 0; } /* * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. */ block = ifp->if_broot; level = be16_to_cpu(block->bb_level); ASSERT(level > 0); pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); bno = be64_to_cpu(*pp); ASSERT(bno != NULLDFSBNO); ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) { XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; } /* * Recursively walks each level of a btree * to count total fsblocks is use. */ STATIC int /* error */ xfs_bmap_count_tree( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fsblock_t blockno, /* file system block number */ int levelin, /* level in btree */ int *count) /* Count of blocks */ { int error; xfs_buf_t *bp, *nbp; int level = levelin; __be64 *pp; xfs_fsblock_t bno = blockno; xfs_fsblock_t nextbno; struct xfs_btree_block *block, *nextblock; int numrecs; if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) return error; *count += 1; block = XFS_BUF_TO_BLOCK(bp); if (--level) { /* Not at node above leaves, count this level of nodes */ nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); while (nextbno != NULLFSBLOCK) { if ((error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp, XFS_BMAP_BTREE_REF))) return error; *count += 1; nextblock = XFS_BUF_TO_BLOCK(nbp); nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib); xfs_trans_brelse(tp, nbp); } /* Dive to the next level */ pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); bno = be64_to_cpu(*pp); if (unlikely((error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) { xfs_trans_brelse(tp, bp); XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } xfs_trans_brelse(tp, bp); } else { /* count all level 1 nodes and their leaves */ for (;;) { nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); numrecs = be16_to_cpu(block->bb_numrecs); xfs_bmap_disk_count_leaves(mp, block, numrecs, count); xfs_trans_brelse(tp, bp); if (nextbno == NULLFSBLOCK) break; bno = nextbno; if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) return error; *count += 1; block = XFS_BUF_TO_BLOCK(bp); } } return 0; } /* * Count leaf blocks given a range of extent records. */ STATIC void xfs_bmap_count_leaves( xfs_ifork_t *ifp, xfs_extnum_t idx, int numrecs, int *count) { int b; for (b = 0; b < numrecs; b++) { xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); *count += xfs_bmbt_get_blockcount(frp); } } /* * Count leaf blocks given a range of extent records originally * in btree format. */ STATIC void xfs_bmap_disk_count_leaves( struct xfs_mount *mp, struct xfs_btree_block *block, int numrecs, int *count) { int b; xfs_bmbt_rec_t *frp; for (b = 1; b <= numrecs; b++) { frp = XFS_BMBT_REC_ADDR(mp, block, b); *count += xfs_bmbt_disk_get_blockcount(frp); } } xfsprogs-3.1.9ubuntu2/libxfs/xfs.h0000664000000000000000000002667011650373061014071 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * This header is effectively a "namespace multiplexor" for the * user level XFS code. It provides all of the necessary stuff * such that we can build some parts of the XFS kernel code in * user space in a controlled fashion, and translates the names * used in the kernel into the names which libxfs is going to * make available to user tools. * * It should only ever be #include'd by XFS "kernel" code being * compiled in user space. * * Our goals here are to... * o "share" large amounts of complex code between user and * kernel space; * o shield the user tools from changes in the bleeding * edge kernel code, merging source changes when * convenient and not immediately (no symlinks); * o i.e. be able to merge changes to the kernel source back * into the affected user tools in a controlled fashion; * o provide a _minimalist_ life-support system for kernel * code in user land, not the "everything + the kitchen * sink" model which libsim had mutated into; * o allow the kernel code to be completely free of code * specifically there to support the user level build. */ #include typedef struct { dev_t dev; } xfs_buftarg_t; typedef __uint32_t uint_t; typedef __uint32_t inst_t; /* an instruction */ #define m_ddev_targp m_dev #define xfs_error_level 0 #define STATIC static #define ATTR_ROOT LIBXFS_ATTR_ROOT #define ATTR_SECURE LIBXFS_ATTR_SECURE #define ATTR_CREATE LIBXFS_ATTR_CREATE #define ATTR_REPLACE LIBXFS_ATTR_REPLACE #define ATTR_KERNOTIME 0 #define ATTR_KERNOVAL 0 #define IHOLD(ip) ((void) 0) #define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) #define XFS_QM_DQATTACH(mp,ip,flags) 0 #define XFS_ERROR(e) (e) #define XFS_ERROR_REPORT(e,l,mp) ((void) 0) #define XFS_ERRLEVEL_LOW 1 #define XFS_FORCED_SHUTDOWN(mp) 0 #define XFS_ILOCK_EXCL 0 #define XFS_STATS_INC(count) do { } while (0) #define XFS_STATS_DEC(count, x) do { } while (0) #define XFS_STATS_ADD(count, x) do { } while (0) #define XFS_TRANS_MOD_DQUOT_BYINO(mp,tp,ip,field,delta) do { } while (0) #define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 #define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 #define XFS_TEST_ERROR(expr,a,b,c) ( expr ) #define XFS_WANT_CORRUPTED_GOTO(expr,l) \ { if (!(expr)) { error = EFSCORRUPTED; goto l; } } #define XFS_WANT_CORRUPTED_RETURN(expr) \ { if (!(expr)) { return EFSCORRUPTED; } } #ifdef __GNUC__ #define __return_address __builtin_return_address(0) #endif /* miscellaneous kernel routines not in user space */ #define down_read(a) ((void) 0) #define up_read(a) ((void) 0) #define spin_lock_init(a) ((void) 0) #define spin_lock(a) ((void) 0) #define spin_unlock(a) ((void) 0) #define likely(x) (x) #define unlikely(x) (x) #define rcu_read_lock() ((void) 0) #define rcu_read_unlock() ((void) 0) /* * random32 is used for di_gen inode allocation, it must be zero for libxfs * or all sorts of badness can occur! */ #define random32() 0 #define PAGE_CACHE_SIZE getpagesize() static inline int __do_div(unsigned long long *n, unsigned base) { int __res; __res = (int)(((unsigned long) *n) % (unsigned) base); *n = ((unsigned long) *n) / (unsigned) base; return __res; } #define do_div(n,base) (__do_div((unsigned long long *)&(n), (base))) #define do_mod(a, b) ((a) % (b)) #define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) #define min_t(type,x,y) \ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) #define max_t(type,x,y) \ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) static inline __uint32_t __get_unaligned_be32(const __uint8_t *p) { return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; } static inline __uint64_t get_unaligned_be64(void *p) { return (__uint64_t)__get_unaligned_be32(p) << 32 | __get_unaligned_be32(p + 4); } static inline void __put_unaligned_be16(__uint16_t val, __uint8_t *p) { *p++ = val >> 8; *p++ = val; } static inline void __put_unaligned_be32(__uint32_t val, __uint8_t *p) { __put_unaligned_be16(val >> 16, p); __put_unaligned_be16(val, p + 2); } static inline void put_unaligned_be64(__uint64_t val, void *p) { __put_unaligned_be32(val >> 32, p); __put_unaligned_be32(val, p + 4); } static inline __attribute__((const)) int is_power_of_2(unsigned long n) { return (n != 0 && ((n & (n - 1)) == 0)); } /* * xfs_iroundup: round up argument to next power of two */ static inline uint roundup_pow_of_two(uint v) { int i; uint m; if ((v & (v - 1)) == 0) return v; ASSERT((v & 0x80000000) == 0); if ((v & (v + 1)) == 0) return v + 1; for (i = 0, m = 1; i < 31; i++, m <<= 1) { if (v & m) continue; v |= m; if ((v & (v + 1)) == 0) return v + 1; } ASSERT(0); return 0; } /* buffer management */ #define XFS_BUF_LOCK 0 #define XFS_BUF_TRYLOCK 0 #define XBF_LOCK XFS_BUF_LOCK #define XBF_TRYLOCK XFS_BUF_TRYLOCK #define XBF_DONT_BLOCK 0 #define XFS_BUF_GETERROR(bp) 0 #define XFS_BUF_DONE(bp) ((bp)->b_flags |= LIBXFS_B_UPTODATE) #define XFS_BUF_ISDONE(bp) ((bp)->b_flags & LIBXFS_B_UPTODATE) #define XFS_BUF_STALE(bp) ((bp)->b_flags |= LIBXFS_B_STALE) #define XFS_BUF_UNDELAYWRITE(bp) ((bp)->b_flags &= ~LIBXFS_B_DIRTY) #define XFS_BUF_SET_VTYPE(a,b) ((void) 0) #define XFS_BUF_SET_VTYPE_REF(a,b,c) ((void) 0) #define XFS_BUF_SET_BDSTRAT_FUNC(a,b) ((void) 0) #define xfs_incore(bt,blkno,len,lockit) 0 #define xfs_buf_relse(bp) libxfs_putbuf(bp) #define xfs_read_buf(mp,devp,blkno,len,f,bpp) \ (*(bpp) = libxfs_readbuf((devp), \ (blkno), (len), 1), 0) #define xfs_buf_get(devp,blkno,len,f) \ (libxfs_getbuf((devp), (blkno), (len))) #define xfs_bwrite(mp,bp) libxfs_writebuf((bp), 0) #define XBRW_READ LIBXFS_BREAD #define XBRW_WRITE LIBXFS_BWRITE #define xfs_buf_iomove(bp,off,len,data,f) libxfs_iomove(bp,off,len,data,f) #define xfs_buf_zero(bp,off,len) libxfs_iomove(bp,off,len,0,LIBXFS_BZERO) /* mount stuff */ #define XFS_MOUNT_32BITINODES LIBXFS_MOUNT_32BITINODES #define XFS_MOUNT_ATTR2 LIBXFS_MOUNT_ATTR2 #define XFS_MOUNT_SMALL_INUMS 0 /* ignored in userspace */ #define XFS_MOUNT_WSYNC 0 /* ignored in userspace */ #define XFS_MOUNT_NOALIGN 0 /* ignored in userspace */ #define xfs_icsb_modify_counters(mp, field, delta, rsvd) \ xfs_mod_incore_sb(mp, field, delta, rsvd) /* * Map XFS kernel routine names to libxfs versions */ #define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist #define xfs_attr_get libxfs_attr_get #define xfs_attr_set libxfs_attr_set #define xfs_attr_remove libxfs_attr_remove #define xfs_rtfree_extent libxfs_rtfree_extent #define xfs_fs_repair_cmn_err libxfs_fs_repair_cmn_err #define xfs_fs_cmn_err libxfs_fs_cmn_err #define xfs_bmap_finish libxfs_bmap_finish #define xfs_trans_ichgtime libxfs_trans_ichgtime #define xfs_mod_incore_sb libxfs_mod_incore_sb #define xfs_trans_alloc libxfs_trans_alloc #define xfs_trans_bhold libxfs_trans_bhold #define xfs_trans_binval libxfs_trans_binval #define xfs_trans_bjoin libxfs_trans_bjoin #define xfs_trans_brelse libxfs_trans_brelse #define xfs_trans_commit libxfs_trans_commit #define xfs_trans_cancel libxfs_trans_cancel #define xfs_trans_dup libxfs_trans_dup #define xfs_trans_get_buf libxfs_trans_get_buf #define xfs_trans_getsb libxfs_trans_getsb #define xfs_trans_iget libxfs_trans_iget #define xfs_trans_ihold libxfs_trans_ihold #define xfs_trans_ijoin libxfs_trans_ijoin #define xfs_trans_ijoin_ref libxfs_trans_ijoin_ref #define xfs_trans_inode_alloc_buf libxfs_trans_inode_alloc_buf #define xfs_trans_log_buf libxfs_trans_log_buf #define xfs_trans_log_inode libxfs_trans_log_inode #define xfs_trans_mod_sb libxfs_trans_mod_sb #define xfs_trans_read_buf libxfs_trans_read_buf #define xfs_trans_reserve libxfs_trans_reserve #define xfs_trans_get_block_res(tp) 1 #define xfs_trans_set_sync(tp) ((void) 0) #define xfs_trans_agblocks_delta(tp, d) #define xfs_trans_agflist_delta(tp, d) #define xfs_trans_agbtree_delta(tp, d) #define xfs_buf_readahead(a,b,c) ((void) 0) /* no readahead */ #define xfs_btree_reada_bufl(m,fsb,c) ((void) 0) #define xfs_btree_reada_bufs(m,fsb,c,x) ((void) 0) #define xfs_buftrace(x,y) ((void) 0) /* debug only */ #define xfs_cmn_err(tag,level,mp,fmt,args...) cmn_err(level,fmt, ## args) #define xfs_dir2_trace_args(where, args) ((void) 0) #define xfs_dir2_trace_args_b(where, args, bp) ((void) 0) #define xfs_dir2_trace_args_bb(where, args, lbp, dbp) ((void) 0) #define xfs_dir2_trace_args_bibii(where, args, bs, ss, bd, sd, c) ((void) 0) #define xfs_dir2_trace_args_db(where, args, db, bp) ((void) 0) #define xfs_dir2_trace_args_i(where, args, i) ((void) 0) #define xfs_dir2_trace_args_s(where, args, s) ((void) 0) #define xfs_dir2_trace_args_sb(where, args, s, bp) ((void) 0) #define xfs_sort qsort #define xfs_icsb_reinit_counters(mp) do { } while (0) #define xfs_initialize_perag_icache(pag) ((void) 0) #define xfs_ilock(ip,mode) ((void) 0) #define xfs_iunlock(ip,mode) ((void) 0) /* space allocation */ #define xfs_alloc_busy_search(tp,ag,b,len) 0 /* avoid unused variable warning */ #define xfs_alloc_busy_insert(tp,ag,b,len) ({ \ xfs_agnumber_t __foo = ag; \ __foo = 0; \ }) #define xfs_rotorstep 1 #define xfs_bmap_rtalloc(a) (ENOSYS) #define xfs_rtpick_extent(mp,tp,len,p) (ENOSYS) #define xfs_get_extsz_hint(ip) (0) #define xfs_inode_is_filestream(ip) (0) #define xfs_filestream_lookup_ag(ip) (0) #define xfs_filestream_new_ag(ip,ag) (0) /* * Prototypes for kernel static functions that are aren't in their * associated header files */ /* xfs_attr.c */ int xfs_attr_rmtval_get(struct xfs_da_args *); /* xfs_bmap.c */ void xfs_bmap_del_free(xfs_bmap_free_t *, xfs_bmap_free_item_t *, xfs_bmap_free_item_t *); /* xfs_da_btree.c */ int xfs_da_do_buf(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t *, xfs_dabuf_t **, int, int, inst_t *); /* xfs_inode.c */ void xfs_iflush_fork(xfs_inode_t *, xfs_dinode_t *, xfs_inode_log_item_t *, int, xfs_buf_t *); int xfs_iformat(xfs_inode_t *, xfs_dinode_t *); /* xfs_mount.c */ int xfs_initialize_perag_data(xfs_mount_t *, xfs_agnumber_t); void xfs_mount_common(xfs_mount_t *, xfs_sb_t *); /* * logitem.c and trans.c prototypes */ /* xfs_trans_item.c */ void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); void xfs_trans_del_item(struct xfs_log_item *); void xfs_trans_free_items(struct xfs_trans *, int); /* xfs_inode_item.c */ void xfs_inode_item_init (xfs_inode_t *, xfs_mount_t *); /* xfs_buf_item.c */ void xfs_buf_item_init (xfs_buf_t *, xfs_mount_t *); void xfs_buf_item_log (xfs_buf_log_item_t *, uint, uint); /* xfs_trans_buf.c */ xfs_buf_t *xfs_trans_buf_item_match (xfs_trans_t *, xfs_buftarg_t *, xfs_daddr_t, int); /* local source files */ int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); void xfs_trans_mod_sb(xfs_trans_t *, uint, long); xfsprogs-3.1.9ubuntu2/libxfs/init.h0000664000000000000000000000276111323235441014223 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LIBXFS_INIT_H #define LIBXFS_INIT_H struct stat64; extern int platform_check_ismounted (char *path, char *block, struct stat64 *sptr, int verbose); extern int platform_check_iswritable (char *path, char *block, struct stat64 *sptr, int fatal); extern int platform_set_blocksize (int fd, char *path, dev_t device, int bsz, int fatal); extern void platform_flush_device (int fd, dev_t device); extern char *platform_findrawpath(char *path); extern char *platform_findrawpath (char *path); extern char *platform_findblockpath (char *path); extern int platform_direct_blockdev (void); extern int platform_align_blockdev (void); extern int platform_nproc(void); extern unsigned long platform_physmem(void); /* in kilobytes */ extern int platform_has_uuid; #endif /* LIBXFS_INIT_H */ xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr.c0000664000000000000000000013231711650373061015112 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * xfs_attr.c * * Provide the external interfaces to manage attribute lists. */ /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ /* * Internal routines when attribute list fits inside the inode. */ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); /* * Internal routines when attribute list is one block. */ STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); /* * Internal routines when attribute list is more than one block. */ STATIC int xfs_attr_node_get(xfs_da_args_t *args); STATIC int xfs_attr_node_addname(xfs_da_args_t *args); STATIC int xfs_attr_node_removename(xfs_da_args_t *args); STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); /* * Routines to manipulate out-of-line attribute values. */ STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ STATIC int xfs_attr_name_to_xname( struct xfs_name *xname, const unsigned char *aname) { if (!aname) return EINVAL; xname->name = aname; xname->len = strlen((char *)aname); if (xname->len >= MAXNAMELEN) return EFAULT; /* match IRIX behaviour */ return 0; } STATIC int xfs_inode_hasattr( struct xfs_inode *ip) { if (!XFS_IFORK_Q(ip) || (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_anextents == 0)) return 0; return 1; } /*======================================================================== * Overall external interface routines. *========================================================================*/ STATIC int xfs_attr_get_int( struct xfs_inode *ip, struct xfs_name *name, unsigned char *value, int *valuelenp, int flags) { xfs_da_args_t args; int error; if (!xfs_inode_hasattr(ip)) return ENOATTR; /* * Fill in the arg structure for this request. */ memset((char *)&args, 0, sizeof(args)); args.name = name->name; args.namelen = name->len; args.value = value; args.valuelen = *valuelenp; args.flags = flags; args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = ip; args.whichfork = XFS_ATTR_FORK; /* * Decide on what work routines to call based on the inode size. */ if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { error = xfs_attr_shortform_getvalue(&args); } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) { error = xfs_attr_leaf_get(&args); } else { error = xfs_attr_node_get(&args); } /* * Return the number of bytes in the value to the caller. */ *valuelenp = args.valuelen; if (error == EEXIST) error = 0; return(error); } int xfs_attr_get( xfs_inode_t *ip, const unsigned char *name, unsigned char *value, int *valuelenp, int flags) { int error; struct xfs_name xname; XFS_STATS_INC(xs_attr_get); if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return(EIO); error = xfs_attr_name_to_xname(&xname, name); if (error) return error; xfs_ilock(ip, XFS_ILOCK_SHARED); error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags); xfs_iunlock(ip, XFS_ILOCK_SHARED); return(error); } /* * Calculate how many blocks we need for the new attribute, */ STATIC int xfs_attr_calc_size( struct xfs_inode *ip, int namelen, int valuelen, int *local) { struct xfs_mount *mp = ip->i_mount; int size; int nblks; /* * Determine space new attribute will use, and if it would be * "local" or "remote" (note: local != inline). */ size = xfs_attr_leaf_newentsize(namelen, valuelen, mp->m_sb.sb_blocksize, local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); if (*local) { if (size > (mp->m_sb.sb_blocksize >> 1)) { /* Double split possible */ nblks *= 2; } } else { /* * Out of line attribute, cannot double split, but * make room for the attribute value itself. */ uint dblocks = XFS_B_TO_FSB(mp, valuelen); nblks += dblocks; nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); } return nblks; } STATIC int xfs_attr_set_int( struct xfs_inode *dp, struct xfs_name *name, unsigned char *value, int valuelen, int flags) { xfs_da_args_t args; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; int error, err2, committed; xfs_mount_t *mp = dp->i_mount; int rsvd = (flags & ATTR_ROOT) != 0; int local; /* * Attach the dquots to the inode. */ error = xfs_qm_dqattach(dp, 0); if (error) return error; /* * If the inode doesn't have an attribute fork, add one. * (inode must not be locked when we call this routine) */ if (XFS_IFORK_Q(dp) == 0) { int sf_size = sizeof(xfs_attr_sf_hdr_t) + XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen); if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) return(error); } /* * Fill in the arg structure for this request. */ memset((char *)&args, 0, sizeof(args)); args.name = name->name; args.namelen = name->len; args.value = value; args.valuelen = valuelen; args.flags = flags; args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_ATTR_FORK; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; /* Size is now blocks for attribute data */ args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); /* * Start our first transaction of the day. * * All future transactions during this code must be "chained" off * this one via the trans_dup() call. All transactions will contain * the inode, and the inode will always be marked with trans_ihold(). * Since the inode will be locked in all transactions, we must log * the inode in every transaction to let it float upward through * the log. */ args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET); /* * Root fork attributes can use reserved data blocks for this * operation if necessary */ if (rsvd) args.trans->t_flags |= XFS_TRANS_RESERVE; if ((error = xfs_trans_reserve(args.trans, args.total, XFS_ATTRSET_LOG_RES(mp, args.total), 0, XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { xfs_trans_cancel(args.trans, 0); return(error); } xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : XFS_QMOPT_RES_REGBLKS); if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); return (error); } xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args.trans, dp); /* * If the attribute list is non-existent or a shortform list, * upgrade it to a single-leaf-block attribute list. */ if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) && (dp->i_d.di_anextents == 0))) { /* * Build initial attribute list (if required). */ if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) xfs_attr_shortform_create(&args); /* * Try to add the attr to the attribute list in * the inode. */ error = xfs_attr_shortform_addname(&args); if (error != ENOSPC) { /* * Commit the shortform mods, and we're done. * NOTE: this is also the error path (EEXIST, etc). */ ASSERT(args.trans != NULL); /* * If this is a synchronous mount, make sure that * the transaction goes to disk before returning * to the user. */ if (mp->m_flags & XFS_MOUNT_WSYNC) { xfs_trans_set_sync(args.trans); } if (!error && (flags & ATTR_KERNOTIME) == 0) { xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); } err2 = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); return(error == 0 ? err2 : error); } /* * It won't fit in the shortform, transform to a leaf block. * GROT: another possible req'mt for a double-split btree op. */ xfs_bmap_init(args.flist, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, &committed); } if (error) { ASSERT(committed); args.trans = NULL; xfs_bmap_cancel(&flist); goto out; } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args.trans, dp); } /* * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. */ error = xfs_trans_roll(&args.trans, dp); if (error) goto out; } if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { error = xfs_attr_leaf_addname(&args); } else { error = xfs_attr_node_addname(&args); } if (error) { goto out; } /* * If this is a synchronous mount, make sure that the * transaction goes to disk before returning to the user. */ if (mp->m_flags & XFS_MOUNT_WSYNC) { xfs_trans_set_sync(args.trans); } if ((flags & ATTR_KERNOTIME) == 0) xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); /* * Commit the last in the sequence of transactions. */ xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); return(error); out: if (args.trans) xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); return(error); } int xfs_attr_set( xfs_inode_t *dp, const unsigned char *name, unsigned char *value, int valuelen, int flags) { int error; struct xfs_name xname; XFS_STATS_INC(xs_attr_set); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return (EIO); error = xfs_attr_name_to_xname(&xname, name); if (error) return error; return xfs_attr_set_int(dp, &xname, value, valuelen, flags); } /* * Generic handler routine to remove a name from an attribute list. * Transitions attribute list from Btree to shortform as necessary. */ STATIC int xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) { xfs_da_args_t args; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; int error; xfs_mount_t *mp = dp->i_mount; /* * Fill in the arg structure for this request. */ memset((char *)&args, 0, sizeof(args)); args.name = name->name; args.namelen = name->len; args.flags = flags; args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.total = 0; args.whichfork = XFS_ATTR_FORK; /* * Attach the dquots to the inode. */ error = xfs_qm_dqattach(dp, 0); if (error) return error; /* * Start our first transaction of the day. * * All future transactions during this code must be "chained" off * this one via the trans_dup() call. All transactions will contain * the inode, and the inode will always be marked with trans_ihold(). * Since the inode will be locked in all transactions, we must log * the inode in every transaction to let it float upward through * the log. */ args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM); /* * Root fork attributes can use reserved data blocks for this * operation if necessary */ if (flags & ATTR_ROOT) args.trans->t_flags |= XFS_TRANS_RESERVE; if ((error = xfs_trans_reserve(args.trans, XFS_ATTRRM_SPACE_RES(mp), XFS_ATTRRM_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_ATTRRM_LOG_COUNT))) { xfs_trans_cancel(args.trans, 0); return(error); } xfs_ilock(dp, XFS_ILOCK_EXCL); /* * No need to make quota reservations here. We expect to release some * blocks not allocate in the common case. */ xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args.trans, dp); /* * Decide on what work routines to call based on the inode size. */ if (!xfs_inode_hasattr(dp)) { error = XFS_ERROR(ENOATTR); goto out; } if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); error = xfs_attr_shortform_remove(&args); if (error) { goto out; } } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { error = xfs_attr_leaf_removename(&args); } else { error = xfs_attr_node_removename(&args); } if (error) { goto out; } /* * If this is a synchronous mount, make sure that the * transaction goes to disk before returning to the user. */ if (mp->m_flags & XFS_MOUNT_WSYNC) { xfs_trans_set_sync(args.trans); } if ((flags & ATTR_KERNOTIME) == 0) xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); /* * Commit the last in the sequence of transactions. */ xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); return(error); out: if (args.trans) xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); return(error); } int xfs_attr_remove( xfs_inode_t *dp, const unsigned char *name, int flags) { int error; struct xfs_name xname; XFS_STATS_INC(xs_attr_remove); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return (EIO); error = xfs_attr_name_to_xname(&xname, name); if (error) return error; xfs_ilock(dp, XFS_ILOCK_SHARED); if (!xfs_inode_hasattr(dp)) { xfs_iunlock(dp, XFS_ILOCK_SHARED); return XFS_ERROR(ENOATTR); } xfs_iunlock(dp, XFS_ILOCK_SHARED); return xfs_attr_remove_int(dp, &xname, flags); } /*======================================================================== * External routines when attribute list is inside the inode *========================================================================*/ /* * Add a name to the shortform attribute list structure * This is the external routine. */ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args) { int newsize, forkoff, retval; retval = xfs_attr_shortform_lookup(args); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { return(retval); } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) return(retval); retval = xfs_attr_shortform_remove(args); ASSERT(retval == 0); } if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX) return(XFS_ERROR(ENOSPC)); newsize = XFS_ATTR_SF_TOTSIZE(args->dp); newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize); if (!forkoff) return(XFS_ERROR(ENOSPC)); xfs_attr_shortform_add(args, forkoff); return(0); } /*======================================================================== * External routines when attribute list is one block *========================================================================*/ /* * Add a name to the leaf attribute list structure * * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; xfs_dabuf_t *bp; int retval, error, committed, forkoff; /* * Read the (only) block in the attribute list in. */ dp = args->dp; args->blkno = 0; error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) return(error); ASSERT(bp != NULL); /* * Look up the given attribute in the leaf block. Figure out if * the given flags produce an error or call for an atomic rename. */ retval = xfs_attr_leaf_lookup_int(bp, args); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { xfs_da_brelse(args->trans, bp); return(retval); } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) { /* pure create op */ xfs_da_brelse(args->trans, bp); return(retval); } args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; args->rmtblkno2 = args->rmtblkno; args->rmtblkcnt2 = args->rmtblkcnt; } /* * Add the attribute to the leaf block, transitioning to a Btree * if required. */ retval = xfs_attr_leaf_add(bp, args); xfs_da_buf_done(bp); if (retval == ENOSPC) { /* * Promote the attribute list to the Btree format, then * Commit that transaction so that the node_addname() call * can manage its own transactions. */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return(error); } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } /* * Commit the current trans (including the inode) and start * a new one. */ error = xfs_trans_roll(&args->trans, dp); if (error) return (error); /* * Fob the whole rest of the problem off on the Btree code. */ error = xfs_attr_node_addname(args); return(error); } /* * Commit the transaction that added the attr name so that * later routines can manage their own transactions. */ error = xfs_trans_roll(&args->trans, dp); if (error) return (error); /* * If there was an out-of-line value, allocate the blocks we * identified for its storage and copy the value. This is done * after we create the attribute so that we don't overflow the * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { error = xfs_attr_rmtval_set(args); if (error) return(error); } /* * If this is an atomic rename operation, we must "flip" the * incomplete flags on the "new" and "old" attribute/value pairs * so that one disappears and one appears atomically. Then we * must remove the "old" attribute/value pair. */ if (args->op_flags & XFS_DA_OP_RENAME) { /* * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ error = xfs_attr_leaf_flipflags(args); if (error) return(error); /* * Dismantle the "old" attribute/value pair by removing * a "remote" value (if it exists). */ args->index = args->index2; args->blkno = args->blkno2; args->rmtblkno = args->rmtblkno2; args->rmtblkcnt = args->rmtblkcnt2; if (args->rmtblkno) { error = xfs_attr_rmtval_remove(args); if (error) return(error); } /* * Read in the block containing the "old" attr, then * remove the "old" attr from that block (neat, huh!) */ error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) return(error); ASSERT(bp != NULL); (void)xfs_attr_leaf_remove(bp, args); /* * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return(error); } /* * bmap_finish() may have committed the last trans * and started a new one. We need the inode to be * in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } } else xfs_da_buf_done(bp); /* * Commit the remove and start the next trans in series. */ error = xfs_trans_roll(&args->trans, dp); } else if (args->rmtblkno > 0) { /* * Added a "remote" value, just clear the incomplete flag. */ error = xfs_attr_leaf_clearflag(args); } return(error); } /* * Remove a name from the leaf attribute list structure * * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; xfs_dabuf_t *bp; int error, committed, forkoff; /* * Remove the attribute. */ dp = args->dp; args->blkno = 0; error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) { return(error); } ASSERT(bp != NULL); error = xfs_attr_leaf_lookup_int(bp, args); if (error == ENOATTR) { xfs_da_brelse(args->trans, bp); return(error); } (void)xfs_attr_leaf_remove(bp, args); /* * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return(error); } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } } else xfs_da_buf_done(bp); return(0); } /* * Look up a name in a leaf attribute list structure. * * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ STATIC int xfs_attr_leaf_get(xfs_da_args_t *args) { xfs_dabuf_t *bp; int error; args->blkno = 0; error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) return(error); ASSERT(bp != NULL); error = xfs_attr_leaf_lookup_int(bp, args); if (error != EEXIST) { xfs_da_brelse(args->trans, bp); return(error); } error = xfs_attr_leaf_getvalue(bp, args); xfs_da_brelse(args->trans, bp); if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { error = xfs_attr_rmtval_get(args); } return(error); } /*======================================================================== * External routines when attribute list size > XFS_LBSIZE(mp). *========================================================================*/ /* * Add a name to a Btree-format attribute list. * * This will involve walking down the Btree, and may involve splitting * leaf nodes and even splitting intermediate nodes up to and including * the root node (a special case of an intermediate node). * * "Remote" attribute values confuse the issue and atomic rename operations * add a whole extra layer of confusion on top of that. */ STATIC int xfs_attr_node_addname(xfs_da_args_t *args) { xfs_da_state_t *state; xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_mount_t *mp; int committed, retval, error; /* * Fill in bucket of arguments/results/context to carry around. */ dp = args->dp; mp = dp->i_mount; restart: state = xfs_da_state_alloc(); state->args = args; state->mp = mp; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; /* * Search to see if name already exists, and get back a pointer * to where it should go. */ error = xfs_da_node_lookup_int(state, &retval); if (error) goto out; blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { goto out; } else if (retval == EEXIST) { if (args->flags & ATTR_CREATE) goto out; args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ args->blkno2 = args->blkno; /* set 2nd entry info*/ args->index2 = args->index; args->rmtblkno2 = args->rmtblkno; args->rmtblkcnt2 = args->rmtblkcnt; args->rmtblkno = 0; args->rmtblkcnt = 0; } retval = xfs_attr_leaf_add(blk->bp, state->args); if (retval == ENOSPC) { if (state->path.active == 1) { /* * Its really a single leaf node, but it had * out-of-line values so it looked like it *might* * have been a b-tree. */ xfs_da_state_free(state); xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } /* * bmap_finish() may have committed the last trans * and started a new one. We need the inode to be * in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } /* * Commit the node conversion and start the next * trans in the chain. */ error = xfs_trans_roll(&args->trans, dp); if (error) goto out; goto restart; } /* * Split as many Btree elements as required. * This code tracks the new and old attr's location * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_split(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } } else { /* * Addition succeeded, update Btree hashvals. */ xfs_da_fixhashpath(state, &state->path); } /* * Kill the state structure, we're done with it and need to * allow the buffers to come back later. */ xfs_da_state_free(state); state = NULL; /* * Commit the leaf addition or btree split and start the next * trans in the chain. */ error = xfs_trans_roll(&args->trans, dp); if (error) goto out; /* * If there was an out-of-line value, allocate the blocks we * identified for its storage and copy the value. This is done * after we create the attribute so that we don't overflow the * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { error = xfs_attr_rmtval_set(args); if (error) return(error); } /* * If this is an atomic rename operation, we must "flip" the * incomplete flags on the "new" and "old" attribute/value pairs * so that one disappears and one appears atomically. Then we * must remove the "old" attribute/value pair. */ if (args->op_flags & XFS_DA_OP_RENAME) { /* * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ error = xfs_attr_leaf_flipflags(args); if (error) goto out; /* * Dismantle the "old" attribute/value pair by removing * a "remote" value (if it exists). */ args->index = args->index2; args->blkno = args->blkno2; args->rmtblkno = args->rmtblkno2; args->rmtblkcnt = args->rmtblkcnt2; if (args->rmtblkno) { error = xfs_attr_rmtval_remove(args); if (error) return(error); } /* * Re-find the "old" attribute entry after any split ops. * The INCOMPLETE flag means that we will find the "old" * attr, not the "new" one. */ args->flags |= XFS_ATTR_INCOMPLETE; state = xfs_da_state_alloc(); state->args = args; state->mp = mp; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; state->inleaf = 0; error = xfs_da_node_lookup_int(state, &retval); if (error) goto out; /* * Remove the name and update the hashvals in the tree. */ blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); error = xfs_attr_leaf_remove(blk->bp, args); xfs_da_fixhashpath(state, &state->path); /* * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } /* * bmap_finish() may have committed the last trans * and started a new one. We need the inode to be * in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } } /* * Commit and start the next trans in the chain. */ error = xfs_trans_roll(&args->trans, dp); if (error) goto out; } else if (args->rmtblkno > 0) { /* * Added a "remote" value, just clear the incomplete flag. */ error = xfs_attr_leaf_clearflag(args); if (error) goto out; } retval = error = 0; out: if (state) xfs_da_state_free(state); if (error) return(error); return(retval); } /* * Remove a name from a B-tree attribute list. * * This will involve walking down the Btree, and may involve joining * leaf nodes and even joining intermediate nodes up to and including * the root node (a special case of an intermediate node). */ STATIC int xfs_attr_node_removename(xfs_da_args_t *args) { xfs_da_state_t *state; xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_dabuf_t *bp; int retval, error, committed, forkoff; /* * Tie a string around our finger to remind us where we are. */ dp = args->dp; state = xfs_da_state_alloc(); state->args = args; state->mp = dp->i_mount; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; /* * Search to see if name exists, and get back a pointer to it. */ error = xfs_da_node_lookup_int(state, &retval); if (error || (retval != EEXIST)) { if (error == 0) error = retval; goto out; } /* * If there is an out-of-line value, de-allocate the blocks. * This is done before we remove the attribute so that we don't * overflow the maximum size of a transaction and/or hit a deadlock. */ blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->bp != NULL); ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); if (args->rmtblkno > 0) { /* * Fill in disk block numbers in the state structure * so that we can get the buffers back after we commit * several transactions in the following calls. */ error = xfs_attr_fillstate(state); if (error) goto out; /* * Mark the attribute as INCOMPLETE, then bunmapi() the * remote value. */ error = xfs_attr_leaf_setflag(args); if (error) goto out; error = xfs_attr_rmtval_remove(args); if (error) goto out; /* * Refill the state structure with buffers, the prior calls * released our buffers. */ error = xfs_attr_refillstate(state); if (error) goto out; } /* * Remove the name and update the hashvals in the tree. */ blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); retval = xfs_attr_leaf_remove(blk->bp, args); xfs_da_fixhashpath(state, &state->path); /* * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } /* * Commit the Btree join operation and start a new trans. */ error = xfs_trans_roll(&args->trans, dp); if (error) goto out; } /* * If the result is small enough, push it all into the inode. */ if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { /* * Have to get rid of the copy of this dabuf in the state. */ ASSERT(state->path.active == 1); ASSERT(state->path.blk[0].bp); xfs_da_buf_done(state->path.blk[0].bp); state->path.blk[0].bp = NULL; error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, XFS_ATTR_FORK); if (error) goto out; ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) bp->data)->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } /* * bmap_finish() may have committed the last trans * and started a new one. We need the inode to be * in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } } else xfs_da_brelse(args->trans, bp); } error = 0; out: xfs_da_state_free(state); return(error); } /* * Fill in the disk block numbers in the state structure for the buffers * that are attached to the state structure. * This is done so that we can quickly reattach ourselves to those buffers * after some set of transaction commits have released these buffers. */ STATIC int xfs_attr_fillstate(xfs_da_state_t *state) { xfs_da_state_path_t *path; xfs_da_state_blk_t *blk; int level; /* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path". */ path = &state->path; ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->bp) { blk->disk_blkno = xfs_da_blkno(blk->bp); xfs_da_buf_done(blk->bp); blk->bp = NULL; } else { blk->disk_blkno = 0; } } /* * Roll down the "altpath" in the state structure, storing the on-disk * block number for those buffers in the "altpath". */ path = &state->altpath; ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->bp) { blk->disk_blkno = xfs_da_blkno(blk->bp); xfs_da_buf_done(blk->bp); blk->bp = NULL; } else { blk->disk_blkno = 0; } } return(0); } /* * Reattach the buffers to the state structure based on the disk block * numbers stored in the state structure. * This is done after some set of transaction commits have released those * buffers from our grip. */ STATIC int xfs_attr_refillstate(xfs_da_state_t *state) { xfs_da_state_path_t *path; xfs_da_state_blk_t *blk; int level, error; /* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path". */ path = &state->path; ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->disk_blkno) { error = xfs_da_read_buf(state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, &blk->bp, XFS_ATTR_FORK); if (error) return(error); } else { blk->bp = NULL; } } /* * Roll down the "altpath" in the state structure, storing the on-disk * block number for those buffers in the "altpath". */ path = &state->altpath; ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); for (blk = path->blk, level = 0; level < path->active; blk++, level++) { if (blk->disk_blkno) { error = xfs_da_read_buf(state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, &blk->bp, XFS_ATTR_FORK); if (error) return(error); } else { blk->bp = NULL; } } return(0); } /* * Look up a filename in a node attribute list. * * This routine gets called for any attribute fork that has more than one * block, ie: both true Btree attr lists and for single-leaf-blocks with * "remote" values taking up more blocks. */ STATIC int xfs_attr_node_get(xfs_da_args_t *args) { xfs_da_state_t *state; xfs_da_state_blk_t *blk; int error, retval; int i; state = xfs_da_state_alloc(); state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_sb.sb_blocksize; state->node_ents = state->mp->m_attr_node_ents; /* * Search to see if name exists, and get back a pointer to it. */ error = xfs_da_node_lookup_int(state, &retval); if (error) { retval = error; } else if (retval == EEXIST) { blk = &state->path.blk[ state->path.active-1 ]; ASSERT(blk->bp != NULL); ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); /* * Get the value, local or "remote" */ retval = xfs_attr_leaf_getvalue(blk->bp, args); if (!retval && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { retval = xfs_attr_rmtval_get(args); } } /* * If not in a transaction, we have to release all the buffers. */ for (i = 0; i < state->path.active; i++) { xfs_da_brelse(args->trans, state->path.blk[i].bp); state->path.blk[i].bp = NULL; } xfs_da_state_free(state); return(retval); } /*======================================================================== * External routines for manipulating out-of-line attribute values. *========================================================================*/ /* * Read the value associated with an attribute from the out-of-line buffer * that we stored it in. */ int xfs_attr_rmtval_get(xfs_da_args_t *args) { xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; xfs_mount_t *mp; xfs_daddr_t dblkno; void *dst; xfs_buf_t *bp; int nmap, error, tmp, valuelen, blkcnt, i; xfs_dablk_t lblkno; ASSERT(!(args->flags & ATTR_KERNOVAL)); mp = args->dp->i_mount; dst = args->value; valuelen = args->valuelen; lblkno = args->rmtblkno; while (valuelen > 0) { nmap = ATTR_RMTVALUE_MAPSIZE; error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, NULL, 0, map, &nmap, NULL); if (error) return(error); ASSERT(nmap >= 1); for (i = 0; (i < nmap) && (valuelen > 0); i++) { ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && (map[i].br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno, blkcnt, XBF_LOCK | XBF_DONT_BLOCK, &bp); if (error) return(error); tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : XFS_BUF_SIZE(bp); xfs_buf_iomove(bp, 0, tmp, dst, XBRW_READ); xfs_buf_relse(bp); dst += tmp; valuelen -= tmp; lblkno += map[i].br_blockcount; } } ASSERT(valuelen == 0); return(0); } /* * Write the value associated with an attribute into the out-of-line buffer * that we have defined for it. */ STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args) { xfs_mount_t *mp; xfs_fileoff_t lfileoff; xfs_inode_t *dp; xfs_bmbt_irec_t map; xfs_daddr_t dblkno; void *src; xfs_buf_t *bp; xfs_dablk_t lblkno; int blkcnt, valuelen, nmap, error, tmp, committed; dp = args->dp; mp = dp->i_mount; src = args->value; /* * Find a "hole" in the attribute address space large enough for * us to drop the new attribute's value into. */ blkcnt = XFS_B_TO_FSB(mp, args->valuelen); lfileoff = 0; error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, XFS_ATTR_FORK); if (error) { return(error); } args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; args->rmtblkcnt = blkcnt; /* * Roll through the "value", allocating blocks on disk as required. */ while (blkcnt > 0) { /* * Allocate a single extent, up to the size of the value. */ xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, args->firstblock, args->total, &map, &nmap, args->flist); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return(error); } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, dp); } ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); lblkno += map.br_blockcount; blkcnt -= map.br_blockcount; /* * Start the next trans in the chain. */ error = xfs_trans_roll(&args->trans, dp); if (error) return (error); } /* * Roll through the "value", copying the attribute value to the * already-allocated blocks. Blocks are written synchronously * so that we can know they are all on disk before we turn off * the INCOMPLETE flag. */ lblkno = args->rmtblkno; valuelen = args->valuelen; while (valuelen > 0) { /* * Try to remember where we decided to put the value. */ xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, args->firstblock, 0, &map, &nmap, NULL); if (error) { return(error); } ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, XBF_LOCK | XBF_DONT_BLOCK); ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : XFS_BUF_SIZE(bp); xfs_buf_iomove(bp, 0, tmp, src, XBRW_WRITE); if (tmp < XFS_BUF_SIZE(bp)) xfs_buf_zero(bp, tmp, XFS_BUF_SIZE(bp) - tmp); if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */ return (error); } src += tmp; valuelen -= tmp; lblkno += map.br_blockcount; } ASSERT(valuelen == 0); return(0); } /* * Remove the value associated with an attribute by deleting the * out-of-line buffer that it is stored on. */ STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args) { xfs_mount_t *mp; xfs_bmbt_irec_t map; xfs_buf_t *bp; xfs_daddr_t dblkno; xfs_dablk_t lblkno; int valuelen, blkcnt, nmap, error, done, committed; mp = args->dp->i_mount; /* * Roll through the "value", invalidating the attribute value's * blocks. */ lblkno = args->rmtblkno; valuelen = args->rmtblkcnt; while (valuelen > 0) { /* * Try to remember where we decided to put the value. */ xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, args->firstblock, 0, &map, &nmap, args->flist); if (error) { return(error); } ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); /* * If the "remote" value is in the cache, remove it. */ bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK); if (bp) { XFS_BUF_STALE(bp); XFS_BUF_UNDELAYWRITE(bp); xfs_buf_relse(bp); bp = NULL; } valuelen -= map.br_blockcount; lblkno += map.br_blockcount; } /* * Keep de-allocating extents until the remote-value region is gone. */ lblkno = args->rmtblkno; blkcnt = args->rmtblkcnt; done = 0; while (!done) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1, args->firstblock, args->flist, &done); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, &committed); } if (error) { ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return(error); } /* * bmap_finish() may have committed the last trans and started * a new one. We need the inode to be in all transactions. */ if (committed) { xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL); xfs_trans_ihold(args->trans, args->dp); } /* * Close out trans and start the next one in the chain. */ error = xfs_trans_roll(&args->trans, args->dp); if (error) return (error); } return(0); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_btree.c0000664000000000000000000027347511650373061015254 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Cursor allocation zone. */ kmem_zone_t *xfs_btree_cur_zone; /* * Btree magic numbers. */ const __uint32_t xfs_magics[XFS_BTNUM_MAX] = { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC }; STATIC int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_lblock( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_btree_block *block, /* btree long form block pointer */ int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer for block, if any */ { int lblock_ok; /* block passes checks */ struct xfs_mount *mp; /* file system mount point */ mp = cur->bc_mp; lblock_ok = be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && be16_to_cpu(block->bb_level) == level && be16_to_cpu(block->bb_numrecs) <= cur->bc_ops->get_maxrecs(cur, level) && block->bb_u.l.bb_leftsib && (be64_to_cpu(block->bb_u.l.bb_leftsib) == NULLDFSBNO || XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib))) && block->bb_u.l.bb_rightsib && (be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO || XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib))); if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK, XFS_RANDOM_BTREE_CHECK_LBLOCK))) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; } STATIC int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_sblock( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_btree_block *block, /* btree short form block pointer */ int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer containing block */ { struct xfs_buf *agbp; /* buffer for ag. freespace struct */ struct xfs_agf *agf; /* ag. freespace structure */ xfs_agblock_t agflen; /* native ag. freespace length */ int sblock_ok; /* block passes checks */ agbp = cur->bc_private.a.agbp; agf = XFS_BUF_TO_AGF(agbp); agflen = be32_to_cpu(agf->agf_length); sblock_ok = be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && be16_to_cpu(block->bb_level) == level && be16_to_cpu(block->bb_numrecs) <= cur->bc_ops->get_maxrecs(cur, level) && (be32_to_cpu(block->bb_u.s.bb_leftsib) == NULLAGBLOCK || be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) && block->bb_u.s.bb_leftsib && (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK || be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) && block->bb_u.s.bb_rightsib; if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK, XFS_RANDOM_BTREE_CHECK_SBLOCK))) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); XFS_CORRUPTION_ERROR("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW, cur->bc_mp, block); return XFS_ERROR(EFSCORRUPTED); } return 0; } /* * Debug routine: check that block header is ok. */ int xfs_btree_check_block( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_btree_block *block, /* generic btree block pointer */ int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer containing block, if any */ { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return xfs_btree_check_lblock(cur, block, level, bp); else return xfs_btree_check_sblock(cur, block, level, bp); } /* * Check that (long) pointer is ok. */ int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_lptr( struct xfs_btree_cur *cur, /* btree cursor */ xfs_dfsbno_t bno, /* btree block disk address */ int level) /* btree block level */ { XFS_WANT_CORRUPTED_RETURN( level > 0 && bno != NULLDFSBNO && XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); return 0; } #ifdef DEBUG /* * Check that (short) pointer is ok. */ STATIC int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_sptr( struct xfs_btree_cur *cur, /* btree cursor */ xfs_agblock_t bno, /* btree block disk address */ int level) /* btree block level */ { xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks; XFS_WANT_CORRUPTED_RETURN( level > 0 && bno != NULLAGBLOCK && bno != 0 && bno < agblocks); return 0; } /* * Check that block ptr is ok. */ STATIC int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_ptr( struct xfs_btree_cur *cur, /* btree cursor */ union xfs_btree_ptr *ptr, /* btree block disk address */ int index, /* offset from ptr to check */ int level) /* btree block level */ { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { return xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]), level); } else { return xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]), level); } } #endif /* * Delete the btree cursor. */ void xfs_btree_del_cursor( xfs_btree_cur_t *cur, /* btree cursor */ int error) /* del because of error */ { int i; /* btree level */ /* * Clear the buffer pointers, and release the buffers. * If we're doing this in the face of an error, we * need to make sure to inspect all of the entries * in the bc_bufs array for buffers to be unlocked. * This is because some of the btree code works from * level n down to 0, and if we get an error along * the way we won't have initialized all the entries * down to 0. */ for (i = 0; i < cur->bc_nlevels; i++) { if (cur->bc_bufs[i]) xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]); else if (!error) break; } /* * Can't free a bmap cursor without having dealt with the * allocated indirect blocks' accounting. */ ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_private.b.allocated == 0); /* * Free the cursor. */ kmem_zone_free(xfs_btree_cur_zone, cur); } /* * Duplicate the btree cursor. * Allocate a new one, copy the record, re-get the buffers. */ int /* error */ xfs_btree_dup_cursor( xfs_btree_cur_t *cur, /* input cursor */ xfs_btree_cur_t **ncur) /* output cursor */ { xfs_buf_t *bp; /* btree block's buffer pointer */ int error; /* error return value */ int i; /* level number of btree block */ xfs_mount_t *mp; /* mount structure for filesystem */ xfs_btree_cur_t *new; /* new cursor value */ xfs_trans_t *tp; /* transaction pointer, can be NULL */ tp = cur->bc_tp; mp = cur->bc_mp; /* * Allocate a new cursor like the old one. */ new = cur->bc_ops->dup_cursor(cur); /* * Copy the record currently in the cursor. */ new->bc_rec = cur->bc_rec; /* * For each level current, re-get the buffer and copy the ptr value. */ for (i = 0; i < new->bc_nlevels; i++) { new->bc_ptrs[i] = cur->bc_ptrs[i]; new->bc_ra[i] = cur->bc_ra[i]; if ((bp = cur->bc_bufs[i])) { if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) { xfs_btree_del_cursor(new, error); *ncur = NULL; return error; } new->bc_bufs[i] = bp; ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); } else new->bc_bufs[i] = NULL; } *ncur = new; return 0; } /* * XFS btree block layout and addressing: * * There are two types of blocks in the btree: leaf and non-leaf blocks. * * The leaf record start with a header then followed by records containing * the values. A non-leaf block also starts with the same header, and * then first contains lookup keys followed by an equal number of pointers * to the btree blocks at the previous level. * * +--------+-------+-------+-------+-------+-------+-------+ * Leaf: | header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N | * +--------+-------+-------+-------+-------+-------+-------+ * * +--------+-------+-------+-------+-------+-------+-------+ * Non-Leaf: | header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N | * +--------+-------+-------+-------+-------+-------+-------+ * * The header is called struct xfs_btree_block for reasons better left unknown * and comes in different versions for short (32bit) and long (64bit) block * pointers. The record and key structures are defined by the btree instances * and opaque to the btree core. The block pointers are simple disk endian * integers, available in a short (32bit) and long (64bit) variant. * * The helpers below calculate the offset of a given record, key or pointer * into a btree block (xfs_btree_*_offset) or return a pointer to the given * record, key or pointer (xfs_btree_*_addr). Note that all addressing * inside the btree block is done using indices starting at one, not zero! */ /* * Return size of the btree block header for this btree instance. */ static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur) { return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? XFS_BTREE_LBLOCK_LEN : XFS_BTREE_SBLOCK_LEN; } /* * Return size of btree block pointers for this btree instance. */ static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur) { return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? sizeof(__be64) : sizeof(__be32); } /* * Calculate offset of the n-th record in a btree block. */ STATIC size_t xfs_btree_rec_offset( struct xfs_btree_cur *cur, int n) { return xfs_btree_block_len(cur) + (n - 1) * cur->bc_ops->rec_len; } /* * Calculate offset of the n-th key in a btree block. */ STATIC size_t xfs_btree_key_offset( struct xfs_btree_cur *cur, int n) { return xfs_btree_block_len(cur) + (n - 1) * cur->bc_ops->key_len; } /* * Calculate offset of the n-th block pointer in a btree block. */ STATIC size_t xfs_btree_ptr_offset( struct xfs_btree_cur *cur, int n, int level) { return xfs_btree_block_len(cur) + cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len + (n - 1) * xfs_btree_ptr_len(cur); } /* * Return a pointer to the n-th record in the btree block. */ STATIC union xfs_btree_rec * xfs_btree_rec_addr( struct xfs_btree_cur *cur, int n, struct xfs_btree_block *block) { return (union xfs_btree_rec *) ((char *)block + xfs_btree_rec_offset(cur, n)); } /* * Return a pointer to the n-th key in the btree block. */ STATIC union xfs_btree_key * xfs_btree_key_addr( struct xfs_btree_cur *cur, int n, struct xfs_btree_block *block) { return (union xfs_btree_key *) ((char *)block + xfs_btree_key_offset(cur, n)); } /* * Return a pointer to the n-th block pointer in the btree block. */ STATIC union xfs_btree_ptr * xfs_btree_ptr_addr( struct xfs_btree_cur *cur, int n, struct xfs_btree_block *block) { int level = xfs_btree_get_level(block); ASSERT(block->bb_level != 0); return (union xfs_btree_ptr *) ((char *)block + xfs_btree_ptr_offset(cur, n, level)); } /* * Get a the root block which is stored in the inode. * * For now this btree implementation assumes the btree root is always * stored in the if_broot field of an inode fork. */ STATIC struct xfs_btree_block * xfs_btree_get_iroot( struct xfs_btree_cur *cur) { struct xfs_ifork *ifp; ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); return (struct xfs_btree_block *)ifp->if_broot; } /* * Retrieve the block pointer from the cursor at the given level. * This may be an inode btree root or from a buffer. */ STATIC struct xfs_btree_block * /* generic btree block pointer */ xfs_btree_get_block( struct xfs_btree_cur *cur, /* btree cursor */ int level, /* level in btree */ struct xfs_buf **bpp) /* buffer containing the block */ { if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && (level == cur->bc_nlevels - 1)) { *bpp = NULL; return xfs_btree_get_iroot(cur); } *bpp = cur->bc_bufs[level]; return XFS_BUF_TO_BLOCK(*bpp); } /* * Get a buffer for the block, return it with no data read. * Long-form addressing. */ xfs_buf_t * /* buffer for fsbno */ xfs_btree_get_bufl( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t fsbno, /* file system block number */ uint lock) /* lock flags for get_buf */ { xfs_buf_t *bp; /* buffer pointer (return value) */ xfs_daddr_t d; /* real disk block address */ ASSERT(fsbno != NULLFSBLOCK); d = XFS_FSB_TO_DADDR(mp, fsbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); return bp; } /* * Get a buffer for the block, return it with no data read. * Short-form addressing. */ xfs_buf_t * /* buffer for agno/agbno */ xfs_btree_get_bufs( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ uint lock) /* lock flags for get_buf */ { xfs_buf_t *bp; /* buffer pointer (return value) */ xfs_daddr_t d; /* real disk block address */ ASSERT(agno != NULLAGNUMBER); ASSERT(agbno != NULLAGBLOCK); d = XFS_AGB_TO_DADDR(mp, agno, agbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); return bp; } /* * Check for the cursor referring to the last block at the given level. */ int /* 1=is last block, 0=not last block */ xfs_btree_islastblock( xfs_btree_cur_t *cur, /* btree cursor */ int level) /* level to check */ { struct xfs_btree_block *block; /* generic btree block pointer */ xfs_buf_t *bp; /* buffer containing block */ block = xfs_btree_get_block(cur, level, &bp); xfs_btree_check_block(cur, block, level, bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO; else return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; } /* * Change the cursor to point to the first record at the given level. * Other levels are unaffected. */ STATIC int /* success=1, failure=0 */ xfs_btree_firstrec( xfs_btree_cur_t *cur, /* btree cursor */ int level) /* level to change */ { struct xfs_btree_block *block; /* generic btree block pointer */ xfs_buf_t *bp; /* buffer containing block */ /* * Get the block pointer for this level. */ block = xfs_btree_get_block(cur, level, &bp); xfs_btree_check_block(cur, block, level, bp); /* * It's empty, there is no such record. */ if (!block->bb_numrecs) return 0; /* * Set the ptr value to 1, that's the first record/key. */ cur->bc_ptrs[level] = 1; return 1; } /* * Change the cursor to point to the last record in the current block * at the given level. Other levels are unaffected. */ STATIC int /* success=1, failure=0 */ xfs_btree_lastrec( xfs_btree_cur_t *cur, /* btree cursor */ int level) /* level to change */ { struct xfs_btree_block *block; /* generic btree block pointer */ xfs_buf_t *bp; /* buffer containing block */ /* * Get the block pointer for this level. */ block = xfs_btree_get_block(cur, level, &bp); xfs_btree_check_block(cur, block, level, bp); /* * It's empty, there is no such record. */ if (!block->bb_numrecs) return 0; /* * Set the ptr value to numrecs, that's the last record/key. */ cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs); return 1; } /* * Compute first and last byte offsets for the fields given. * Interprets the offsets table, which contains struct field offsets. */ void xfs_btree_offsets( __int64_t fields, /* bitmask of fields */ const short *offsets, /* table of field offsets */ int nbits, /* number of bits to inspect */ int *first, /* output: first byte offset */ int *last) /* output: last byte offset */ { int i; /* current bit number */ __int64_t imask; /* mask for current bit number */ ASSERT(fields != 0); /* * Find the lowest bit, so the first byte offset. */ for (i = 0, imask = 1LL; ; i++, imask <<= 1) { if (imask & fields) { *first = offsets[i]; break; } } /* * Find the highest bit, so the last byte offset. */ for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) { if (imask & fields) { *last = offsets[i + 1] - 1; break; } } } /* * Get a buffer for the block, return it read in. * Long-form addressing. */ int /* error */ xfs_btree_read_bufl( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t fsbno, /* file system block number */ uint lock, /* lock flags for read_buf */ xfs_buf_t **bpp, /* buffer for fsbno */ int refval) /* ref count value for buffer */ { xfs_buf_t *bp; /* return value */ xfs_daddr_t d; /* real disk block address */ int error; ASSERT(fsbno != NULLFSBLOCK); d = XFS_FSB_TO_DADDR(mp, fsbno); if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, mp->m_bsize, lock, &bp))) { return error; } ASSERT(!bp || !XFS_BUF_GETERROR(bp)); if (bp != NULL) { XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); } *bpp = bp; return 0; } /* * Get a buffer for the block, return it read in. * Short-form addressing. */ int /* error */ xfs_btree_read_bufs( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ uint lock, /* lock flags for read_buf */ xfs_buf_t **bpp, /* buffer for agno/agbno */ int refval) /* ref count value for buffer */ { xfs_buf_t *bp; /* return value */ xfs_daddr_t d; /* real disk block address */ int error; ASSERT(agno != NULLAGNUMBER); ASSERT(agbno != NULLAGBLOCK); d = XFS_AGB_TO_DADDR(mp, agno, agbno); if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, mp->m_bsize, lock, &bp))) { return error; } ASSERT(!bp || !XFS_BUF_GETERROR(bp)); if (bp != NULL) { switch (refval) { case XFS_ALLOC_BTREE_REF: XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); break; case XFS_INO_BTREE_REF: XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval); break; } } *bpp = bp; return 0; } STATIC int xfs_btree_readahead_lblock( struct xfs_btree_cur *cur, int lr, struct xfs_btree_block *block) { int rval = 0; xfs_dfsbno_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { xfs_btree_reada_bufl(cur->bc_mp, left, 1); rval++; } if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { xfs_btree_reada_bufl(cur->bc_mp, right, 1); rval++; } return rval; } STATIC int xfs_btree_readahead_sblock( struct xfs_btree_cur *cur, int lr, struct xfs_btree_block *block) { int rval = 0; xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib); xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib); if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, left, 1); rval++; } if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, right, 1); rval++; } return rval; } /* * Read-ahead btree blocks, at the given level. * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA. */ STATIC int xfs_btree_readahead( struct xfs_btree_cur *cur, /* btree cursor */ int lev, /* level in btree */ int lr) /* left/right bits */ { struct xfs_btree_block *block; /* * No readahead needed if we are at the root level and the * btree root is stored in the inode. */ if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && (lev == cur->bc_nlevels - 1)) return 0; if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev]) return 0; cur->bc_ra[lev] |= lr; block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return xfs_btree_readahead_lblock(cur, lr, block); return xfs_btree_readahead_sblock(cur, lr, block); } /* * Set the buffer for level "lev" in the cursor to bp, releasing * any previous buffer. */ STATIC void xfs_btree_setbuf( xfs_btree_cur_t *cur, /* btree cursor */ int lev, /* level in btree */ xfs_buf_t *bp) /* new buffer to set */ { struct xfs_btree_block *b; /* btree block */ if (cur->bc_bufs[lev]) xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[lev]); cur->bc_bufs[lev] = bp; cur->bc_ra[lev] = 0; b = XFS_BUF_TO_BLOCK(bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO) cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO) cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; } else { if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK) cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK) cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; } } STATIC int xfs_btree_ptr_is_null( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return be64_to_cpu(ptr->l) == NULLDFSBNO; else return be32_to_cpu(ptr->s) == NULLAGBLOCK; } STATIC void xfs_btree_set_ptr_null( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) ptr->l = cpu_to_be64(NULLDFSBNO); else ptr->s = cpu_to_be32(NULLAGBLOCK); } /* * Get/set/init sibling pointers */ STATIC void xfs_btree_get_sibling( struct xfs_btree_cur *cur, struct xfs_btree_block *block, union xfs_btree_ptr *ptr, int lr) { ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { if (lr == XFS_BB_RIGHTSIB) ptr->l = block->bb_u.l.bb_rightsib; else ptr->l = block->bb_u.l.bb_leftsib; } else { if (lr == XFS_BB_RIGHTSIB) ptr->s = block->bb_u.s.bb_rightsib; else ptr->s = block->bb_u.s.bb_leftsib; } } STATIC void xfs_btree_set_sibling( struct xfs_btree_cur *cur, struct xfs_btree_block *block, union xfs_btree_ptr *ptr, int lr) { ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { if (lr == XFS_BB_RIGHTSIB) block->bb_u.l.bb_rightsib = ptr->l; else block->bb_u.l.bb_leftsib = ptr->l; } else { if (lr == XFS_BB_RIGHTSIB) block->bb_u.s.bb_rightsib = ptr->s; else block->bb_u.s.bb_leftsib = ptr->s; } } STATIC void xfs_btree_init_block( struct xfs_btree_cur *cur, int level, int numrecs, struct xfs_btree_block *new) /* new block */ { new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); new->bb_level = cpu_to_be16(level); new->bb_numrecs = cpu_to_be16(numrecs); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { new->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); new->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); } else { new->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); new->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); } } /* * Return true if ptr is the last record in the btree and * we need to track updateѕ to this record. The decision * will be further refined in the update_lastrec method. */ STATIC int xfs_btree_is_lastrec( struct xfs_btree_cur *cur, struct xfs_btree_block *block, int level) { union xfs_btree_ptr ptr; if (level > 0) return 0; if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE)) return 0; xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); if (!xfs_btree_ptr_is_null(cur, &ptr)) return 0; return 1; } STATIC void xfs_btree_buf_to_ptr( struct xfs_btree_cur *cur, struct xfs_buf *bp, union xfs_btree_ptr *ptr) { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp))); else { ptr->s = cpu_to_be32(xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp))); } } STATIC xfs_daddr_t xfs_btree_ptr_to_daddr( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { ASSERT(be64_to_cpu(ptr->l) != NULLDFSBNO); return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); } else { ASSERT(cur->bc_private.a.agno != NULLAGNUMBER); ASSERT(be32_to_cpu(ptr->s) != NULLAGBLOCK); return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, be32_to_cpu(ptr->s)); } } STATIC void xfs_btree_set_refs( struct xfs_btree_cur *cur, struct xfs_buf *bp) { switch (cur->bc_btnum) { case XFS_BTNUM_BNO: case XFS_BTNUM_CNT: XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_ALLOC_BTREE_REF); break; case XFS_BTNUM_INO: XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, XFS_INO_BTREE_REF); break; case XFS_BTNUM_BMAP: XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_BMAP_BTREE_REF); break; default: ASSERT(0); } } STATIC int xfs_btree_get_buf_block( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr, int flags, struct xfs_btree_block **block, struct xfs_buf **bpp) { struct xfs_mount *mp = cur->bc_mp; xfs_daddr_t d; /* need to sort out how callers deal with failures first */ ASSERT(!(flags & XBF_TRYLOCK)); d = xfs_btree_ptr_to_daddr(cur, ptr); *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags); ASSERT(*bpp); ASSERT(!XFS_BUF_GETERROR(*bpp)); *block = XFS_BUF_TO_BLOCK(*bpp); return 0; } /* * Read in the buffer at the given ptr and return the buffer and * the block pointer within the buffer. */ STATIC int xfs_btree_read_buf_block( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr, int level, int flags, struct xfs_btree_block **block, struct xfs_buf **bpp) { struct xfs_mount *mp = cur->bc_mp; xfs_daddr_t d; int error; /* need to sort out how callers deal with failures first */ ASSERT(!(flags & XBF_TRYLOCK)); d = xfs_btree_ptr_to_daddr(cur, ptr); error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags, bpp); if (error) return error; ASSERT(*bpp != NULL); ASSERT(!XFS_BUF_GETERROR(*bpp)); xfs_btree_set_refs(cur, *bpp); *block = XFS_BUF_TO_BLOCK(*bpp); error = xfs_btree_check_block(cur, *block, level, *bpp); if (error) xfs_trans_brelse(cur->bc_tp, *bpp); return error; } /* * Copy keys from one btree block to another. */ STATIC void xfs_btree_copy_keys( struct xfs_btree_cur *cur, union xfs_btree_key *dst_key, union xfs_btree_key *src_key, int numkeys) { ASSERT(numkeys >= 0); memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len); } /* * Copy records from one btree block to another. */ STATIC void xfs_btree_copy_recs( struct xfs_btree_cur *cur, union xfs_btree_rec *dst_rec, union xfs_btree_rec *src_rec, int numrecs) { ASSERT(numrecs >= 0); memcpy(dst_rec, src_rec, numrecs * cur->bc_ops->rec_len); } /* * Copy block pointers from one btree block to another. */ STATIC void xfs_btree_copy_ptrs( struct xfs_btree_cur *cur, union xfs_btree_ptr *dst_ptr, union xfs_btree_ptr *src_ptr, int numptrs) { ASSERT(numptrs >= 0); memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur)); } /* * Shift keys one index left/right inside a single btree block. */ STATIC void xfs_btree_shift_keys( struct xfs_btree_cur *cur, union xfs_btree_key *key, int dir, int numkeys) { char *dst_key; ASSERT(numkeys >= 0); ASSERT(dir == 1 || dir == -1); dst_key = (char *)key + (dir * cur->bc_ops->key_len); memmove(dst_key, key, numkeys * cur->bc_ops->key_len); } /* * Shift records one index left/right inside a single btree block. */ STATIC void xfs_btree_shift_recs( struct xfs_btree_cur *cur, union xfs_btree_rec *rec, int dir, int numrecs) { char *dst_rec; ASSERT(numrecs >= 0); ASSERT(dir == 1 || dir == -1); dst_rec = (char *)rec + (dir * cur->bc_ops->rec_len); memmove(dst_rec, rec, numrecs * cur->bc_ops->rec_len); } /* * Shift block pointers one index left/right inside a single btree block. */ STATIC void xfs_btree_shift_ptrs( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr, int dir, int numptrs) { char *dst_ptr; ASSERT(numptrs >= 0); ASSERT(dir == 1 || dir == -1); dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur)); memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur)); } /* * Log key values from the btree block. */ STATIC void xfs_btree_log_keys( struct xfs_btree_cur *cur, struct xfs_buf *bp, int first, int last) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); if (bp) { xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_key_offset(cur, first), xfs_btree_key_offset(cur, last + 1) - 1); } else { xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, xfs_ilog_fbroot(cur->bc_private.b.whichfork)); } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); } /* * Log record values from the btree block. */ void xfs_btree_log_recs( struct xfs_btree_cur *cur, struct xfs_buf *bp, int first, int last) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_rec_offset(cur, first), xfs_btree_rec_offset(cur, last + 1) - 1); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); } /* * Log block pointer fields from a btree block (nonleaf). */ STATIC void xfs_btree_log_ptrs( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_buf *bp, /* buffer containing btree block */ int first, /* index of first pointer to log */ int last) /* index of last pointer to log */ { XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); if (bp) { struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); int level = xfs_btree_get_level(block); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_ptr_offset(cur, first, level), xfs_btree_ptr_offset(cur, last + 1, level) - 1); } else { xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, xfs_ilog_fbroot(cur->bc_private.b.whichfork)); } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); } /* * Log fields from a btree block header. */ void xfs_btree_log_block( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_buf *bp, /* buffer containing btree block */ int fields) /* mask of fields: XFS_BB_... */ { int first; /* first byte offset logged */ int last; /* last byte offset logged */ static const short soffsets[] = { /* table of offsets (short) */ offsetof(struct xfs_btree_block, bb_magic), offsetof(struct xfs_btree_block, bb_level), offsetof(struct xfs_btree_block, bb_numrecs), offsetof(struct xfs_btree_block, bb_u.s.bb_leftsib), offsetof(struct xfs_btree_block, bb_u.s.bb_rightsib), XFS_BTREE_SBLOCK_LEN }; static const short loffsets[] = { /* table of offsets (long) */ offsetof(struct xfs_btree_block, bb_magic), offsetof(struct xfs_btree_block, bb_level), offsetof(struct xfs_btree_block, bb_numrecs), offsetof(struct xfs_btree_block, bb_u.l.bb_leftsib), offsetof(struct xfs_btree_block, bb_u.l.bb_rightsib), XFS_BTREE_LBLOCK_LEN }; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGBI(cur, bp, fields); if (bp) { xfs_btree_offsets(fields, (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? loffsets : soffsets, XFS_BB_NUM_BITS, &first, &last); xfs_trans_log_buf(cur->bc_tp, bp, first, last); } else { xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, xfs_ilog_fbroot(cur->bc_private.b.whichfork)); } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); } /* * Increment cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. */ int /* error */ xfs_btree_increment( struct xfs_btree_cur *cur, int level, int *stat) /* success/failure */ { struct xfs_btree_block *block; union xfs_btree_ptr ptr; struct xfs_buf *bp; int error; /* error return value */ int lev; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, level); ASSERT(level < cur->bc_nlevels); /* Read-ahead to the right at this level. */ xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); /* Get a pointer to the btree block. */ block = xfs_btree_get_block(cur, level, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) goto error0; #endif /* We're done if we remain in the block after the increment. */ if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block)) goto out1; /* Fail if we just went off the right edge of the tree. */ xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); if (xfs_btree_ptr_is_null(cur, &ptr)) goto out0; XFS_BTREE_STATS_INC(cur, increment); /* * March up the tree incrementing pointers. * Stop when we don't go off the right edge of a block. */ for (lev = level + 1; lev < cur->bc_nlevels; lev++) { block = xfs_btree_get_block(cur, lev, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, lev, bp); if (error) goto error0; #endif if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block)) break; /* Read-ahead the right block for the next loop. */ xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA); } /* * If we went off the root then we are either seriously * confused or have the tree root in an inode. */ if (lev == cur->bc_nlevels) { if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) goto out0; ASSERT(0); error = EFSCORRUPTED; goto error0; } ASSERT(lev < cur->bc_nlevels); /* * Now walk back down the tree, fixing up the cursor's buffer * pointers and key numbers. */ for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { union xfs_btree_ptr *ptrp; ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); error = xfs_btree_read_buf_block(cur, ptrp, --lev, 0, &block, &bp); if (error) goto error0; xfs_btree_setbuf(cur, lev, bp); cur->bc_ptrs[lev] = 1; } out1: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Decrement cursor by one record at the level. * For nonzero levels the leaf-ward information is untouched. */ int /* error */ xfs_btree_decrement( struct xfs_btree_cur *cur, int level, int *stat) /* success/failure */ { struct xfs_btree_block *block; xfs_buf_t *bp; int error; /* error return value */ int lev; union xfs_btree_ptr ptr; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, level); ASSERT(level < cur->bc_nlevels); /* Read-ahead to the left at this level. */ xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA); /* We're done if we remain in the block after the decrement. */ if (--cur->bc_ptrs[level] > 0) goto out1; /* Get a pointer to the btree block. */ block = xfs_btree_get_block(cur, level, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) goto error0; #endif /* Fail if we just went off the left edge of the tree. */ xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB); if (xfs_btree_ptr_is_null(cur, &ptr)) goto out0; XFS_BTREE_STATS_INC(cur, decrement); /* * March up the tree decrementing pointers. * Stop when we don't go off the left edge of a block. */ for (lev = level + 1; lev < cur->bc_nlevels; lev++) { if (--cur->bc_ptrs[lev] > 0) break; /* Read-ahead the left block for the next loop. */ xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA); } /* * If we went off the root then we are seriously confused. * or the root of the tree is in an inode. */ if (lev == cur->bc_nlevels) { if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) goto out0; ASSERT(0); error = EFSCORRUPTED; goto error0; } ASSERT(lev < cur->bc_nlevels); /* * Now walk back down the tree, fixing up the cursor's buffer * pointers and key numbers. */ for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { union xfs_btree_ptr *ptrp; ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); error = xfs_btree_read_buf_block(cur, ptrp, --lev, 0, &block, &bp); if (error) goto error0; xfs_btree_setbuf(cur, lev, bp); cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block); } out1: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } STATIC int xfs_btree_lookup_get_block( struct xfs_btree_cur *cur, /* btree cursor */ int level, /* level in the btree */ union xfs_btree_ptr *pp, /* ptr to btree block */ struct xfs_btree_block **blkp) /* return btree block */ { struct xfs_buf *bp; /* buffer pointer for btree block */ int error = 0; /* special case the root block if in an inode */ if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && (level == cur->bc_nlevels - 1)) { *blkp = xfs_btree_get_iroot(cur); return 0; } /* * If the old buffer at this level for the disk address we are * looking for re-use it. * * Otherwise throw it away and get a new one. */ bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) == xfs_btree_ptr_to_daddr(cur, pp)) { *blkp = XFS_BUF_TO_BLOCK(bp); return 0; } error = xfs_btree_read_buf_block(cur, pp, level, 0, blkp, &bp); if (error) return error; xfs_btree_setbuf(cur, level, bp); return 0; } /* * Get current search key. For level 0 we don't actually have a key * structure so we make one up from the record. For all other levels * we just return the right key. */ STATIC union xfs_btree_key * xfs_lookup_get_search_key( struct xfs_btree_cur *cur, int level, int keyno, struct xfs_btree_block *block, union xfs_btree_key *kp) { if (level == 0) { cur->bc_ops->init_key_from_rec(kp, xfs_btree_rec_addr(cur, keyno, block)); return kp; } return xfs_btree_key_addr(cur, keyno, block); } /* * Lookup the record. The cursor is made to point to it, based on dir. * Return 0 if can't find any such record, 1 for success. */ int /* error */ xfs_btree_lookup( struct xfs_btree_cur *cur, /* btree cursor */ xfs_lookup_t dir, /* <=, ==, or >= */ int *stat) /* success/failure */ { struct xfs_btree_block *block; /* current btree block */ __int64_t diff; /* difference for the current key */ int error; /* error return value */ int keyno; /* current key number */ int level; /* level in the btree */ union xfs_btree_ptr *pp; /* ptr to btree block */ union xfs_btree_ptr ptr; /* ptr to btree block */ XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, dir); XFS_BTREE_STATS_INC(cur, lookup); block = NULL; keyno = 0; /* initialise start pointer from cursor */ cur->bc_ops->init_ptr_from_cur(cur, &ptr); pp = &ptr; /* * Iterate over each level in the btree, starting at the root. * For each level above the leaves, find the key we need, based * on the lookup record, then follow the corresponding block * pointer down to the next level. */ for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) { /* Get the block we need to do the lookup on. */ error = xfs_btree_lookup_get_block(cur, level, pp, &block); if (error) goto error0; if (diff == 0) { /* * If we already had a key match at a higher level, we * know we need to use the first entry in this block. */ keyno = 1; } else { /* Otherwise search this block. Do a binary search. */ int high; /* high entry number */ int low; /* low entry number */ /* Set low and high entry numbers, 1-based. */ low = 1; high = xfs_btree_get_numrecs(block); if (!high) { /* Block is empty, must be an empty leaf. */ ASSERT(level == 0 && cur->bc_nlevels == 1); cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } /* Binary search the block. */ while (low <= high) { union xfs_btree_key key; union xfs_btree_key *kp; XFS_BTREE_STATS_INC(cur, compare); /* keyno is average of low and high. */ keyno = (low + high) >> 1; /* Get current search key */ kp = xfs_lookup_get_search_key(cur, level, keyno, block, &key); /* * Compute difference to get next direction: * - less than, move right * - greater than, move left * - equal, we're done */ diff = cur->bc_ops->key_diff(cur, kp); if (diff < 0) low = keyno + 1; else if (diff > 0) high = keyno - 1; else break; } } /* * If there are more levels, set up for the next level * by getting the block number and filling in the cursor. */ if (level > 0) { /* * If we moved left, need the previous key number, * unless there isn't one. */ if (diff > 0 && --keyno < 1) keyno = 1; pp = xfs_btree_ptr_addr(cur, keyno, block); #ifdef DEBUG error = xfs_btree_check_ptr(cur, pp, 0, level); if (error) goto error0; #endif cur->bc_ptrs[level] = keyno; } } /* Done with the search. See if we need to adjust the results. */ if (dir != XFS_LOOKUP_LE && diff < 0) { keyno++; /* * If ge search and we went off the end of the block, but it's * not the last block, we're in the wrong block. */ xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); if (dir == XFS_LOOKUP_GE && keyno > xfs_btree_get_numrecs(block) && !xfs_btree_ptr_is_null(cur, &ptr)) { int i; cur->bc_ptrs[0] = keyno; error = xfs_btree_increment(cur, 0, &i); if (error) goto error0; XFS_WANT_CORRUPTED_RETURN(i == 1); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; } } else if (dir == XFS_LOOKUP_LE && diff > 0) keyno--; cur->bc_ptrs[0] = keyno; /* Return if we succeeded or not. */ if (keyno == 0 || keyno > xfs_btree_get_numrecs(block)) *stat = 0; else if (dir != XFS_LOOKUP_EQ || diff == 0) *stat = 1; else *stat = 0; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Update keys at all levels from here to the root along the cursor's path. */ STATIC int xfs_btree_updkey( struct xfs_btree_cur *cur, union xfs_btree_key *keyp, int level) { struct xfs_btree_block *block; struct xfs_buf *bp; union xfs_btree_key *kp; int ptr; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGIK(cur, level, keyp); ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1); /* * Go up the tree from this level toward the root. * At each level, update the key value to the value input. * Stop when we reach a level where the cursor isn't pointing * at the first entry in the block. */ for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) { #ifdef DEBUG int error; #endif block = xfs_btree_get_block(cur, level, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } #endif ptr = cur->bc_ptrs[level]; kp = xfs_btree_key_addr(cur, ptr, block); xfs_btree_copy_keys(cur, kp, keyp, 1); xfs_btree_log_keys(cur, bp, ptr, ptr); } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; } /* * Update the record referred to by cur to the value in the * given record. This either works (return 0) or gets an * EFSCORRUPTED error. */ int xfs_btree_update( struct xfs_btree_cur *cur, union xfs_btree_rec *rec) { struct xfs_btree_block *block; struct xfs_buf *bp; int error; int ptr; union xfs_btree_rec *rp; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGR(cur, rec); /* Pick up the current block. */ block = xfs_btree_get_block(cur, 0, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, 0, bp); if (error) goto error0; #endif /* Get the address of the rec to be updated. */ ptr = cur->bc_ptrs[0]; rp = xfs_btree_rec_addr(cur, ptr, block); /* Fill in the new contents and log them. */ xfs_btree_copy_recs(cur, rp, rec, 1); xfs_btree_log_recs(cur, bp, ptr, ptr); /* * If we are tracking the last record in the tree and * we are at the far right edge of the tree, update it. */ if (xfs_btree_is_lastrec(cur, block, 0)) { cur->bc_ops->update_lastrec(cur, block, rec, ptr, LASTREC_UPDATE); } /* Updating first rec in leaf. Pass new key value up to our parent. */ if (ptr == 1) { union xfs_btree_key key; cur->bc_ops->init_key_from_rec(&key, rec); error = xfs_btree_updkey(cur, &key, 1); if (error) goto error0; } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Move 1 record left from cur/level if possible. * Update cur to reflect the new path. */ STATIC int /* error */ xfs_btree_lshift( struct xfs_btree_cur *cur, int level, int *stat) /* success/failure */ { union xfs_btree_key key; /* btree key */ struct xfs_buf *lbp; /* left buffer pointer */ struct xfs_btree_block *left; /* left btree block */ int lrecs; /* left record count */ struct xfs_buf *rbp; /* right buffer pointer */ struct xfs_btree_block *right; /* right btree block */ int rrecs; /* right record count */ union xfs_btree_ptr lptr; /* left btree pointer */ union xfs_btree_key *rkp = NULL; /* right btree key */ union xfs_btree_ptr *rpp = NULL; /* right address pointer */ union xfs_btree_rec *rrp = NULL; /* right record pointer */ int error; /* error return value */ XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, level); if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && level == cur->bc_nlevels - 1) goto out0; /* Set up variables for this block as "right". */ right = xfs_btree_get_block(cur, level, &rbp); #ifdef DEBUG error = xfs_btree_check_block(cur, right, level, rbp); if (error) goto error0; #endif /* If we've got no left sibling then we can't shift an entry left. */ xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); if (xfs_btree_ptr_is_null(cur, &lptr)) goto out0; /* * If the cursor entry is the one that would be moved, don't * do it... it's too complicated. */ if (cur->bc_ptrs[level] <= 1) goto out0; /* Set up the left neighbor as "left". */ error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp); if (error) goto error0; /* If it's full, it can't take another entry. */ lrecs = xfs_btree_get_numrecs(left); if (lrecs == cur->bc_ops->get_maxrecs(cur, level)) goto out0; rrecs = xfs_btree_get_numrecs(right); /* * We add one entry to the left side and remove one for the right side. * Account for it here, the changes will be updated on disk and logged * later. */ lrecs++; rrecs--; XFS_BTREE_STATS_INC(cur, lshift); XFS_BTREE_STATS_ADD(cur, moves, 1); /* * If non-leaf, copy a key and a ptr to the left block. * Log the changes to the left block. */ if (level > 0) { /* It's a non-leaf. Move keys and pointers. */ union xfs_btree_key *lkp; /* left btree key */ union xfs_btree_ptr *lpp; /* left address pointer */ lkp = xfs_btree_key_addr(cur, lrecs, left); rkp = xfs_btree_key_addr(cur, 1, right); lpp = xfs_btree_ptr_addr(cur, lrecs, left); rpp = xfs_btree_ptr_addr(cur, 1, right); #ifdef DEBUG error = xfs_btree_check_ptr(cur, rpp, 0, level); if (error) goto error0; #endif xfs_btree_copy_keys(cur, lkp, rkp, 1); xfs_btree_copy_ptrs(cur, lpp, rpp, 1); xfs_btree_log_keys(cur, lbp, lrecs, lrecs); xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs); ASSERT(cur->bc_ops->keys_inorder(cur, xfs_btree_key_addr(cur, lrecs - 1, left), lkp)); } else { /* It's a leaf. Move records. */ union xfs_btree_rec *lrp; /* left record pointer */ lrp = xfs_btree_rec_addr(cur, lrecs, left); rrp = xfs_btree_rec_addr(cur, 1, right); xfs_btree_copy_recs(cur, lrp, rrp, 1); xfs_btree_log_recs(cur, lbp, lrecs, lrecs); ASSERT(cur->bc_ops->recs_inorder(cur, xfs_btree_rec_addr(cur, lrecs - 1, left), lrp)); } xfs_btree_set_numrecs(left, lrecs); xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS); xfs_btree_set_numrecs(right, rrecs); xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS); /* * Slide the contents of right down one entry. */ XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1); if (level > 0) { /* It's a nonleaf. operate on keys and ptrs */ #ifdef DEBUG int i; /* loop index */ for (i = 0; i < rrecs; i++) { error = xfs_btree_check_ptr(cur, rpp, i + 1, level); if (error) goto error0; } #endif xfs_btree_shift_keys(cur, xfs_btree_key_addr(cur, 2, right), -1, rrecs); xfs_btree_shift_ptrs(cur, xfs_btree_ptr_addr(cur, 2, right), -1, rrecs); xfs_btree_log_keys(cur, rbp, 1, rrecs); xfs_btree_log_ptrs(cur, rbp, 1, rrecs); } else { /* It's a leaf. operate on records */ xfs_btree_shift_recs(cur, xfs_btree_rec_addr(cur, 2, right), -1, rrecs); xfs_btree_log_recs(cur, rbp, 1, rrecs); /* * If it's the first record in the block, we'll need a key * structure to pass up to the next level (updkey). */ cur->bc_ops->init_key_from_rec(&key, xfs_btree_rec_addr(cur, 1, right)); rkp = &key; } /* Update the parent key values of right. */ error = xfs_btree_updkey(cur, rkp, level + 1); if (error) goto error0; /* Slide the cursor value left one. */ cur->bc_ptrs[level]--; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Move 1 record right from cur/level if possible. * Update cur to reflect the new path. */ STATIC int /* error */ xfs_btree_rshift( struct xfs_btree_cur *cur, int level, int *stat) /* success/failure */ { union xfs_btree_key key; /* btree key */ struct xfs_buf *lbp; /* left buffer pointer */ struct xfs_btree_block *left; /* left btree block */ struct xfs_buf *rbp; /* right buffer pointer */ struct xfs_btree_block *right; /* right btree block */ struct xfs_btree_cur *tcur; /* temporary btree cursor */ union xfs_btree_ptr rptr; /* right block pointer */ union xfs_btree_key *rkp; /* right btree key */ int rrecs; /* right record count */ int lrecs; /* left record count */ int error; /* error return value */ int i; /* loop counter */ XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, level); if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && (level == cur->bc_nlevels - 1)) goto out0; /* Set up variables for this block as "left". */ left = xfs_btree_get_block(cur, level, &lbp); #ifdef DEBUG error = xfs_btree_check_block(cur, left, level, lbp); if (error) goto error0; #endif /* If we've got no right sibling then we can't shift an entry right. */ xfs_btree_get_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB); if (xfs_btree_ptr_is_null(cur, &rptr)) goto out0; /* * If the cursor entry is the one that would be moved, don't * do it... it's too complicated. */ lrecs = xfs_btree_get_numrecs(left); if (cur->bc_ptrs[level] >= lrecs) goto out0; /* Set up the right neighbor as "right". */ error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp); if (error) goto error0; /* If it's full, it can't take another entry. */ rrecs = xfs_btree_get_numrecs(right); if (rrecs == cur->bc_ops->get_maxrecs(cur, level)) goto out0; XFS_BTREE_STATS_INC(cur, rshift); XFS_BTREE_STATS_ADD(cur, moves, rrecs); /* * Make a hole at the start of the right neighbor block, then * copy the last left block entry to the hole. */ if (level > 0) { /* It's a nonleaf. make a hole in the keys and ptrs */ union xfs_btree_key *lkp; union xfs_btree_ptr *lpp; union xfs_btree_ptr *rpp; lkp = xfs_btree_key_addr(cur, lrecs, left); lpp = xfs_btree_ptr_addr(cur, lrecs, left); rkp = xfs_btree_key_addr(cur, 1, right); rpp = xfs_btree_ptr_addr(cur, 1, right); #ifdef DEBUG for (i = rrecs - 1; i >= 0; i--) { error = xfs_btree_check_ptr(cur, rpp, i, level); if (error) goto error0; } #endif xfs_btree_shift_keys(cur, rkp, 1, rrecs); xfs_btree_shift_ptrs(cur, rpp, 1, rrecs); #ifdef DEBUG error = xfs_btree_check_ptr(cur, lpp, 0, level); if (error) goto error0; #endif /* Now put the new data in, and log it. */ xfs_btree_copy_keys(cur, rkp, lkp, 1); xfs_btree_copy_ptrs(cur, rpp, lpp, 1); xfs_btree_log_keys(cur, rbp, 1, rrecs + 1); xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1); ASSERT(cur->bc_ops->keys_inorder(cur, rkp, xfs_btree_key_addr(cur, 2, right))); } else { /* It's a leaf. make a hole in the records */ union xfs_btree_rec *lrp; union xfs_btree_rec *rrp; lrp = xfs_btree_rec_addr(cur, lrecs, left); rrp = xfs_btree_rec_addr(cur, 1, right); xfs_btree_shift_recs(cur, rrp, 1, rrecs); /* Now put the new data in, and log it. */ xfs_btree_copy_recs(cur, rrp, lrp, 1); xfs_btree_log_recs(cur, rbp, 1, rrecs + 1); cur->bc_ops->init_key_from_rec(&key, rrp); rkp = &key; ASSERT(cur->bc_ops->recs_inorder(cur, rrp, xfs_btree_rec_addr(cur, 2, right))); } /* * Decrement and log left's numrecs, bump and log right's numrecs. */ xfs_btree_set_numrecs(left, --lrecs); xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS); xfs_btree_set_numrecs(right, ++rrecs); xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS); /* * Using a temporary cursor, update the parent key values of the * block on the right. */ error = xfs_btree_dup_cursor(cur, &tcur); if (error) goto error0; i = xfs_btree_lastrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); error = xfs_btree_increment(tcur, level, &i); if (error) goto error1; error = xfs_btree_updkey(tcur, rkp, level + 1); if (error) goto error1; xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; error1: XFS_BTREE_TRACE_CURSOR(tcur, XBT_ERROR); xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); return error; } /* * Split cur/level block in half. * Return new block number and the key to its first * record (to be inserted into parent). */ STATIC int /* error */ xfs_btree_split( struct xfs_btree_cur *cur, int level, union xfs_btree_ptr *ptrp, union xfs_btree_key *key, struct xfs_btree_cur **curp, int *stat) /* success/failure */ { union xfs_btree_ptr lptr; /* left sibling block ptr */ struct xfs_buf *lbp; /* left buffer pointer */ struct xfs_btree_block *left; /* left btree block */ union xfs_btree_ptr rptr; /* right sibling block ptr */ struct xfs_buf *rbp; /* right buffer pointer */ struct xfs_btree_block *right; /* right btree block */ union xfs_btree_ptr rrptr; /* right-right sibling ptr */ struct xfs_buf *rrbp; /* right-right buffer pointer */ struct xfs_btree_block *rrblock; /* right-right btree block */ int lrecs; int rrecs; int src_index; int error; /* error return value */ #ifdef DEBUG int i; #endif XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGIPK(cur, level, *ptrp, key); XFS_BTREE_STATS_INC(cur, split); /* Set up left block (current one). */ left = xfs_btree_get_block(cur, level, &lbp); #ifdef DEBUG error = xfs_btree_check_block(cur, left, level, lbp); if (error) goto error0; #endif xfs_btree_buf_to_ptr(cur, lbp, &lptr); /* Allocate the new block. If we can't do it, we're toast. Give up. */ error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, 1, stat); if (error) goto error0; if (*stat == 0) goto out0; XFS_BTREE_STATS_INC(cur, alloc); /* Set up the new block as "right". */ error = xfs_btree_get_buf_block(cur, &rptr, 0, &right, &rbp); if (error) goto error0; /* Fill in the btree header for the new right block. */ xfs_btree_init_block(cur, xfs_btree_get_level(left), 0, right); /* * Split the entries between the old and the new block evenly. * Make sure that if there's an odd number of entries now, that * each new block will have the same number of entries. */ lrecs = xfs_btree_get_numrecs(left); rrecs = lrecs / 2; if ((lrecs & 1) && cur->bc_ptrs[level] <= rrecs + 1) rrecs++; src_index = (lrecs - rrecs + 1); XFS_BTREE_STATS_ADD(cur, moves, rrecs); /* * Copy btree block entries from the left block over to the * new block, the right. Update the right block and log the * changes. */ if (level > 0) { /* It's a non-leaf. Move keys and pointers. */ union xfs_btree_key *lkp; /* left btree key */ union xfs_btree_ptr *lpp; /* left address pointer */ union xfs_btree_key *rkp; /* right btree key */ union xfs_btree_ptr *rpp; /* right address pointer */ lkp = xfs_btree_key_addr(cur, src_index, left); lpp = xfs_btree_ptr_addr(cur, src_index, left); rkp = xfs_btree_key_addr(cur, 1, right); rpp = xfs_btree_ptr_addr(cur, 1, right); #ifdef DEBUG for (i = src_index; i < rrecs; i++) { error = xfs_btree_check_ptr(cur, lpp, i, level); if (error) goto error0; } #endif xfs_btree_copy_keys(cur, rkp, lkp, rrecs); xfs_btree_copy_ptrs(cur, rpp, lpp, rrecs); xfs_btree_log_keys(cur, rbp, 1, rrecs); xfs_btree_log_ptrs(cur, rbp, 1, rrecs); /* Grab the keys to the entries moved to the right block */ xfs_btree_copy_keys(cur, key, rkp, 1); } else { /* It's a leaf. Move records. */ union xfs_btree_rec *lrp; /* left record pointer */ union xfs_btree_rec *rrp; /* right record pointer */ lrp = xfs_btree_rec_addr(cur, src_index, left); rrp = xfs_btree_rec_addr(cur, 1, right); xfs_btree_copy_recs(cur, rrp, lrp, rrecs); xfs_btree_log_recs(cur, rbp, 1, rrecs); cur->bc_ops->init_key_from_rec(key, xfs_btree_rec_addr(cur, 1, right)); } /* * Find the left block number by looking in the buffer. * Adjust numrecs, sibling pointers. */ xfs_btree_get_sibling(cur, left, &rrptr, XFS_BB_RIGHTSIB); xfs_btree_set_sibling(cur, right, &rrptr, XFS_BB_RIGHTSIB); xfs_btree_set_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); xfs_btree_set_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB); lrecs -= rrecs; xfs_btree_set_numrecs(left, lrecs); xfs_btree_set_numrecs(right, xfs_btree_get_numrecs(right) + rrecs); xfs_btree_log_block(cur, rbp, XFS_BB_ALL_BITS); xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); /* * If there's a block to the new block's right, make that block * point back to right instead of to left. */ if (!xfs_btree_ptr_is_null(cur, &rrptr)) { error = xfs_btree_read_buf_block(cur, &rrptr, level, 0, &rrblock, &rrbp); if (error) goto error0; xfs_btree_set_sibling(cur, rrblock, &rptr, XFS_BB_LEFTSIB); xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB); } /* * If the cursor is really in the right block, move it there. * If it's just pointing past the last entry in left, then we'll * insert there, so don't change anything in that case. */ if (cur->bc_ptrs[level] > lrecs + 1) { xfs_btree_setbuf(cur, level, rbp); cur->bc_ptrs[level] -= lrecs; } /* * If there are more levels, we'll need another cursor which refers * the right block, no matter where this cursor was. */ if (level + 1 < cur->bc_nlevels) { error = xfs_btree_dup_cursor(cur, curp); if (error) goto error0; (*curp)->bc_ptrs[level + 1]++; } *ptrp = rptr; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Copy the old inode root contents into a real block and make the * broot point to it. */ int /* error */ xfs_btree_new_iroot( struct xfs_btree_cur *cur, /* btree cursor */ int *logflags, /* logging flags for inode */ int *stat) /* return status - 0 fail */ { struct xfs_buf *cbp; /* buffer for cblock */ struct xfs_btree_block *block; /* btree block */ struct xfs_btree_block *cblock; /* child btree block */ union xfs_btree_key *ckp; /* child key pointer */ union xfs_btree_ptr *cpp; /* child ptr pointer */ union xfs_btree_key *kp; /* pointer to btree key */ union xfs_btree_ptr *pp; /* pointer to block addr */ union xfs_btree_ptr nptr; /* new block addr */ int level; /* btree level */ int error; /* error return code */ #ifdef DEBUG int i; /* loop counter */ #endif XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_STATS_INC(cur, newroot); ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); level = cur->bc_nlevels - 1; block = xfs_btree_get_iroot(cur); pp = xfs_btree_ptr_addr(cur, 1, block); /* Allocate the new block. If we can't do it, we're toast. Give up. */ error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat); if (error) goto error0; if (*stat == 0) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; } XFS_BTREE_STATS_INC(cur, alloc); /* Copy the root into a real block. */ error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp); if (error) goto error0; memcpy(cblock, block, xfs_btree_block_len(cur)); be16_add_cpu(&block->bb_level, 1); xfs_btree_set_numrecs(block, 1); cur->bc_nlevels++; cur->bc_ptrs[level + 1] = 1; kp = xfs_btree_key_addr(cur, 1, block); ckp = xfs_btree_key_addr(cur, 1, cblock); xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock)); cpp = xfs_btree_ptr_addr(cur, 1, cblock); #ifdef DEBUG for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { error = xfs_btree_check_ptr(cur, pp, i, level); if (error) goto error0; } #endif xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock)); #ifdef DEBUG error = xfs_btree_check_ptr(cur, &nptr, 0, level); if (error) goto error0; #endif xfs_btree_copy_ptrs(cur, pp, &nptr, 1); xfs_iroot_realloc(cur->bc_private.b.ip, 1 - xfs_btree_get_numrecs(cblock), cur->bc_private.b.whichfork); xfs_btree_setbuf(cur, level, cbp); /* * Do all this logging at the end so that * the root is at the right level. */ xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); *logflags |= XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork); *stat = 1; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Allocate a new root block, fill it in. */ STATIC int /* error */ xfs_btree_new_root( struct xfs_btree_cur *cur, /* btree cursor */ int *stat) /* success/failure */ { struct xfs_btree_block *block; /* one half of the old root block */ struct xfs_buf *bp; /* buffer containing block */ int error; /* error return value */ struct xfs_buf *lbp; /* left buffer pointer */ struct xfs_btree_block *left; /* left btree block */ struct xfs_buf *nbp; /* new (root) buffer */ struct xfs_btree_block *new; /* new (root) btree block */ int nptr; /* new value for key index, 1 or 2 */ struct xfs_buf *rbp; /* right buffer pointer */ struct xfs_btree_block *right; /* right btree block */ union xfs_btree_ptr rptr; union xfs_btree_ptr lptr; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_STATS_INC(cur, newroot); /* initialise our start point from the cursor */ cur->bc_ops->init_ptr_from_cur(cur, &rptr); /* Allocate the new block. If we can't do it, we're toast. Give up. */ error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, 1, stat); if (error) goto error0; if (*stat == 0) goto out0; XFS_BTREE_STATS_INC(cur, alloc); /* Set up the new block. */ error = xfs_btree_get_buf_block(cur, &lptr, 0, &new, &nbp); if (error) goto error0; /* Set the root in the holding structure increasing the level by 1. */ cur->bc_ops->set_root(cur, &lptr, 1); /* * At the previous root level there are now two blocks: the old root, * and the new block generated when it was split. We don't know which * one the cursor is pointing at, so we set up variables "left" and * "right" for each case. */ block = xfs_btree_get_block(cur, cur->bc_nlevels - 1, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, cur->bc_nlevels - 1, bp); if (error) goto error0; #endif xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); if (!xfs_btree_ptr_is_null(cur, &rptr)) { /* Our block is left, pick up the right block. */ lbp = bp; xfs_btree_buf_to_ptr(cur, lbp, &lptr); left = block; error = xfs_btree_read_buf_block(cur, &rptr, cur->bc_nlevels - 1, 0, &right, &rbp); if (error) goto error0; bp = rbp; nptr = 1; } else { /* Our block is right, pick up the left block. */ rbp = bp; xfs_btree_buf_to_ptr(cur, rbp, &rptr); right = block; xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); error = xfs_btree_read_buf_block(cur, &lptr, cur->bc_nlevels - 1, 0, &left, &lbp); if (error) goto error0; bp = lbp; nptr = 2; } /* Fill in the new block's btree header and log it. */ xfs_btree_init_block(cur, cur->bc_nlevels, 2, new); xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) && !xfs_btree_ptr_is_null(cur, &rptr)); /* Fill in the key data in the new root. */ if (xfs_btree_get_level(left) > 0) { xfs_btree_copy_keys(cur, xfs_btree_key_addr(cur, 1, new), xfs_btree_key_addr(cur, 1, left), 1); xfs_btree_copy_keys(cur, xfs_btree_key_addr(cur, 2, new), xfs_btree_key_addr(cur, 1, right), 1); } else { cur->bc_ops->init_key_from_rec( xfs_btree_key_addr(cur, 1, new), xfs_btree_rec_addr(cur, 1, left)); cur->bc_ops->init_key_from_rec( xfs_btree_key_addr(cur, 2, new), xfs_btree_rec_addr(cur, 1, right)); } xfs_btree_log_keys(cur, nbp, 1, 2); /* Fill in the pointer data in the new root. */ xfs_btree_copy_ptrs(cur, xfs_btree_ptr_addr(cur, 1, new), &lptr, 1); xfs_btree_copy_ptrs(cur, xfs_btree_ptr_addr(cur, 2, new), &rptr, 1); xfs_btree_log_ptrs(cur, nbp, 1, 2); /* Fix up the cursor. */ xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); cur->bc_ptrs[cur->bc_nlevels] = nptr; cur->bc_nlevels++; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } STATIC int xfs_btree_make_block_unfull( struct xfs_btree_cur *cur, /* btree cursor */ int level, /* btree level */ int numrecs,/* # of recs in block */ int *oindex,/* old tree index */ int *index, /* new tree index */ union xfs_btree_ptr *nptr, /* new btree ptr */ struct xfs_btree_cur **ncur, /* new btree cursor */ union xfs_btree_rec *nrec, /* new record */ int *stat) { union xfs_btree_key key; /* new btree key value */ int error = 0; if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && level == cur->bc_nlevels - 1) { struct xfs_inode *ip = cur->bc_private.b.ip; if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) { /* A root block that can be made bigger. */ xfs_iroot_realloc(ip, 1, cur->bc_private.b.whichfork); } else { /* A root block that needs replacing */ int logflags = 0; error = xfs_btree_new_iroot(cur, &logflags, stat); if (error || *stat == 0) return error; xfs_trans_log_inode(cur->bc_tp, ip, logflags); } return 0; } /* First, try shifting an entry to the right neighbor. */ error = xfs_btree_rshift(cur, level, stat); if (error || *stat) return error; /* Next, try shifting an entry to the left neighbor. */ error = xfs_btree_lshift(cur, level, stat); if (error) return error; if (*stat) { *oindex = *index = cur->bc_ptrs[level]; return 0; } /* * Next, try splitting the current block in half. * * If this works we have to re-set our variables because we * could be in a different block now. */ error = xfs_btree_split(cur, level, nptr, &key, ncur, stat); if (error || *stat == 0) return error; *index = cur->bc_ptrs[level]; cur->bc_ops->init_rec_from_key(&key, nrec); return 0; } /* * Insert one record/level. Return information to the caller * allowing the next level up to proceed if necessary. */ STATIC int xfs_btree_insrec( struct xfs_btree_cur *cur, /* btree cursor */ int level, /* level to insert record at */ union xfs_btree_ptr *ptrp, /* i/o: block number inserted */ union xfs_btree_rec *recp, /* i/o: record data inserted */ struct xfs_btree_cur **curp, /* output: new cursor replacing cur */ int *stat) /* success/failure */ { struct xfs_btree_block *block; /* btree block */ struct xfs_buf *bp; /* buffer for block */ union xfs_btree_key key; /* btree key */ union xfs_btree_ptr nptr; /* new block ptr */ struct xfs_btree_cur *ncur; /* new btree cursor */ union xfs_btree_rec nrec; /* new record count */ int optr; /* old key/record index */ int ptr; /* key/record index */ int numrecs;/* number of records */ int error; /* error return value */ #ifdef DEBUG int i; #endif XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGIPR(cur, level, *ptrp, recp); ncur = NULL; /* * If we have an external root pointer, and we've made it to the * root level, allocate a new root block and we're done. */ if (!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && (level >= cur->bc_nlevels)) { error = xfs_btree_new_root(cur, stat); xfs_btree_set_ptr_null(cur, ptrp); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return error; } /* If we're off the left edge, return failure. */ ptr = cur->bc_ptrs[level]; if (ptr == 0) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } /* Make a key out of the record data to be inserted, and save it. */ cur->bc_ops->init_key_from_rec(&key, recp); optr = ptr; XFS_BTREE_STATS_INC(cur, insrec); /* Get pointers to the btree buffer and block. */ block = xfs_btree_get_block(cur, level, &bp); numrecs = xfs_btree_get_numrecs(block); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) goto error0; /* Check that the new entry is being inserted in the right place. */ if (ptr <= numrecs) { if (level == 0) { ASSERT(cur->bc_ops->recs_inorder(cur, recp, xfs_btree_rec_addr(cur, ptr, block))); } else { ASSERT(cur->bc_ops->keys_inorder(cur, &key, xfs_btree_key_addr(cur, ptr, block))); } } #endif /* * If the block is full, we can't insert the new entry until we * make the block un-full. */ xfs_btree_set_ptr_null(cur, &nptr); if (numrecs == cur->bc_ops->get_maxrecs(cur, level)) { error = xfs_btree_make_block_unfull(cur, level, numrecs, &optr, &ptr, &nptr, &ncur, &nrec, stat); if (error || *stat == 0) goto error0; } /* * The current block may have changed if the block was * previously full and we have just made space in it. */ block = xfs_btree_get_block(cur, level, &bp); numrecs = xfs_btree_get_numrecs(block); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) return error; #endif /* * At this point we know there's room for our new entry in the block * we're pointing at. */ XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr + 1); if (level > 0) { /* It's a nonleaf. make a hole in the keys and ptrs */ union xfs_btree_key *kp; union xfs_btree_ptr *pp; kp = xfs_btree_key_addr(cur, ptr, block); pp = xfs_btree_ptr_addr(cur, ptr, block); #ifdef DEBUG for (i = numrecs - ptr; i >= 0; i--) { error = xfs_btree_check_ptr(cur, pp, i, level); if (error) return error; } #endif xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1); xfs_btree_shift_ptrs(cur, pp, 1, numrecs - ptr + 1); #ifdef DEBUG error = xfs_btree_check_ptr(cur, ptrp, 0, level); if (error) goto error0; #endif /* Now put the new data in, bump numrecs and log it. */ xfs_btree_copy_keys(cur, kp, &key, 1); xfs_btree_copy_ptrs(cur, pp, ptrp, 1); numrecs++; xfs_btree_set_numrecs(block, numrecs); xfs_btree_log_ptrs(cur, bp, ptr, numrecs); xfs_btree_log_keys(cur, bp, ptr, numrecs); #ifdef DEBUG if (ptr < numrecs) { ASSERT(cur->bc_ops->keys_inorder(cur, kp, xfs_btree_key_addr(cur, ptr + 1, block))); } #endif } else { /* It's a leaf. make a hole in the records */ union xfs_btree_rec *rp; rp = xfs_btree_rec_addr(cur, ptr, block); xfs_btree_shift_recs(cur, rp, 1, numrecs - ptr + 1); /* Now put the new data in, bump numrecs and log it. */ xfs_btree_copy_recs(cur, rp, recp, 1); xfs_btree_set_numrecs(block, ++numrecs); xfs_btree_log_recs(cur, bp, ptr, numrecs); #ifdef DEBUG if (ptr < numrecs) { ASSERT(cur->bc_ops->recs_inorder(cur, rp, xfs_btree_rec_addr(cur, ptr + 1, block))); } #endif } /* Log the new number of records in the btree header. */ xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); /* If we inserted at the start of a block, update the parents' keys. */ if (optr == 1) { error = xfs_btree_updkey(cur, &key, level + 1); if (error) goto error0; } /* * If we are tracking the last record in the tree and * we are at the far right edge of the tree, update it. */ if (xfs_btree_is_lastrec(cur, block, level)) { cur->bc_ops->update_lastrec(cur, block, recp, ptr, LASTREC_INSREC); } /* * Return the new block number, if any. * If there is one, give back a record value and a cursor too. */ *ptrp = nptr; if (!xfs_btree_ptr_is_null(cur, &nptr)) { *recp = nrec; *curp = ncur; } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Insert the record at the point referenced by cur. * * A multi-level split of the tree on insert will invalidate the original * cursor. All callers of this function should assume that the cursor is * no longer valid and revalidate it. */ int xfs_btree_insert( struct xfs_btree_cur *cur, int *stat) { int error; /* error return value */ int i; /* result value, 0 for failure */ int level; /* current level number in btree */ union xfs_btree_ptr nptr; /* new block number (split result) */ struct xfs_btree_cur *ncur; /* new cursor (split result) */ struct xfs_btree_cur *pcur; /* previous level's cursor */ union xfs_btree_rec rec; /* record to insert */ level = 0; ncur = NULL; pcur = cur; xfs_btree_set_ptr_null(cur, &nptr); cur->bc_ops->init_rec_from_cur(cur, &rec); /* * Loop going up the tree, starting at the leaf level. * Stop when we don't get a split block, that must mean that * the insert is finished with this level. */ do { /* * Insert nrec/nptr into this level of the tree. * Note if we fail, nptr will be null. */ error = xfs_btree_insrec(pcur, level, &nptr, &rec, &ncur, &i); if (error) { if (pcur != cur) xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); goto error0; } XFS_WANT_CORRUPTED_GOTO(i == 1, error0); level++; /* * See if the cursor we just used is trash. * Can't trash the caller's cursor, but otherwise we should * if ncur is a new cursor or we're about to be done. */ if (pcur != cur && (ncur || xfs_btree_ptr_is_null(cur, &nptr))) { /* Save the state from the cursor before we trash it */ if (cur->bc_ops->update_cursor) cur->bc_ops->update_cursor(pcur, cur); cur->bc_nlevels = pcur->bc_nlevels; xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR); } /* If we got a new cursor, switch to it. */ if (ncur) { pcur = ncur; ncur = NULL; } } while (!xfs_btree_ptr_is_null(cur, &nptr)); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = i; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Try to merge a non-leaf block back into the inode root. * * Note: the killroot names comes from the fact that we're effectively * killing the old root block. But because we can't just delete the * inode we have to copy the single block it was pointing to into the * inode. */ STATIC int xfs_btree_kill_iroot( struct xfs_btree_cur *cur) { int whichfork = cur->bc_private.b.whichfork; struct xfs_inode *ip = cur->bc_private.b.ip; struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_btree_block *block; struct xfs_btree_block *cblock; union xfs_btree_key *kp; union xfs_btree_key *ckp; union xfs_btree_ptr *pp; union xfs_btree_ptr *cpp; struct xfs_buf *cbp; int level; int index; int numrecs; #ifdef DEBUG union xfs_btree_ptr ptr; int i; #endif XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); ASSERT(cur->bc_nlevels > 1); /* * Don't deal with the root block needs to be a leaf case. * We're just going to turn the thing back into extents anyway. */ level = cur->bc_nlevels - 1; if (level == 1) goto out0; /* * Give up if the root has multiple children. */ block = xfs_btree_get_iroot(cur); if (xfs_btree_get_numrecs(block) != 1) goto out0; cblock = xfs_btree_get_block(cur, level - 1, &cbp); numrecs = xfs_btree_get_numrecs(cblock); /* * Only do this if the next level will fit. * Then the data must be copied up to the inode, * instead of freeing the root you free the next level. */ if (numrecs > cur->bc_ops->get_dmaxrecs(cur, level)) goto out0; XFS_BTREE_STATS_INC(cur, killroot); #ifdef DEBUG xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB); ASSERT(xfs_btree_ptr_is_null(cur, &ptr)); xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); ASSERT(xfs_btree_ptr_is_null(cur, &ptr)); #endif index = numrecs - cur->bc_ops->get_maxrecs(cur, level); if (index) { xfs_iroot_realloc(cur->bc_private.b.ip, index, cur->bc_private.b.whichfork); block = ifp->if_broot; } be16_add_cpu(&block->bb_numrecs, index); ASSERT(block->bb_numrecs == cblock->bb_numrecs); kp = xfs_btree_key_addr(cur, 1, block); ckp = xfs_btree_key_addr(cur, 1, cblock); xfs_btree_copy_keys(cur, kp, ckp, numrecs); pp = xfs_btree_ptr_addr(cur, 1, block); cpp = xfs_btree_ptr_addr(cur, 1, cblock); #ifdef DEBUG for (i = 0; i < numrecs; i++) { int error; error = xfs_btree_check_ptr(cur, cpp, i, level - 1); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } } #endif xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); cur->bc_ops->free_block(cur, cbp); XFS_BTREE_STATS_INC(cur, free); cur->bc_bufs[level - 1] = NULL; be16_add_cpu(&block->bb_level, -1); xfs_trans_log_inode(cur->bc_tp, ip, XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork)); cur->bc_nlevels--; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; } /* * Kill the current root node, and replace it with it's only child node. */ STATIC int xfs_btree_kill_root( struct xfs_btree_cur *cur, struct xfs_buf *bp, int level, union xfs_btree_ptr *newroot) { int error; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_STATS_INC(cur, killroot); /* * Update the root pointer, decreasing the level by 1 and then * free the old root. */ cur->bc_ops->set_root(cur, newroot, -1); error = cur->bc_ops->free_block(cur, bp); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } XFS_BTREE_STATS_INC(cur, free); cur->bc_bufs[level] = NULL; cur->bc_ra[level] = 0; cur->bc_nlevels--; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; } STATIC int xfs_btree_dec_cursor( struct xfs_btree_cur *cur, int level, int *stat) { int error; int i; if (level > 0) { error = xfs_btree_decrement(cur, level, &i); if (error) return error; } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; } /* * Single level of the btree record deletion routine. * Delete record pointed to by cur/level. * Remove the record from its block then rebalance the tree. * Return 0 for error, 1 for done, 2 to go on to the next level. */ STATIC int /* error */ xfs_btree_delrec( struct xfs_btree_cur *cur, /* btree cursor */ int level, /* level removing record from */ int *stat) /* fail/done/go-on */ { struct xfs_btree_block *block; /* btree block */ union xfs_btree_ptr cptr; /* current block ptr */ struct xfs_buf *bp; /* buffer for block */ int error; /* error return value */ int i; /* loop counter */ union xfs_btree_key key; /* storage for keyp */ union xfs_btree_key *keyp = &key; /* passed to the next level */ union xfs_btree_ptr lptr; /* left sibling block ptr */ struct xfs_buf *lbp; /* left buffer pointer */ struct xfs_btree_block *left; /* left btree block */ int lrecs = 0; /* left record count */ int ptr; /* key/record index */ union xfs_btree_ptr rptr; /* right sibling block ptr */ struct xfs_buf *rbp; /* right buffer pointer */ struct xfs_btree_block *right; /* right btree block */ struct xfs_btree_block *rrblock; /* right-right btree block */ struct xfs_buf *rrbp; /* right-right buffer pointer */ int rrecs = 0; /* right record count */ struct xfs_btree_cur *tcur; /* temporary btree cursor */ int numrecs; /* temporary numrec count */ XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); XFS_BTREE_TRACE_ARGI(cur, level); tcur = NULL; /* Get the index of the entry being deleted, check for nothing there. */ ptr = cur->bc_ptrs[level]; if (ptr == 0) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } /* Get the buffer & block containing the record or key/ptr. */ block = xfs_btree_get_block(cur, level, &bp); numrecs = xfs_btree_get_numrecs(block); #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) goto error0; #endif /* Fail if we're off the end of the block. */ if (ptr > numrecs) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } XFS_BTREE_STATS_INC(cur, delrec); XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr); /* Excise the entries being deleted. */ if (level > 0) { /* It's a nonleaf. operate on keys and ptrs */ union xfs_btree_key *lkp; union xfs_btree_ptr *lpp; lkp = xfs_btree_key_addr(cur, ptr + 1, block); lpp = xfs_btree_ptr_addr(cur, ptr + 1, block); #ifdef DEBUG for (i = 0; i < numrecs - ptr; i++) { error = xfs_btree_check_ptr(cur, lpp, i, level); if (error) goto error0; } #endif if (ptr < numrecs) { xfs_btree_shift_keys(cur, lkp, -1, numrecs - ptr); xfs_btree_shift_ptrs(cur, lpp, -1, numrecs - ptr); xfs_btree_log_keys(cur, bp, ptr, numrecs - 1); xfs_btree_log_ptrs(cur, bp, ptr, numrecs - 1); } /* * If it's the first record in the block, we'll need to pass a * key up to the next level (updkey). */ if (ptr == 1) keyp = xfs_btree_key_addr(cur, 1, block); } else { /* It's a leaf. operate on records */ if (ptr < numrecs) { xfs_btree_shift_recs(cur, xfs_btree_rec_addr(cur, ptr + 1, block), -1, numrecs - ptr); xfs_btree_log_recs(cur, bp, ptr, numrecs - 1); } /* * If it's the first record in the block, we'll need a key * structure to pass up to the next level (updkey). */ if (ptr == 1) { cur->bc_ops->init_key_from_rec(&key, xfs_btree_rec_addr(cur, 1, block)); keyp = &key; } } /* * Decrement and log the number of entries in the block. */ xfs_btree_set_numrecs(block, --numrecs); xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); /* * If we are tracking the last record in the tree and * we are at the far right edge of the tree, update it. */ if (xfs_btree_is_lastrec(cur, block, level)) { cur->bc_ops->update_lastrec(cur, block, NULL, ptr, LASTREC_DELREC); } /* * We're at the root level. First, shrink the root block in-memory. * Try to get rid of the next level down. If we can't then there's * nothing left to do. */ if (level == cur->bc_nlevels - 1) { if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) { xfs_iroot_realloc(cur->bc_private.b.ip, -1, cur->bc_private.b.whichfork); error = xfs_btree_kill_iroot(cur); if (error) goto error0; error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; *stat = 1; return 0; } /* * If this is the root level, and there's only one entry left, * and it's NOT the leaf level, then we can get rid of this * level. */ if (numrecs == 1 && level > 0) { union xfs_btree_ptr *pp; /* * pp is still set to the first pointer in the block. * Make it the new root of the btree. */ pp = xfs_btree_ptr_addr(cur, 1, block); error = xfs_btree_kill_root(cur, bp, level, pp); if (error) goto error0; } else if (level > 0) { error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; } *stat = 1; return 0; } /* * If we deleted the leftmost entry in the block, update the * key values above us in the tree. */ if (ptr == 1) { error = xfs_btree_updkey(cur, keyp, level + 1); if (error) goto error0; } /* * If the number of records remaining in the block is at least * the minimum, we're done. */ if (numrecs >= cur->bc_ops->get_minrecs(cur, level)) { error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; return 0; } /* * Otherwise, we have to move some records around to keep the * tree balanced. Look at the left and right sibling blocks to * see if we can re-balance by moving only one record. */ xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); xfs_btree_get_sibling(cur, block, &lptr, XFS_BB_LEFTSIB); if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) { /* * One child of root, need to get a chance to copy its contents * into the root and delete it. Can't go up to next level, * there's nothing to delete there. */ if (xfs_btree_ptr_is_null(cur, &rptr) && xfs_btree_ptr_is_null(cur, &lptr) && level == cur->bc_nlevels - 2) { error = xfs_btree_kill_iroot(cur); if (!error) error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; return 0; } } ASSERT(!xfs_btree_ptr_is_null(cur, &rptr) || !xfs_btree_ptr_is_null(cur, &lptr)); /* * Duplicate the cursor so our btree manipulations here won't * disrupt the next level up. */ error = xfs_btree_dup_cursor(cur, &tcur); if (error) goto error0; /* * If there's a right sibling, see if it's ok to shift an entry * out of it. */ if (!xfs_btree_ptr_is_null(cur, &rptr)) { /* * Move the temp cursor to the last entry in the next block. * Actually any entry but the first would suffice. */ i = xfs_btree_lastrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); error = xfs_btree_increment(tcur, level, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); i = xfs_btree_lastrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* Grab a pointer to the block. */ right = xfs_btree_get_block(tcur, level, &rbp); #ifdef DEBUG error = xfs_btree_check_block(tcur, right, level, rbp); if (error) goto error0; #endif /* Grab the current block number, for future use. */ xfs_btree_get_sibling(tcur, right, &cptr, XFS_BB_LEFTSIB); /* * If right block is full enough so that removing one entry * won't make it too empty, and left-shifting an entry out * of right to us works, we're done. */ if (xfs_btree_get_numrecs(right) - 1 >= cur->bc_ops->get_minrecs(tcur, level)) { error = xfs_btree_lshift(tcur, level, &i); if (error) goto error0; if (i) { ASSERT(xfs_btree_get_numrecs(block) >= cur->bc_ops->get_minrecs(tcur, level)); xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); tcur = NULL; error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; return 0; } } /* * Otherwise, grab the number of records in right for * future reference, and fix up the temp cursor to point * to our block again (last record). */ rrecs = xfs_btree_get_numrecs(right); if (!xfs_btree_ptr_is_null(cur, &lptr)) { i = xfs_btree_firstrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); error = xfs_btree_decrement(tcur, level, &i); if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); } } /* * If there's a left sibling, see if it's ok to shift an entry * out of it. */ if (!xfs_btree_ptr_is_null(cur, &lptr)) { /* * Move the temp cursor to the first entry in the * previous block. */ i = xfs_btree_firstrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); error = xfs_btree_decrement(tcur, level, &i); if (error) goto error0; i = xfs_btree_firstrec(tcur, level); XFS_WANT_CORRUPTED_GOTO(i == 1, error0); /* Grab a pointer to the block. */ left = xfs_btree_get_block(tcur, level, &lbp); #ifdef DEBUG error = xfs_btree_check_block(cur, left, level, lbp); if (error) goto error0; #endif /* Grab the current block number, for future use. */ xfs_btree_get_sibling(tcur, left, &cptr, XFS_BB_RIGHTSIB); /* * If left block is full enough so that removing one entry * won't make it too empty, and right-shifting an entry out * of left to us works, we're done. */ if (xfs_btree_get_numrecs(left) - 1 >= cur->bc_ops->get_minrecs(tcur, level)) { error = xfs_btree_rshift(tcur, level, &i); if (error) goto error0; if (i) { ASSERT(xfs_btree_get_numrecs(block) >= cur->bc_ops->get_minrecs(tcur, level)); xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); tcur = NULL; if (level == 0) cur->bc_ptrs[0]++; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 1; return 0; } } /* * Otherwise, grab the number of records in right for * future reference. */ lrecs = xfs_btree_get_numrecs(left); } /* Delete the temp cursor, we're done with it. */ xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); tcur = NULL; /* If here, we need to do a join to keep the tree balanced. */ ASSERT(!xfs_btree_ptr_is_null(cur, &cptr)); if (!xfs_btree_ptr_is_null(cur, &lptr) && lrecs + xfs_btree_get_numrecs(block) <= cur->bc_ops->get_maxrecs(cur, level)) { /* * Set "right" to be the starting block, * "left" to be the left neighbor. */ rptr = cptr; right = block; rbp = bp; error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp); if (error) goto error0; /* * If that won't work, see if we can join with the right neighbor block. */ } else if (!xfs_btree_ptr_is_null(cur, &rptr) && rrecs + xfs_btree_get_numrecs(block) <= cur->bc_ops->get_maxrecs(cur, level)) { /* * Set "left" to be the starting block, * "right" to be the right neighbor. */ lptr = cptr; left = block; lbp = bp; error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp); if (error) goto error0; /* * Otherwise, we can't fix the imbalance. * Just return. This is probably a logic error, but it's not fatal. */ } else { error = xfs_btree_dec_cursor(cur, level, stat); if (error) goto error0; return 0; } rrecs = xfs_btree_get_numrecs(right); lrecs = xfs_btree_get_numrecs(left); /* * We're now going to join "left" and "right" by moving all the stuff * in "right" to "left" and deleting "right". */ XFS_BTREE_STATS_ADD(cur, moves, rrecs); if (level > 0) { /* It's a non-leaf. Move keys and pointers. */ union xfs_btree_key *lkp; /* left btree key */ union xfs_btree_ptr *lpp; /* left address pointer */ union xfs_btree_key *rkp; /* right btree key */ union xfs_btree_ptr *rpp; /* right address pointer */ lkp = xfs_btree_key_addr(cur, lrecs + 1, left); lpp = xfs_btree_ptr_addr(cur, lrecs + 1, left); rkp = xfs_btree_key_addr(cur, 1, right); rpp = xfs_btree_ptr_addr(cur, 1, right); #ifdef DEBUG for (i = 1; i < rrecs; i++) { error = xfs_btree_check_ptr(cur, rpp, i, level); if (error) goto error0; } #endif xfs_btree_copy_keys(cur, lkp, rkp, rrecs); xfs_btree_copy_ptrs(cur, lpp, rpp, rrecs); xfs_btree_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); xfs_btree_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); } else { /* It's a leaf. Move records. */ union xfs_btree_rec *lrp; /* left record pointer */ union xfs_btree_rec *rrp; /* right record pointer */ lrp = xfs_btree_rec_addr(cur, lrecs + 1, left); rrp = xfs_btree_rec_addr(cur, 1, right); xfs_btree_copy_recs(cur, lrp, rrp, rrecs); xfs_btree_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); } XFS_BTREE_STATS_INC(cur, join); /* * Fix up the number of records and right block pointer in the * surviving block, and log it. */ xfs_btree_set_numrecs(left, lrecs + rrecs); xfs_btree_get_sibling(cur, right, &cptr, XFS_BB_RIGHTSIB), xfs_btree_set_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB); xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); /* If there is a right sibling, point it to the remaining block. */ xfs_btree_get_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB); if (!xfs_btree_ptr_is_null(cur, &cptr)) { error = xfs_btree_read_buf_block(cur, &cptr, level, 0, &rrblock, &rrbp); if (error) goto error0; xfs_btree_set_sibling(cur, rrblock, &lptr, XFS_BB_LEFTSIB); xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB); } /* Free the deleted block. */ error = cur->bc_ops->free_block(cur, rbp); if (error) goto error0; XFS_BTREE_STATS_INC(cur, free); /* * If we joined with the left neighbor, set the buffer in the * cursor to the left block, and fix up the index. */ if (bp != lbp) { cur->bc_bufs[level] = lbp; cur->bc_ptrs[level] += lrecs; cur->bc_ra[level] = 0; } /* * If we joined with the right neighbor and there's a level above * us, increment the cursor at that level. */ else if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || (level + 1 < cur->bc_nlevels)) { error = xfs_btree_increment(cur, level + 1, &i); if (error) goto error0; } /* * Readjust the ptr at this level if it's not a leaf, since it's * still pointing at the deletion point, which makes the cursor * inconsistent. If this makes the ptr 0, the caller fixes it up. * We can't use decrement because it would change the next level up. */ if (level > 0) cur->bc_ptrs[level]--; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); /* Return value means the next level up has something to do. */ *stat = 2; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); if (tcur) xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); return error; } /* * Delete the record pointed to by cur. * The cursor refers to the place where the record was (could be inserted) * when the operation returns. */ int /* error */ xfs_btree_delete( struct xfs_btree_cur *cur, int *stat) /* success/failure */ { int error; /* error return value */ int level; int i; XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); /* * Go up the tree, starting at leaf level. * * If 2 is returned then a join was done; go to the next level. * Otherwise we are done. */ for (level = 0, i = 2; i == 2; level++) { error = xfs_btree_delrec(cur, level, &i); if (error) goto error0; } if (i == 0) { for (level = 1; level < cur->bc_nlevels; level++) { if (cur->bc_ptrs[level] == 0) { error = xfs_btree_decrement(cur, level, &i); if (error) goto error0; break; } } } XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = i; return 0; error0: XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } /* * Get the data from the pointed-to record. */ int /* error */ xfs_btree_get_rec( struct xfs_btree_cur *cur, /* btree cursor */ union xfs_btree_rec **recp, /* output: btree record */ int *stat) /* output: success/failure */ { struct xfs_btree_block *block; /* btree block */ struct xfs_buf *bp; /* buffer pointer */ int ptr; /* record number */ #ifdef DEBUG int error; /* error return value */ #endif ptr = cur->bc_ptrs[0]; block = xfs_btree_get_block(cur, 0, &bp); #ifdef DEBUG error = xfs_btree_check_block(cur, block, 0, bp); if (error) return error; #endif /* * Off the right end or left end, return failure. */ if (ptr > xfs_btree_get_numrecs(block) || ptr <= 0) { *stat = 0; return 0; } /* * Point to the record and extract its data. */ *recp = xfs_btree_rec_addr(cur, ptr, block); *stat = 1; return 0; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_attr_leaf.c0000664000000000000000000020744511650373061016106 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * xfs_attr_leaf.c * * Routines to implement leaf blocks of attributes as Btrees of hashed names. */ /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ /* * Routines used for growing the Btree. */ STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, xfs_dabuf_t **bpp); STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, int freemap_index); STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2); STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, xfs_da_state_blk_t *leaf_blk_1, xfs_da_state_blk_t *leaf_blk_2, int *number_entries_in_blk1, int *number_usedbytes_in_blk1); /* * Utility routines. */ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, int src_start, xfs_attr_leafblock_t *dst_leaf, int dst_start, int move_count, xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); /*======================================================================== * Namespace helper routines *========================================================================*/ /* * If namespace bits don't match return 0. * If all match then return 1. */ STATIC int xfs_attr_namesp_match(int arg_flags, int ondisk_flags) { return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); } /*======================================================================== * External routines when attribute fork size < XFS_LITINO(mp). *========================================================================*/ /* * Query whether the requested number of additional bytes of extended * attribute space will be able to fit inline. * Returns zero if not, else the di_forkoff fork offset to be used in the * literal area for attribute data once the new bytes have been added. * * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value; * special case for dev/uuid inodes, they have fixed size data forks. */ int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) { int offset; int minforkoff; /* lower limit on valid forkoff locations */ int maxforkoff; /* upper limit on valid forkoff locations */ int dsize; xfs_mount_t *mp = dp->i_mount; offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ switch (dp->i_d.di_format) { case XFS_DINODE_FMT_DEV: minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; return (offset >= minforkoff) ? minforkoff : 0; case XFS_DINODE_FMT_UUID: minforkoff = roundup(sizeof(uuid_t), 8) >> 3; return (offset >= minforkoff) ? minforkoff : 0; } if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { if (bytes <= XFS_IFORK_ASIZE(dp)) return dp->i_d.di_forkoff; return 0; } dsize = dp->i_df.if_bytes; switch (dp->i_d.di_format) { case XFS_DINODE_FMT_EXTENTS: /* * If there is no attr fork and the data fork is extents, * determine if creating the default attr fork will result * in the extents form migrating to btree. If so, the * minimum offset only needs to be the space required for * the btree root. */ if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > xfs_default_attroffset(dp)) dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); break; case XFS_DINODE_FMT_BTREE: /* * If have data btree then keep forkoff if we have one, * otherwise we are adding a new attr, so then we set * minforkoff to where the btree root can finish so we have * plenty of room for attrs */ if (dp->i_d.di_forkoff) { if (offset < dp->i_d.di_forkoff) return 0; else return dp->i_d.di_forkoff; } else dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); break; } /* * A data fork btree root must have space for at least * MINDBTPTRS key/ptr pairs if the data fork is small or empty. */ minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); minforkoff = roundup(minforkoff, 8) >> 3; /* attr fork btree root can have at least this many key/ptr pairs */ maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); maxforkoff = maxforkoff >> 3; /* rounded down */ if (offset >= minforkoff && offset < maxforkoff) return offset; if (offset >= maxforkoff) return maxforkoff; return 0; } /* * Switch on the ATTR2 superblock bit (implies also FEATURES2) */ STATIC void xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) { if ((mp->m_flags & XFS_MOUNT_ATTR2) && !(xfs_sb_version_hasattr2(&mp->m_sb))) { spin_lock(&mp->m_sb_lock); if (!xfs_sb_version_hasattr2(&mp->m_sb)) { xfs_sb_version_addattr2(&mp->m_sb); spin_unlock(&mp->m_sb_lock); xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); } else spin_unlock(&mp->m_sb_lock); } } /* * Create the initial contents of a shortform attribute list. */ void xfs_attr_shortform_create(xfs_da_args_t *args) { xfs_attr_sf_hdr_t *hdr; xfs_inode_t *dp; xfs_ifork_t *ifp; dp = args->dp; ASSERT(dp != NULL); ifp = dp->i_afp; ASSERT(ifp != NULL); ASSERT(ifp->if_bytes == 0); if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; ifp->if_flags |= XFS_IFINLINE; } else { ASSERT(ifp->if_flags & XFS_IFINLINE); } xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK); hdr = (xfs_attr_sf_hdr_t *)ifp->if_u1.if_data; hdr->count = 0; hdr->totsize = cpu_to_be16(sizeof(*hdr)); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); } /* * Add a name/value pair to the shortform attribute list. * Overflow from the inode has already been checked for. */ void xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) { xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; int i, offset, size; xfs_mount_t *mp; xfs_inode_t *dp; xfs_ifork_t *ifp; dp = args->dp; mp = dp->i_mount; dp->i_d.di_forkoff = forkoff; dp->i_df.if_ext_max = XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); dp->i_afp->if_ext_max = XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); ifp = dp->i_afp; ASSERT(ifp->if_flags & XFS_IFINLINE); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { #ifdef DEBUG if (sfe->namelen != args->namelen) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; ASSERT(0); #endif } offset = (char *)sfe - (char *)sf; size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); xfs_idata_realloc(dp, size, XFS_ATTR_FORK); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; sfe = (xfs_attr_sf_entry_t *)((char *)sf + offset); sfe->namelen = args->namelen; sfe->valuelen = args->valuelen; sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); memcpy(sfe->nameval, args->name, args->namelen); memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); sf->hdr.count++; be16_add_cpu(&sf->hdr.totsize, size); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); xfs_sbversion_add_attr2(mp, args->trans); } /* * After the last attribute is removed revert to original inode format, * making all literal area available to the data fork once more. */ STATIC void xfs_attr_fork_reset( struct xfs_inode *ip, struct xfs_trans *tp) { xfs_idestroy_fork(ip, XFS_ATTR_FORK); ip->i_d.di_forkoff = 0; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_afp == NULL); ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } /* * Remove an attribute from the shortform attribute list structure. */ int xfs_attr_shortform_remove(xfs_da_args_t *args) { xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; int base, size=0, end, totsize, i; xfs_mount_t *mp; xfs_inode_t *dp; dp = args->dp; mp = dp->i_mount; base = sizeof(xfs_attr_sf_hdr_t); sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; sfe = &sf->list[0]; end = sf->hdr.count; for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), base += size, i++) { size = XFS_ATTR_SF_ENTSIZE(sfe); if (sfe->namelen != args->namelen) continue; if (memcmp(sfe->nameval, args->name, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; break; } if (i == end) return(XFS_ERROR(ENOATTR)); /* * Fix up the attribute fork data, covering the hole */ end = base + size; totsize = be16_to_cpu(sf->hdr.totsize); if (end != totsize) memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end); sf->hdr.count--; be16_add_cpu(&sf->hdr.totsize, -size); /* * Fix up the start offset of the attribute fork */ totsize -= size; if (totsize == sizeof(xfs_attr_sf_hdr_t) && (mp->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && !(args->op_flags & XFS_DA_OP_ADDNAME)) { xfs_attr_fork_reset(dp, args->trans); } else { xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); ASSERT(dp->i_d.di_forkoff); ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || (args->op_flags & XFS_DA_OP_ADDNAME) || !(mp->m_flags & XFS_MOUNT_ATTR2) || dp->i_d.di_format == XFS_DINODE_FMT_BTREE); dp->i_afp->if_ext_max = XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); dp->i_df.if_ext_max = XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); } xfs_sbversion_add_attr2(mp, args->trans); return(0); } /* * Look up a name in a shortform attribute list structure. */ /*ARGSUSED*/ int xfs_attr_shortform_lookup(xfs_da_args_t *args) { xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; int i; xfs_ifork_t *ifp; ifp = args->dp->i_afp; ASSERT(ifp->if_flags & XFS_IFINLINE); sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { if (sfe->namelen != args->namelen) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; return(XFS_ERROR(EEXIST)); } return(XFS_ERROR(ENOATTR)); } /* * Look up a name in a shortform attribute list structure. */ /*ARGSUSED*/ int xfs_attr_shortform_getvalue(xfs_da_args_t *args) { xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; int i; ASSERT(args->dp->i_d.di_aformat == XFS_IFINLINE); sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { if (sfe->namelen != args->namelen) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; if (args->flags & ATTR_KERNOVAL) { args->valuelen = sfe->valuelen; return(XFS_ERROR(EEXIST)); } if (args->valuelen < sfe->valuelen) { args->valuelen = sfe->valuelen; return(XFS_ERROR(ERANGE)); } args->valuelen = sfe->valuelen; memcpy(args->value, &sfe->nameval[args->namelen], args->valuelen); return(XFS_ERROR(EEXIST)); } return(XFS_ERROR(ENOATTR)); } /* * Convert from using the shortform to the leaf. */ int xfs_attr_shortform_to_leaf(xfs_da_args_t *args) { xfs_inode_t *dp; xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_da_args_t nargs; char *tmpbuffer; int error, i, size; xfs_dablk_t blkno; xfs_dabuf_t *bp; xfs_ifork_t *ifp; dp = args->dp; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; size = be16_to_cpu(sf->hdr.totsize); tmpbuffer = kmem_alloc(size, KM_SLEEP); ASSERT(tmpbuffer != NULL); memcpy(tmpbuffer, ifp->if_u1.if_data, size); sf = (xfs_attr_shortform_t *)tmpbuffer; xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); bp = NULL; error = xfs_da_grow_inode(args, &blkno); if (error) { /* * If we hit an IO error middle of the transaction inside * grow_inode(), we may have inconsistent data. Bail out. */ if (error == EIO) goto out; xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ goto out; } ASSERT(blkno == 0); error = xfs_attr_leaf_create(args, blkno, &bp); if (error) { error = xfs_da_shrink_inode(args, 0, bp); bp = NULL; if (error) goto out; xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ goto out; } memset((char *)&nargs, 0, sizeof(nargs)); nargs.dp = dp; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; nargs.op_flags = XFS_DA_OP_OKNOENT; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; i++) { nargs.name = sfe->nameval; nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; nargs.hashval = xfs_da_hashname(sfe->nameval, sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr_leaf_add(bp, &nargs); ASSERT(error != ENOSPC); if (error) goto out; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); } error = 0; out: if(bp) xfs_da_buf_done(bp); kmem_free(tmpbuffer); return(error); } /* * Check a leaf attribute block to see if all the entries would fit into * a shortform attribute list. */ int xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *name_loc; int bytes, i; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); entry = &leaf->entries[0]; bytes = sizeof(struct xfs_attr_sf_hdr); for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!(entry->flags & XFS_ATTR_LOCAL)) return(0); name_loc = xfs_attr_leaf_name_local(leaf, i); if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); bytes += sizeof(struct xfs_attr_sf_entry)-1 + name_loc->namelen + be16_to_cpu(name_loc->valuelen); } if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && (bytes == sizeof(struct xfs_attr_sf_hdr))) return(-1); return(xfs_attr_shortform_bytesfit(dp, bytes)); } /* * Convert a leaf attribute list to shortform attribute list */ int xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *name_loc; xfs_da_args_t nargs; xfs_inode_t *dp; char *tmpbuffer; int error, i; dp = args->dp; tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); ASSERT(tmpbuffer != NULL); ASSERT(bp != NULL); memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); leaf = (xfs_attr_leafblock_t *)tmpbuffer; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); /* * Clean out the prior contents of the attribute list. */ error = xfs_da_shrink_inode(args, 0, bp); if (error) goto out; if (forkoff == -1) { ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); xfs_attr_fork_reset(dp, args->trans); goto out; } xfs_attr_shortform_create(args); /* * Copy the attributes */ memset((char *)&nargs, 0, sizeof(nargs)); nargs.dp = dp; nargs.firstblock = args->firstblock; nargs.flist = args->flist; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; nargs.op_flags = XFS_DA_OP_OKNOENT; entry = &leaf->entries[0]; for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!entry->nameidx) continue; ASSERT(entry->flags & XFS_ATTR_LOCAL); name_loc = xfs_attr_leaf_name_local(leaf, i); nargs.name = name_loc->nameval; nargs.namelen = name_loc->namelen; nargs.value = &name_loc->nameval[nargs.namelen]; nargs.valuelen = be16_to_cpu(name_loc->valuelen); nargs.hashval = be32_to_cpu(entry->hashval); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); xfs_attr_shortform_add(&nargs, forkoff); } error = 0; out: kmem_free(tmpbuffer); return(error); } /* * Convert from using a single leaf to a root node and a leaf. */ int xfs_attr_leaf_to_node(xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_da_intnode_t *node; xfs_inode_t *dp; xfs_dabuf_t *bp1, *bp2; xfs_dablk_t blkno; int error; dp = args->dp; bp1 = bp2 = NULL; error = xfs_da_grow_inode(args, &blkno); if (error) goto out; error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, XFS_ATTR_FORK); if (error) goto out; ASSERT(bp1 != NULL); bp2 = NULL; error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2, XFS_ATTR_FORK); if (error) goto out; ASSERT(bp2 != NULL); memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); xfs_da_buf_done(bp1); bp1 = NULL; xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); /* * Set up the new root node. */ error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); if (error) goto out; node = bp1->data; leaf = bp2->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); /* both on-disk, don't endian-flip twice */ node->btree[0].hashval = leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; node->btree[0].before = cpu_to_be32(blkno); node->hdr.count = cpu_to_be16(1); xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); error = 0; out: if (bp1) xfs_da_buf_done(bp1); if (bp2) xfs_da_buf_done(bp2); return(error); } /*======================================================================== * Routines used for growing the Btree. *========================================================================*/ /* * Create the initial contents of a leaf attribute list * or a leaf in a node attribute list. */ STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_hdr_t *hdr; xfs_inode_t *dp; xfs_dabuf_t *bp; int error; dp = args->dp; ASSERT(dp != NULL); error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, XFS_ATTR_FORK); if (error) return(error); ASSERT(bp != NULL); leaf = bp->data; memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); hdr = &leaf->hdr; hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); if (!hdr->firstused) { hdr->firstused = cpu_to_be16( XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN); } hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - sizeof(xfs_attr_leaf_hdr_t)); xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); *bpp = bp; return(0); } /* * Split the leaf node, rebalance, then add the new entry. */ int xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, xfs_da_state_blk_t *newblk) { xfs_dablk_t blkno; int error; /* * Allocate space for a new leaf node. */ ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC); error = xfs_da_grow_inode(state->args, &blkno); if (error) return(error); error = xfs_attr_leaf_create(state->args, blkno, &newblk->bp); if (error) return(error); newblk->blkno = blkno; newblk->magic = XFS_ATTR_LEAF_MAGIC; /* * Rebalance the entries across the two leaves. * NOTE: rebalance() currently depends on the 2nd block being empty. */ xfs_attr_leaf_rebalance(state, oldblk, newblk); error = xfs_da_blk_link(state, oldblk, newblk); if (error) return(error); /* * Save info on "old" attribute for "atomic rename" ops, leaf_add() * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the * "new" attrs info. Will need the "old" info to remove it later. * * Insert the "new" entry in the correct block. */ if (state->inleaf) error = xfs_attr_leaf_add(oldblk->bp, state->args); else error = xfs_attr_leaf_add(newblk->bp, state->args); /* * Update last hashval in each block since we added the name. */ oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL); newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL); return(error); } /* * Add a name to the leaf attribute list structure. */ int xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_hdr_t *hdr; xfs_attr_leaf_map_t *map; int tablesize, entsize, sum, tmp, i; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(leaf->hdr.count))); hdr = &leaf->hdr; entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, args->trans->t_mountp->m_sb.sb_blocksize, NULL); /* * Search through freemap for first-fit on new name length. * (may need to figure in size of entry struct too) */ tablesize = (be16_to_cpu(hdr->count) + 1) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1]; for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { if (tablesize > be16_to_cpu(hdr->firstused)) { sum += be16_to_cpu(map->size); continue; } if (!map->size) continue; /* no space in this map */ tmp = entsize; if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) tmp += sizeof(xfs_attr_leaf_entry_t); if (be16_to_cpu(map->size) >= tmp) { tmp = xfs_attr_leaf_add_work(bp, args, i); return(tmp); } sum += be16_to_cpu(map->size); } /* * If there are no holes in the address space of the block, * and we don't have enough freespace, then compaction will do us * no good and we should just give up. */ if (!hdr->holes && (sum < entsize)) return(XFS_ERROR(ENOSPC)); /* * Compact the entries to coalesce free space. * This may change the hdr->count via dropping INCOMPLETE entries. */ xfs_attr_leaf_compact(args->trans, bp); /* * After compaction, the block is guaranteed to have only one * free region, in freemap[0]. If it is not big enough, give up. */ if (be16_to_cpu(hdr->freemap[0].size) < (entsize + sizeof(xfs_attr_leaf_entry_t))) return(XFS_ERROR(ENOSPC)); return(xfs_attr_leaf_add_work(bp, args, 0)); } /* * Add a name to a leaf attribute list structure. */ STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_hdr_t *hdr; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; xfs_attr_leaf_map_t *map; xfs_mount_t *mp; int tmp, i; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr = &leaf->hdr; ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count))); /* * Force open some space in the entry array and fill it in. */ entry = &leaf->entries[args->index]; if (args->index < be16_to_cpu(hdr->count)) { tmp = be16_to_cpu(hdr->count) - args->index; tmp *= sizeof(xfs_attr_leaf_entry_t); memmove((char *)(entry+1), (char *)entry, tmp); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); } be16_add_cpu(&hdr->count, 1); /* * Allocate space for the new string (at the end of the run). */ map = &hdr->freemap[mapindex]; mp = args->trans->t_mountp; ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); ASSERT((be16_to_cpu(map->base) & 0x3) == 0); ASSERT(be16_to_cpu(map->size) >= xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, NULL)); ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); ASSERT((be16_to_cpu(map->size) & 0x3) == 0); be16_add_cpu(&map->size, -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, mp->m_sb.sb_blocksize, &tmp)); entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + be16_to_cpu(map->size)); entry->hashval = cpu_to_be32(args->hashval); entry->flags = tmp ? XFS_ATTR_LOCAL : 0; entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); if (args->op_flags & XFS_DA_OP_RENAME) { entry->flags |= XFS_ATTR_INCOMPLETE; if ((args->blkno2 == args->blkno) && (args->index2 <= args->index)) { args->index2++; } } xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); ASSERT((args->index == 0) || (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); ASSERT((args->index == be16_to_cpu(hdr->count)-1) || (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval))); /* * Copy the attribute name and value into the new space. * * For "remote" attribute values, simply note that we need to * allocate space for the "remote" value. We can't actually * allocate the extents in this transaction, and we can't decide * which blocks they should be as we might allocate more blocks * as part of this transaction (a split operation for example). */ if (entry->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf, args->index); name_loc->namelen = args->namelen; name_loc->valuelen = cpu_to_be16(args->valuelen); memcpy((char *)name_loc->nameval, args->name, args->namelen); memcpy((char *)&name_loc->nameval[args->namelen], args->value, be16_to_cpu(name_loc->valuelen)); } else { name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->namelen = args->namelen; memcpy((char *)name_rmt->name, args->name, args->namelen); entry->flags |= XFS_ATTR_INCOMPLETE; /* just in case */ name_rmt->valuelen = 0; name_rmt->valueblk = 0; args->rmtblkno = 1; args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); } xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), xfs_attr_leaf_entsize(leaf, args->index))); /* * Update the control info for this leaf node */ if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) { /* both on-disk, don't endian-flip twice */ hdr->firstused = entry->nameidx; } ASSERT(be16_to_cpu(hdr->firstused) >= ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[0]; for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { if (be16_to_cpu(map->base) == tmp) { be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); be16_add_cpu(&map->size, -((int)sizeof(xfs_attr_leaf_entry_t))); } } be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); return(0); } /* * Garbage collect a leaf attribute list block by copying it to a new buffer. */ STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) { xfs_attr_leafblock_t *leaf_s, *leaf_d; xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; xfs_mount_t *mp; char *tmpbuffer; mp = trans->t_mountp; tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); ASSERT(tmpbuffer != NULL); memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp)); memset(bp->data, 0, XFS_LBSIZE(mp)); /* * Copy basic information */ leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; leaf_d = bp->data; hdr_s = &leaf_s->hdr; hdr_d = &leaf_d->hdr; hdr_d->info = hdr_s->info; /* struct copy */ hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp)); /* handle truncation gracefully */ if (!hdr_d->firstused) { hdr_d->firstused = cpu_to_be16( XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN); } hdr_d->usedbytes = 0; hdr_d->count = 0; hdr_d->holes = 0; hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - sizeof(xfs_attr_leaf_hdr_t)); /* * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. */ xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, be16_to_cpu(hdr_s->count), mp); xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); kmem_free(tmpbuffer); } /* * Redistribute the attribute list entries between two leaf nodes, * taking into account the size of the new entry. * * NOTE: if new block is empty, then it will get the upper half of the * old block. At present, all (one) callers pass in an empty second block. * * This code adjusts the args->index/blkno and args->index2/blkno2 fields * to match what it is doing in splitting the attribute leaf block. Those * values are used in "atomic rename" operations on attributes. Note that * the "new" and "old" values can end up in different blocks. */ STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2) { xfs_da_args_t *args; xfs_da_state_blk_t *tmp_blk; xfs_attr_leafblock_t *leaf1, *leaf2; xfs_attr_leaf_hdr_t *hdr1, *hdr2; int count, totallen, max, space, swap; /* * Set up environment. */ ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC); ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); args = state->args; /* * Check ordering of blocks, reverse if it makes things simpler. * * NOTE: Given that all (current) callers pass in an empty * second block, this code should never set "swap". */ swap = 0; if (xfs_attr_leaf_order(blk1->bp, blk2->bp)) { tmp_blk = blk1; blk1 = blk2; blk2 = tmp_blk; leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; swap = 1; } hdr1 = &leaf1->hdr; hdr2 = &leaf2->hdr; /* * Examine entries until we reduce the absolute difference in * byte usage between the two blocks to a minimum. Then get * the direction to copy and the number of elements to move. * * "inleaf" is true if the new entry should be inserted into blk1. * If "swap" is also true, then reverse the sense of "inleaf". */ state->inleaf = xfs_attr_leaf_figure_balance(state, blk1, blk2, &count, &totallen); if (swap) state->inleaf = !state->inleaf; /* * Move any entries required from leaf to leaf: */ if (count < be16_to_cpu(hdr1->count)) { /* * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ count = be16_to_cpu(hdr1->count) - count; space = be16_to_cpu(hdr1->usedbytes) - totallen; space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf2 is the destination, compact it if it looks tight. */ max = be16_to_cpu(hdr2->firstused) - sizeof(xfs_attr_leaf_hdr_t); max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t); if (space > max) { xfs_attr_leaf_compact(args->trans, blk2->bp); } /* * Move high entries from leaf1 to low end of leaf2. */ xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, leaf2, 0, count, state->mp); xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); } else if (count > be16_to_cpu(hdr1->count)) { /* * I assert that since all callers pass in an empty * second buffer, this code should never execute. */ /* * Figure the total bytes to be added to the destination leaf. */ /* number entries being moved */ count -= be16_to_cpu(hdr1->count); space = totallen - be16_to_cpu(hdr1->usedbytes); space += count * sizeof(xfs_attr_leaf_entry_t); /* * leaf1 is the destination, compact it if it looks tight. */ max = be16_to_cpu(hdr1->firstused) - sizeof(xfs_attr_leaf_hdr_t); max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t); if (space > max) { xfs_attr_leaf_compact(args->trans, blk1->bp); } /* * Move low entries from leaf2 to high end of leaf1. */ xfs_attr_leaf_moveents(leaf2, 0, leaf1, be16_to_cpu(hdr1->count), count, state->mp); xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); } /* * Copy out last hashval in each block for B-tree code. */ blk1->hashval = be32_to_cpu( leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval); blk2->hashval = be32_to_cpu( leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval); /* * Adjust the expected index for insertion. * NOTE: this code depends on the (current) situation that the * second block was originally empty. * * If the insertion point moved to the 2nd block, we must adjust * the index. We must also track the entry just following the * new entry for use in an "atomic rename" operation, that entry * is always the "old" entry and the "new" entry is what we are * inserting. The index/blkno fields refer to the "old" entry, * while the index2/blkno2 fields refer to the "new" entry. */ if (blk1->index > be16_to_cpu(leaf1->hdr.count)) { ASSERT(state->inleaf == 0); blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); args->index = args->index2 = blk2->index; args->blkno = args->blkno2 = blk2->blkno; } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) { if (state->inleaf) { args->index = blk1->index; args->blkno = blk1->blkno; args->index2 = 0; args->blkno2 = blk2->blkno; } else { blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); args->index = args->index2 = blk2->index; args->blkno = args->blkno2 = blk2->blkno; } } else { ASSERT(state->inleaf == 1); args->index = args->index2 = blk1->index; args->blkno = args->blkno2 = blk1->blkno; } } /* * Examine entries until we reduce the absolute difference in * byte usage between the two blocks to a minimum. * GROT: Is this really necessary? With other than a 512 byte blocksize, * GROT: there will always be enough room in either block for a new entry. * GROT: Do a double-split for this case? */ STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, xfs_da_state_blk_t *blk2, int *countarg, int *usedbytesarg) { xfs_attr_leafblock_t *leaf1, *leaf2; xfs_attr_leaf_hdr_t *hdr1, *hdr2; xfs_attr_leaf_entry_t *entry; int count, max, index, totallen, half; int lastdelta, foundit, tmp; /* * Set up environment. */ leaf1 = blk1->bp->data; leaf2 = blk2->bp->data; hdr1 = &leaf1->hdr; hdr2 = &leaf2->hdr; foundit = 0; totallen = 0; /* * Examine entries until we reduce the absolute difference in * byte usage between the two blocks to a minimum. */ max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); half = (max+1) * sizeof(*entry); half += be16_to_cpu(hdr1->usedbytes) + be16_to_cpu(hdr2->usedbytes) + xfs_attr_leaf_newentsize( state->args->namelen, state->args->valuelen, state->blocksize, NULL); half /= 2; lastdelta = state->blocksize; entry = &leaf1->entries[0]; for (count = index = 0; count < max; entry++, index++, count++) { #define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A)) /* * The new entry is in the first block, account for it. */ if (count == blk1->index) { tmp = totallen + sizeof(*entry) + xfs_attr_leaf_newentsize( state->args->namelen, state->args->valuelen, state->blocksize, NULL); if (XFS_ATTR_ABS(half - tmp) > lastdelta) break; lastdelta = XFS_ATTR_ABS(half - tmp); totallen = tmp; foundit = 1; } /* * Wrap around into the second block if necessary. */ if (count == be16_to_cpu(hdr1->count)) { leaf1 = leaf2; entry = &leaf1->entries[0]; index = 0; } /* * Figure out if next leaf entry would be too much. */ tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1, index); if (XFS_ATTR_ABS(half - tmp) > lastdelta) break; lastdelta = XFS_ATTR_ABS(half - tmp); totallen = tmp; #undef XFS_ATTR_ABS } /* * Calculate the number of usedbytes that will end up in lower block. * If new entry not in lower block, fix up the count. */ totallen -= count * sizeof(*entry); if (foundit) { totallen -= sizeof(*entry) + xfs_attr_leaf_newentsize( state->args->namelen, state->args->valuelen, state->blocksize, NULL); } *countarg = count; *usedbytesarg = totallen; return(foundit); } /*======================================================================== * Routines used for shrinking the Btree. *========================================================================*/ /* * Check a leaf block and its neighbors to see if the block should be * collapsed into one or the other neighbor. Always keep the block * with the smaller block number. * If the current block is over 50% full, don't try to join it, return 0. * If the block is empty, fill in the state structure and return 2. * If it can be collapsed, fill in the state structure and return 1. * If nothing can be done, return 0. * * GROT: allow for INCOMPLETE entries in calculation. */ int xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) { xfs_attr_leafblock_t *leaf; xfs_da_state_blk_t *blk; xfs_da_blkinfo_t *info; int count, bytes, forward, error, retval, i; xfs_dablk_t blkno; xfs_dabuf_t *bp; /* * Check for the degenerate case of the block being over 50% full. * If so, it's not worth even looking to see if we might be able * to coalesce with a sibling. */ blk = &state->path.blk[ state->path.active-1 ]; info = blk->bp->data; ASSERT(be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); leaf = (xfs_attr_leafblock_t *)info; count = be16_to_cpu(leaf->hdr.count); bytes = sizeof(xfs_attr_leaf_hdr_t) + count * sizeof(xfs_attr_leaf_entry_t) + be16_to_cpu(leaf->hdr.usedbytes); if (bytes > (state->blocksize >> 1)) { *action = 0; /* blk over 50%, don't try to join */ return(0); } /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to * coalesce it with a sibling block. We choose (arbitrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { /* * Make altpath point to the block we want to keep and * path point to the block we want to drop (this one). */ forward = (info->forw != 0); memcpy(&state->altpath, &state->path, sizeof(state->path)); error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); if (error) return(error); if (retval) { *action = 0; } else { *action = 2; } return(0); } /* * Examine each sibling block to see if we can coalesce with * at least 25% free space to spare. We need to figure out * whether to merge with the forward or the backward block. * We prefer coalescing with the lower numbered sibling so as * to shrink an attribute list over time. */ /* start with smaller blk num */ forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); for (i = 0; i < 2; forward = !forward, i++) { if (forward) blkno = be32_to_cpu(info->forw); else blkno = be32_to_cpu(info->back); if (blkno == 0) continue; error = xfs_da_read_buf(state->args->trans, state->args->dp, blkno, -1, &bp, XFS_ATTR_FORK); if (error) return(error); ASSERT(bp != NULL); leaf = (xfs_attr_leafblock_t *)info; count = be16_to_cpu(leaf->hdr.count); bytes = state->blocksize - (state->blocksize>>2); bytes -= be16_to_cpu(leaf->hdr.usedbytes); leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); count += be16_to_cpu(leaf->hdr.count); bytes -= be16_to_cpu(leaf->hdr.usedbytes); bytes -= count * sizeof(xfs_attr_leaf_entry_t); bytes -= sizeof(xfs_attr_leaf_hdr_t); xfs_da_brelse(state->args->trans, bp); if (bytes >= 0) break; /* fits with at least 25% to spare */ } if (i >= 2) { *action = 0; return(0); } /* * Make altpath point to the block we want to keep (the lower * numbered block) and path point to the block we want to drop. */ memcpy(&state->altpath, &state->path, sizeof(state->path)); if (blkno < blk->blkno) { error = xfs_da_path_shift(state, &state->altpath, forward, 0, &retval); } else { error = xfs_da_path_shift(state, &state->path, forward, 0, &retval); } if (error) return(error); if (retval) { *action = 0; } else { *action = 1; } return(0); } /* * Remove a name from the leaf attribute list structure. * * Return 1 if leaf is less than 37% full, 0 if >= 37% full. * If two leaves are 37% full, when combined they will leave 25% free. */ int xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_hdr_t *hdr; xfs_attr_leaf_map_t *map; xfs_attr_leaf_entry_t *entry; int before, after, smallest, entsize; int tablesize, tmp, i; xfs_mount_t *mp; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr = &leaf->hdr; mp = args->trans->t_mountp; ASSERT((be16_to_cpu(hdr->count) > 0) && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); ASSERT((args->index >= 0) && (args->index < be16_to_cpu(hdr->count))); ASSERT(be16_to_cpu(hdr->firstused) >= ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); entry = &leaf->entries[args->index]; ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); /* * Scan through free region table: * check for adjacency of free'd entry with an existing one, * find smallest free region in case we need to replace it, * adjust any map that borders the entry table, */ tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); map = &hdr->freemap[0]; tmp = be16_to_cpu(map->size); before = after = -1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1; entsize = xfs_attr_leaf_entsize(leaf, args->index); for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); if (be16_to_cpu(map->base) == tablesize) { be16_add_cpu(&map->base, -((int)sizeof(xfs_attr_leaf_entry_t))); be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t)); } if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) == be16_to_cpu(entry->nameidx)) { before = i; } else if (be16_to_cpu(map->base) == (be16_to_cpu(entry->nameidx) + entsize)) { after = i; } else if (be16_to_cpu(map->size) < tmp) { tmp = be16_to_cpu(map->size); smallest = i; } } /* * Coalesce adjacent freemap regions, * or replace the smallest region. */ if ((before >= 0) || (after >= 0)) { if ((before >= 0) && (after >= 0)) { map = &hdr->freemap[before]; be16_add_cpu(&map->size, entsize); be16_add_cpu(&map->size, be16_to_cpu(hdr->freemap[after].size)); hdr->freemap[after].base = 0; hdr->freemap[after].size = 0; } else if (before >= 0) { map = &hdr->freemap[before]; be16_add_cpu(&map->size, entsize); } else { map = &hdr->freemap[after]; /* both on-disk, don't endian flip twice */ map->base = entry->nameidx; be16_add_cpu(&map->size, entsize); } } else { /* * Replace smallest region (if it is smaller than free'd entry) */ map = &hdr->freemap[smallest]; if (be16_to_cpu(map->size) < entsize) { map->base = cpu_to_be16(be16_to_cpu(entry->nameidx)); map->size = cpu_to_be16(entsize); } } /* * Did we remove the first entry? */ if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) smallest = 1; else smallest = 0; /* * Compress the remaining entries and zero out the removed stuff. */ memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); be16_add_cpu(&hdr->usedbytes, -entsize); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), entsize)); tmp = (be16_to_cpu(hdr->count) - args->index) * sizeof(xfs_attr_leaf_entry_t); memmove((char *)entry, (char *)(entry+1), tmp); be16_add_cpu(&hdr->count, -1); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); entry = &leaf->entries[be16_to_cpu(hdr->count)]; memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); /* * If we removed the first entry, re-find the first used byte * in the name area. Note that if the entry was the "firstused", * then we don't have a "hole" in our block resulting from * removing the name. */ if (smallest) { tmp = XFS_LBSIZE(mp); entry = &leaf->entries[0]; for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); if (be16_to_cpu(entry->nameidx) < tmp) tmp = be16_to_cpu(entry->nameidx); } hdr->firstused = cpu_to_be16(tmp); if (!hdr->firstused) { hdr->firstused = cpu_to_be16( tmp - XFS_ATTR_LEAF_NAME_ALIGN); } } else { hdr->holes = 1; /* mark as needing compaction */ } xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); /* * Check if leaf is less than 50% full, caller may want to * "join" the leaf with a sibling if so. */ tmp = sizeof(xfs_attr_leaf_hdr_t); tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t); tmp += be16_to_cpu(leaf->hdr.usedbytes); return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */ } /* * Move all the attribute list entries from drop_leaf into save_leaf. */ void xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk) { xfs_attr_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; xfs_attr_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; xfs_mount_t *mp; char *tmpbuffer; /* * Set up environment. */ mp = state->mp; ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC); ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); drop_leaf = drop_blk->bp->data; save_leaf = save_blk->bp->data; ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); drop_hdr = &drop_leaf->hdr; save_hdr = &save_leaf->hdr; /* * Save last hashval from dying block for later Btree fixup. */ drop_blk->hashval = be32_to_cpu( drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval); /* * Check if we need a temp buffer, or can we do it in place. * Note that we don't check "leaf" for holes because we will * always be dropping it, toosmall() decided that for us already. */ if (save_hdr->holes == 0) { /* * dest leaf has no holes, so we add there. May need * to make some room in the entry array. */ if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0, be16_to_cpu(drop_hdr->count), mp); } else { xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, be16_to_cpu(save_hdr->count), be16_to_cpu(drop_hdr->count), mp); } } else { /* * Destination has holes, so we make a temporary copy * of the leaf and add them both to that. */ tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); ASSERT(tmpbuffer != NULL); memset(tmpbuffer, 0, state->blocksize); tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer; tmp_hdr = &tmp_leaf->hdr; tmp_hdr->info = save_hdr->info; /* struct copy */ tmp_hdr->count = 0; tmp_hdr->firstused = cpu_to_be16(state->blocksize); if (!tmp_hdr->firstused) { tmp_hdr->firstused = cpu_to_be16( state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN); } tmp_hdr->usedbytes = 0; if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, be16_to_cpu(drop_hdr->count), mp); xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), be16_to_cpu(save_hdr->count), mp); } else { xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0, be16_to_cpu(save_hdr->count), mp); xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), be16_to_cpu(drop_hdr->count), mp); } memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); kmem_free(tmpbuffer); } xfs_da_log_buf(state->args->trans, save_blk->bp, 0, state->blocksize - 1); /* * Copy out last hashval in each block for B-tree code. */ save_blk->hashval = be32_to_cpu( save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval); } /*======================================================================== * Routines used for finding things in the Btree. *========================================================================*/ /* * Look up a name in a leaf attribute list structure. * This is the internal routine, it uses the caller's buffer. * * Note that duplicate keys are allowed, but only check within the * current leaf node. The Btree code must check in adjacent leaf nodes. * * Return in args->index the index into the entry[] array of either * the found entry, or where the entry should have been (insert before * that entry). * * Don't change the args->value unless we find the attribute. */ int xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; int probe, span; xfs_dahash_t hashval; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(be16_to_cpu(leaf->hdr.count) < (XFS_LBSIZE(args->dp->i_mount)/8)); /* * Binary search. (note: small blocks will skip this loop) */ hashval = args->hashval; probe = span = be16_to_cpu(leaf->hdr.count) / 2; for (entry = &leaf->entries[probe]; span > 4; entry = &leaf->entries[probe]) { span /= 2; if (be32_to_cpu(entry->hashval) < hashval) probe += span; else if (be32_to_cpu(entry->hashval) > hashval) probe -= span; else break; } ASSERT((probe >= 0) && (!leaf->hdr.count || (probe < be16_to_cpu(leaf->hdr.count)))); ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); /* * Since we may have duplicate hashval's, find the first matching * hashval in the leaf. */ while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { entry--; probe--; } while ((probe < be16_to_cpu(leaf->hdr.count)) && (be32_to_cpu(entry->hashval) < hashval)) { entry++; probe++; } if ((probe == be16_to_cpu(leaf->hdr.count)) || (be32_to_cpu(entry->hashval) != hashval)) { args->index = probe; return(XFS_ERROR(ENOATTR)); } /* * Duplicate keys may be present, so search all of them for a match. */ for ( ; (probe < be16_to_cpu(leaf->hdr.count)) && (be32_to_cpu(entry->hashval) == hashval); entry++, probe++) { /* * GROT: Add code to remove incomplete entries. */ /* * If we are looking for INCOMPLETE entries, show only those. * If we are looking for complete entries, show only those. */ if ((args->flags & XFS_ATTR_INCOMPLETE) != (entry->flags & XFS_ATTR_INCOMPLETE)) { continue; } if (entry->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf, probe); if (name_loc->namelen != args->namelen) continue; if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; return(XFS_ERROR(EEXIST)); } else { name_rmt = xfs_attr_leaf_name_remote(leaf, probe); if (name_rmt->namelen != args->namelen) continue; if (memcmp(args->name, (char *)name_rmt->name, args->namelen) != 0) continue; if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; args->rmtblkno = be32_to_cpu(name_rmt->valueblk); args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, be32_to_cpu(name_rmt->valuelen)); return(XFS_ERROR(EEXIST)); } } args->index = probe; return(XFS_ERROR(ENOATTR)); } /* * Get the value associated with an attribute name from a leaf attribute * list structure. */ int xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) { int valuelen; xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(be16_to_cpu(leaf->hdr.count) < (XFS_LBSIZE(args->dp->i_mount)/8)); ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); entry = &leaf->entries[args->index]; if (entry->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf, args->index); ASSERT(name_loc->namelen == args->namelen); ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); valuelen = be16_to_cpu(name_loc->valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; return(0); } if (args->valuelen < valuelen) { args->valuelen = valuelen; return(XFS_ERROR(ERANGE)); } args->valuelen = valuelen; memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); } else { name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); ASSERT(name_rmt->namelen == args->namelen); ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; return(0); } if (args->valuelen < valuelen) { args->valuelen = valuelen; return(XFS_ERROR(ERANGE)); } args->valuelen = valuelen; } return(0); } /*======================================================================== * Utility routines. *========================================================================*/ /* * Move the indicated entries from one leaf to another. * NOTE: this routine modifies both source and destination leaves. */ /*ARGSUSED*/ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, xfs_attr_leafblock_t *leaf_d, int start_d, int count, xfs_mount_t *mp) { xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; xfs_attr_leaf_entry_t *entry_s, *entry_d; int desti, tmp, i; /* * Check for nothing to do. */ if (count == 0) return; /* * Set up environment. */ ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); hdr_s = &leaf_s->hdr; hdr_d = &leaf_d->hdr; ASSERT((be16_to_cpu(hdr_s->count) > 0) && (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); ASSERT(be16_to_cpu(hdr_s->firstused) >= ((be16_to_cpu(hdr_s->count) * sizeof(*entry_s))+sizeof(*hdr_s))); ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); ASSERT(be16_to_cpu(hdr_d->firstused) >= ((be16_to_cpu(hdr_d->count) * sizeof(*entry_d))+sizeof(*hdr_d))); ASSERT(start_s < be16_to_cpu(hdr_s->count)); ASSERT(start_d <= be16_to_cpu(hdr_d->count)); ASSERT(count <= be16_to_cpu(hdr_s->count)); /* * Move the entries in the destination leaf up to make a hole? */ if (start_d < be16_to_cpu(hdr_d->count)) { tmp = be16_to_cpu(hdr_d->count) - start_d; tmp *= sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_d->entries[start_d]; entry_d = &leaf_d->entries[start_d + count]; memmove((char *)entry_d, (char *)entry_s, tmp); } /* * Copy all entry's in the same (sorted) order, * but allocate attribute info packed and in sequence. */ entry_s = &leaf_s->entries[start_s]; entry_d = &leaf_d->entries[start_d]; desti = start_d; for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) { ASSERT(be16_to_cpu(entry_s->nameidx) >= be16_to_cpu(hdr_s->firstused)); tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i); #ifdef GROT /* * Code to drop INCOMPLETE entries. Difficult to use as we * may also need to change the insertion index. Code turned * off for 6.2, should be revisited later. */ if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); be16_add_cpu(&hdr_s->usedbytes, -tmp); be16_add_cpu(&hdr_s->count, -1); entry_d--; /* to compensate for ++ in loop hdr */ desti--; if ((start_s + i) < offset) result++; /* insertion index adjustment */ } else { #endif /* GROT */ be16_add_cpu(&hdr_d->firstused, -tmp); /* both on-disk, don't endian flip twice */ entry_d->hashval = entry_s->hashval; /* both on-disk, don't endian flip twice */ entry_d->nameidx = hdr_d->firstused; entry_d->flags = entry_s->flags; ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); memmove(xfs_attr_leaf_name(leaf_d, desti), xfs_attr_leaf_name(leaf_s, start_s + i), tmp); ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); be16_add_cpu(&hdr_s->usedbytes, -tmp); be16_add_cpu(&hdr_d->usedbytes, tmp); be16_add_cpu(&hdr_s->count, -1); be16_add_cpu(&hdr_d->count, 1); tmp = be16_to_cpu(hdr_d->count) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t); ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); #ifdef GROT } #endif /* GROT */ } /* * Zero out the entries we just copied. */ if (start_s == be16_to_cpu(hdr_s->count)) { tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_s->entries[start_s]; ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); memset((char *)entry_s, 0, tmp); } else { /* * Move the remaining entries down to fill the hole, * then zero the entries at the top. */ tmp = be16_to_cpu(hdr_s->count) - count; tmp *= sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_s->entries[start_s + count]; entry_d = &leaf_s->entries[start_s]; memmove((char *)entry_d, (char *)entry_s, tmp); tmp = count * sizeof(xfs_attr_leaf_entry_t); entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; ASSERT(((char *)entry_s + tmp) <= ((char *)leaf_s + XFS_LBSIZE(mp))); memset((char *)entry_s, 0, tmp); } /* * Fill in the freemap information */ hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * sizeof(xfs_attr_leaf_entry_t)); hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - be16_to_cpu(hdr_d->freemap[0].base)); hdr_d->freemap[1].base = 0; hdr_d->freemap[2].base = 0; hdr_d->freemap[1].size = 0; hdr_d->freemap[2].size = 0; hdr_s->holes = 1; /* leaf may not be compact */ } /* * Compare two leaf blocks "order". * Return 0 unless leaf2 should go before leaf1. */ int xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) { xfs_attr_leafblock_t *leaf1, *leaf2; leaf1 = leaf1_bp->data; leaf2 = leaf2_bp->data; ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) && (be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC)); if ((be16_to_cpu(leaf1->hdr.count) > 0) && (be16_to_cpu(leaf2->hdr.count) > 0) && ((be32_to_cpu(leaf2->entries[0].hashval) < be32_to_cpu(leaf1->entries[0].hashval)) || (be32_to_cpu(leaf2->entries[ be16_to_cpu(leaf2->hdr.count)-1].hashval) < be32_to_cpu(leaf1->entries[ be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { return(1); } return(0); } /* * Pick up the last hashvalue from a leaf block. */ xfs_dahash_t xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) { xfs_attr_leafblock_t *leaf; leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if (count) *count = be16_to_cpu(leaf->hdr.count); if (!leaf->hdr.count) return(0); return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); } /* * Calculate the number of bytes used to store the indicated attribute * (whether local or remote only calculate bytes in this block). */ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) { xfs_attr_leaf_name_local_t *name_loc; xfs_attr_leaf_name_remote_t *name_rmt; int size; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf, index); size = xfs_attr_leaf_entsize_local(name_loc->namelen, be16_to_cpu(name_loc->valuelen)); } else { name_rmt = xfs_attr_leaf_name_remote(leaf, index); size = xfs_attr_leaf_entsize_remote(name_rmt->namelen); } return(size); } /* * Calculate the number of bytes that would be required to store the new * attribute (whether local or remote only calculate bytes in this block). * This routine decides as a side effect whether the attribute will be * a "local" or a "remote" attribute. */ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) { int size; size = xfs_attr_leaf_entsize_local(namelen, valuelen); if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { if (local) { *local = 1; } } else { size = xfs_attr_leaf_entsize_remote(namelen); if (local) { *local = 0; } } return(size); } /*======================================================================== * Manage the INCOMPLETE flag in a leaf entry *========================================================================*/ /* * Clear the INCOMPLETE flag on an entry in a leaf block. */ int xfs_attr_leaf_clearflag(xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_remote_t *name_rmt; xfs_dabuf_t *bp; int error; #ifdef DEBUG xfs_attr_leaf_name_local_t *name_loc; int namelen; char *name; #endif /* DEBUG */ /* * Set up the operation. */ error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) { return(error); } ASSERT(bp != NULL); leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); ASSERT(args->index >= 0); entry = &leaf->entries[ args->index ]; ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); #ifdef DEBUG if (entry->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf, args->index); namelen = name_loc->namelen; name = (char *)name_loc->nameval; } else { name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); namelen = name_rmt->namelen; name = (char *)name_rmt->name; } ASSERT(be32_to_cpu(entry->hashval) == args->hashval); ASSERT(namelen == args->namelen); ASSERT(memcmp(name, args->name, namelen) == 0); #endif /* DEBUG */ entry->flags &= ~XFS_ATTR_INCOMPLETE; xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); if (args->rmtblkno) { ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } xfs_da_buf_done(bp); /* * Commit the flag value change and start the next trans in series. */ return xfs_trans_roll(&args->trans, args->dp); } /* * Set the INCOMPLETE flag on an entry in a leaf block. */ int xfs_attr_leaf_setflag(xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_remote_t *name_rmt; xfs_dabuf_t *bp; int error; /* * Set up the operation. */ error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, XFS_ATTR_FORK); if (error) { return(error); } ASSERT(bp != NULL); leaf = bp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); ASSERT(args->index >= 0); entry = &leaf->entries[ args->index ]; ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); entry->flags |= XFS_ATTR_INCOMPLETE; xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); if ((entry->flags & XFS_ATTR_LOCAL) == 0) { name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->valueblk = 0; name_rmt->valuelen = 0; xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } xfs_da_buf_done(bp); /* * Commit the flag value change and start the next trans in series. */ return xfs_trans_roll(&args->trans, args->dp); } /* * In a single transaction, clear the INCOMPLETE flag on the leaf entry * given by args->blkno/index and set the INCOMPLETE flag on the leaf * entry given by args->blkno2/index2. * * Note that they could be in different blocks, or in the same block. */ int xfs_attr_leaf_flipflags(xfs_da_args_t *args) { xfs_attr_leafblock_t *leaf1, *leaf2; xfs_attr_leaf_entry_t *entry1, *entry2; xfs_attr_leaf_name_remote_t *name_rmt; xfs_dabuf_t *bp1, *bp2; int error; #ifdef DEBUG xfs_attr_leaf_name_local_t *name_loc; int namelen1, namelen2; char *name1, *name2; #endif /* DEBUG */ /* * Read the block containing the "old" attr */ error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp1, XFS_ATTR_FORK); if (error) { return(error); } ASSERT(bp1 != NULL); /* * Read the block containing the "new" attr, if it is different */ if (args->blkno2 != args->blkno) { error = xfs_da_read_buf(args->trans, args->dp, args->blkno2, -1, &bp2, XFS_ATTR_FORK); if (error) { return(error); } ASSERT(bp2 != NULL); } else { bp2 = bp1; } leaf1 = bp1->data; ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); ASSERT(args->index >= 0); entry1 = &leaf1->entries[ args->index ]; leaf2 = bp2->data; ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); ASSERT(args->index2 >= 0); entry2 = &leaf2->entries[ args->index2 ]; #ifdef DEBUG if (entry1->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf1, args->index); namelen1 = name_loc->namelen; name1 = (char *)name_loc->nameval; } else { name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); namelen1 = name_rmt->namelen; name1 = (char *)name_rmt->name; } if (entry2->flags & XFS_ATTR_LOCAL) { name_loc = xfs_attr_leaf_name_local(leaf2, args->index2); namelen2 = name_loc->namelen; name2 = (char *)name_loc->nameval; } else { name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); namelen2 = name_rmt->namelen; name2 = (char *)name_rmt->name; } ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval)); ASSERT(namelen1 == namelen2); ASSERT(memcmp(name1, name2, namelen1) == 0); #endif /* DEBUG */ ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE); ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0); entry1->flags &= ~XFS_ATTR_INCOMPLETE; xfs_da_log_buf(args->trans, bp1, XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); if (args->rmtblkno) { ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp1, XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); } entry2->flags |= XFS_ATTR_INCOMPLETE; xfs_da_log_buf(args->trans, bp2, XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); name_rmt->valueblk = 0; name_rmt->valuelen = 0; xfs_da_log_buf(args->trans, bp2, XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); } xfs_da_buf_done(bp1); if (bp1 != bp2) xfs_da_buf_done(bp2); /* * Commit the flag value change and start the next trans in series. */ error = xfs_trans_roll(&args->trans, args->dp); return(error); } xfsprogs-3.1.9ubuntu2/libxfs/logitem.c0000664000000000000000000001030711650373061014712 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include kmem_zone_t *xfs_buf_item_zone; kmem_zone_t *xfs_ili_zone; /* inode log item zone */ /* * Following functions from fs/xfs/xfs_trans_buf.c */ /* * Check to see if a buffer matching the given parameters is already * a part of the given transaction. */ xfs_buf_t * xfs_trans_buf_item_match( xfs_trans_t *tp, xfs_buftarg_t *target, xfs_daddr_t blkno, int len) { struct xfs_log_item_desc *lidp; struct xfs_buf_log_item *blip; len = BBTOB(len); list_for_each_entry(lidp, &tp->t_items, lid_trans) { blip = (struct xfs_buf_log_item *)lidp->lid_item; if (blip->bli_item.li_type == XFS_LI_BUF && XFS_BUF_TARGET(blip->bli_buf) == target->dev && XFS_BUF_ADDR(blip->bli_buf) == blkno && XFS_BUF_COUNT(blip->bli_buf) == len) return blip->bli_buf; } return NULL; } /* * The following are from fs/xfs/xfs_buf_item.c */ /* * Allocate a new buf log item to go with the given buffer. * Set the buffer's b_fsprivate field to point to the new * buf log item. If there are other item's attached to the * buffer (see xfs_buf_attach_iodone() below), then put the * buf log item at the front. */ void xfs_buf_item_init( xfs_buf_t *bp, xfs_mount_t *mp) { xfs_log_item_t *lip; xfs_buf_log_item_t *bip; #ifdef LI_DEBUG fprintf(stderr, "buf_item_init for buffer %p\n", bp); #endif /* * Check to see if there is already a buf log item for * this buffer. If there is, it is guaranteed to be * the first. If we do already have one, there is * nothing to do here so return. */ if (XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *) != mp) XFS_BUF_SET_FSPRIVATE3(bp, mp); XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb); if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); if (lip->li_type == XFS_LI_BUF) { #ifdef LI_DEBUG fprintf(stderr, "reused buf item %p for pre-logged buffer %p\n", lip, bp); #endif return; } } bip = (xfs_buf_log_item_t *)kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); #ifdef LI_DEBUG fprintf(stderr, "adding buf item %p for not-logged buffer %p\n", bip, bp); #endif bip->bli_item.li_type = XFS_LI_BUF; bip->bli_item.li_mountp = mp; bip->bli_buf = bp; bip->bli_format.blf_type = XFS_LI_BUF; bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); XFS_BUF_SET_FSPRIVATE(bp, bip); } /* * Mark bytes first through last inclusive as dirty in the buf * item's bitmap. */ void xfs_buf_item_log( xfs_buf_log_item_t *bip, uint first, uint last) { /* * Mark the item as having some dirty data for * quick reference in xfs_buf_item_dirty. */ bip->bli_flags |= XFS_BLI_DIRTY; } /* * Initialize the inode log item for a newly allocated (in-core) inode. */ void xfs_inode_item_init( xfs_inode_t *ip, xfs_mount_t *mp) { xfs_inode_log_item_t *iip; ASSERT(ip->i_itemp == NULL); iip = ip->i_itemp = (xfs_inode_log_item_t *) kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP); #ifdef LI_DEBUG fprintf(stderr, "inode_item_init for inode %llu, iip=%p\n", ip->i_ino, iip); #endif iip->ili_item.li_type = XFS_LI_INODE; iip->ili_item.li_mountp = mp; iip->ili_inode = ip; iip->ili_format.ilf_type = XFS_LI_INODE; iip->ili_format.ilf_ino = ip->i_ino; iip->ili_format.ilf_blkno = ip->i_imap.im_blkno; iip->ili_format.ilf_len = ip->i_imap.im_len; iip->ili_format.ilf_boffset = ip->i_imap.im_boffset; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_dir2_block.c0000664000000000000000000010046311650373061016147 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Local function prototypes. */ static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, int last); static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, int *entno); static int xfs_dir2_block_sort(const void *a, const void *b); static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; /* * One-time startup routine called from xfs_init(). */ void xfs_dir_startup(void) { xfs_dir_hash_dot = xfs_da_hashname((unsigned char *)".", 1); xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2); } /* * Add an entry to a block directory. */ int /* error */ xfs_dir2_block_addname( xfs_da_args_t *args) /* directory op arguments */ { xfs_dir2_data_free_t *bf; /* bestfree table in block */ xfs_dir2_block_t *block; /* directory block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* buffer for block */ xfs_dir2_block_tail_t *btp; /* block tail */ int compact; /* need to compact leaf ents */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* directory inode */ xfs_dir2_data_unused_t *dup; /* block unused entry */ int error; /* error return value */ xfs_dir2_data_unused_t *enddup=NULL; /* unused at end of data */ xfs_dahash_t hash; /* hash value of found entry */ int high; /* high index for binary srch */ int highstale; /* high stale index */ int lfloghigh=0; /* last final leaf to log */ int lfloglow=0; /* first final leaf to log */ int len; /* length of the new entry */ int low; /* low index for binary srch */ int lowstale; /* low stale index */ int mid=0; /* midpoint for binary srch */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log header */ int needscan; /* need to rescan freespace */ __be16 *tagp; /* pointer to tag value */ xfs_trans_t *tp; /* transaction structure */ trace_xfs_dir2_block_addname(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; /* * Read the (one and only) directory block into dabuf bp. */ if ((error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { return error; } ASSERT(bp != NULL); block = bp->data; /* * Check the magic number, corrupted if wrong. */ if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", XFS_ERRLEVEL_LOW, mp, block); xfs_da_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } len = xfs_dir2_data_entsize(args->namelen); /* * Set up pointers to parts of the block. */ bf = block->hdr.bestfree; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * No stale entries? Need space for entry and new leaf. */ if (!btp->stale) { /* * Tag just before the first leaf entry. */ tagp = (__be16 *)blp - 1; /* * Data object just before the first leaf entry. */ enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free then can't do this add without cleaning up: * the space before the first leaf entry needs to be free so it * can be expanded to hold the pointer to the new entry. */ if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG) dup = enddup = NULL; /* * Check out the biggest freespace and see if it's the same one. */ else { dup = (xfs_dir2_data_unused_t *) ((char *)block + be16_to_cpu(bf[0].offset)); if (dup == enddup) { /* * It is the biggest freespace, is it too small * to hold the new leaf too? */ if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) { /* * Yes, we use the second-largest * entry instead if it works. */ if (be16_to_cpu(bf[1].length) >= len) dup = (xfs_dir2_data_unused_t *) ((char *)block + be16_to_cpu(bf[1].offset)); else dup = NULL; } } else { /* * Not the same free entry, * just check its length. */ if (be16_to_cpu(dup->length) < len) { dup = NULL; } } } compact = 0; } /* * If there are stale entries we'll use one for the leaf. * Is the biggest entry enough to avoid compaction? */ else if (be16_to_cpu(bf[0].length) >= len) { dup = (xfs_dir2_data_unused_t *) ((char *)block + be16_to_cpu(bf[0].offset)); compact = 0; } /* * Will need to compact to make this work. */ else { /* * Tag just before the first leaf entry. */ tagp = (__be16 *)blp - 1; /* * Data object just before the first leaf entry. */ dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free then the data will go where the * leaf data starts now, if it works at all. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) dup = NULL; } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) dup = NULL; else dup = (xfs_dir2_data_unused_t *)blp; compact = 1; } /* * If this isn't a real add, we're done with the buffer. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) xfs_da_brelse(tp, bp); /* * If we don't have space for the new entry & leaf ... */ if (!dup) { /* * Not trying to actually do anything, or don't have * a space reservation: return no-space. */ if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) return XFS_ERROR(ENOSPC); /* * Convert to the next larger format. * Then add the new entry in that format. */ error = xfs_dir2_block_to_leaf(args, bp); xfs_da_buf_done(bp); if (error) return error; return xfs_dir2_leaf_addname(args); } /* * Just checking, and it would work, so say so. */ if (args->op_flags & XFS_DA_OP_JUSTCHECK) return 0; needlog = needscan = 0; /* * If need to compact the leaf entries, do it now. * Leave the highest-numbered stale entry stale. * XXX should be the one closest to mid but mid is not yet computed. */ if (compact) { int fromidx; /* source leaf index */ int toidx; /* target leaf index */ for (fromidx = toidx = be32_to_cpu(btp->count) - 1, highstale = lfloghigh = -1; fromidx >= 0; fromidx--) { if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) { if (highstale == -1) highstale = toidx; else { if (lfloghigh == -1) lfloghigh = toidx; continue; } } if (fromidx < toidx) blp[toidx] = blp[fromidx]; toidx--; } lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); lfloghigh -= be32_to_cpu(btp->stale) - 1; be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); xfs_dir2_data_make_free(tp, bp, (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), &needlog, &needscan); blp += be32_to_cpu(btp->stale) - 1; btp->stale = cpu_to_be32(1); /* * If we now need to rebuild the bestfree map, do so. * This needs to happen before the next call to use_free. */ if (needscan) { xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); needscan = 0; } } /* * Set leaf logging boundaries to impossible state. * For the no-stale case they're set explicitly. */ else if (btp->stale) { lfloglow = be32_to_cpu(btp->count); lfloghigh = -1; } /* * Find the slot that's first lower than our hash value, -1 if none. */ for (low = 0, high = be32_to_cpu(btp->count) - 1; low <= high; ) { mid = (low + high) >> 1; if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) break; if (hash < args->hashval) low = mid + 1; else high = mid - 1; } while (mid >= 0 && be32_to_cpu(blp[mid].hashval) >= args->hashval) { mid--; } /* * No stale entries, will use enddup space to hold new leaf. */ if (!btp->stale) { /* * Mark the space needed for the new leaf entry, now in use. */ xfs_dir2_data_use_free(tp, bp, enddup, (xfs_dir2_data_aoff_t) ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - sizeof(*blp)), (xfs_dir2_data_aoff_t)sizeof(*blp), &needlog, &needscan); /* * Update the tail (entry count). */ be32_add_cpu(&btp->count, 1); /* * If we now need to rebuild the bestfree map, do so. * This needs to happen before the next call to use_free. */ if (needscan) { xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); needscan = 0; } /* * Adjust pointer to the first leaf entry, we're about to move * the table up one to open up space for the new leaf entry. * Then adjust our index to match. */ blp--; mid++; if (mid) memmove(blp, &blp[1], mid * sizeof(*blp)); lfloglow = 0; lfloghigh = mid; } /* * Use a stale leaf for our new entry. */ else { for (lowstale = mid; lowstale >= 0 && be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR; lowstale--) continue; for (highstale = mid + 1; highstale < be32_to_cpu(btp->count) && be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR && (lowstale < 0 || mid - lowstale > highstale - mid); highstale++) continue; /* * Move entries toward the low-numbered stale entry. */ if (lowstale >= 0 && (highstale == be32_to_cpu(btp->count) || mid - lowstale <= highstale - mid)) { if (mid - lowstale) memmove(&blp[lowstale], &blp[lowstale + 1], (mid - lowstale) * sizeof(*blp)); lfloglow = MIN(lowstale, lfloglow); lfloghigh = MAX(mid, lfloghigh); } /* * Move entries toward the high-numbered stale entry. */ else { ASSERT(highstale < be32_to_cpu(btp->count)); mid++; if (highstale - mid) memmove(&blp[mid + 1], &blp[mid], (highstale - mid) * sizeof(*blp)); lfloglow = MIN(mid, lfloglow); lfloghigh = MAX(highstale, lfloghigh); } be32_add_cpu(&btp->stale, -1); } /* * Point to the new data entry. */ dep = (xfs_dir2_data_entry_t *)dup; /* * Fill in the leaf entry. */ blp[mid].hashval = cpu_to_be32(args->hashval); blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); /* * Mark space for the data entry used. */ xfs_dir2_data_use_free(tp, bp, dup, (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), (xfs_dir2_data_aoff_t)len, &needlog, &needscan); /* * Create the new data entry. */ dep->inumber = cpu_to_be64(args->inumber); dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)block); /* * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_block_log_tail(tp, bp); xfs_dir2_data_log_entry(tp, bp, dep); xfs_dir2_data_check(dp, bp); xfs_da_buf_done(bp); return 0; } /* * Log leaf entries from the block. */ static void xfs_dir2_block_log_leaf( xfs_trans_t *tp, /* transaction structure */ xfs_dabuf_t *bp, /* block buffer */ int first, /* index of first logged leaf */ int last) /* index of last logged leaf */ { xfs_dir2_block_t *block; /* directory block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_mount_t *mp; /* filesystem mount point */ mp = tp->t_mountp; block = bp->data; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), (uint)((char *)&blp[last + 1] - (char *)block - 1)); } /* * Log the block tail. */ static void xfs_dir2_block_log_tail( xfs_trans_t *tp, /* transaction structure */ xfs_dabuf_t *bp) /* block buffer */ { xfs_dir2_block_t *block; /* directory block structure */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_mount_t *mp; /* filesystem mount point */ mp = tp->t_mountp; block = bp->data; btp = xfs_dir2_block_tail_p(mp, block); xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), (uint)((char *)(btp + 1) - (char *)block - 1)); } /* * Look up an entry in the block. This is the external routine, * xfs_dir2_block_lookup_int does the real work. */ int /* error */ xfs_dir2_block_lookup( xfs_da_args_t *args) /* dir lookup arguments */ { xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ int ent; /* entry index */ int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ trace_xfs_dir2_block_lookup(args); /* * Get the buffer, look up the entry. * If not found (ENOENT) then return, have no buffer. */ if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) return error; dp = args->dp; mp = dp->i_mount; block = bp->data; xfs_dir2_data_check(dp, bp); btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Get the offset from the leaf entry, to point to the data. */ dep = (xfs_dir2_data_entry_t *)((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Fill in inode number, CI name if appropriate, release the block. */ args->inumber = be64_to_cpu(dep->inumber); error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); xfs_da_brelse(args->trans, bp); return XFS_ERROR(error); } /* * Internal block lookup routine. */ static int /* error */ xfs_dir2_block_lookup_int( xfs_da_args_t *args, /* dir lookup arguments */ xfs_dabuf_t **bpp, /* returned block buffer */ int *entno) /* returned entry number */ { xfs_dir2_dataptr_t addr; /* data entry address */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ int error; /* error return value */ xfs_dahash_t hash; /* found hash value */ int high; /* binary search high index */ int low; /* binary search low index */ int mid; /* binary search current idx */ xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ enum xfs_dacmp cmp; /* comparison result */ dp = args->dp; tp = args->trans; mp = dp->i_mount; /* * Read the buffer, return error if we can't get it. */ if ((error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { return error; } ASSERT(bp != NULL); block = bp->data; xfs_dir2_data_check(dp, bp); btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Loop doing a binary search for our hash value. * Find our entry, ENOENT if it's not there. */ for (low = 0, high = be32_to_cpu(btp->count) - 1; ; ) { ASSERT(low <= high); mid = (low + high) >> 1; if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) break; if (hash < args->hashval) low = mid + 1; else high = mid - 1; if (low > high) { ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); xfs_da_brelse(tp, bp); return XFS_ERROR(ENOENT); } } /* * Back up to the first one with the right hash value. */ while (mid > 0 && be32_to_cpu(blp[mid - 1].hashval) == args->hashval) { mid--; } /* * Now loop forward through all the entries with the * right hash value looking for our name. */ do { if ((addr = be32_to_cpu(blp[mid].address)) == XFS_DIR2_NULL_DATAPTR) continue; /* * Get pointer to the entry from the leaf. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); /* * Compare name and if it's an exact match, return the index * and buffer. If it's the first case-insensitive match, store * the index and buffer and continue looking for an exact match. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; *bpp = bp; *entno = mid; if (cmp == XFS_CMP_EXACT) return 0; } } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash); ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); /* * Here, we can only be doing a lookup (not a rename or replace). * If a case-insensitive match was found earlier, return success. */ if (args->cmpresult == XFS_CMP_CASE) return 0; /* * No match, release the buffer and return ENOENT. */ xfs_da_brelse(tp, bp); return XFS_ERROR(ENOENT); } /* * Remove an entry from a block format directory. * If that makes the block small enough to fit in shortform, transform it. */ int /* error */ xfs_dir2_block_removename( xfs_da_args_t *args) /* directory operation args */ { xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ int ent; /* block leaf entry index */ int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log block header */ int needscan; /* need to fixup bestfree */ xfs_dir2_sf_hdr_t sfh; /* shortform header */ int size; /* shortform size */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_block_removename(args); /* * Look up the entry in the block. Gets the buffer and entry index. * It will always be there, the vnodeops level does a lookup first. */ if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { return error; } dp = args->dp; tp = args->trans; mp = dp->i_mount; block = bp->data; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry using the leaf entry. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Mark the data entry's space free. */ needlog = needscan = 0; xfs_dir2_data_make_free(tp, bp, (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * Fix up the block tail. */ be32_add_cpu(&btp->stale, 1); xfs_dir2_block_log_tail(tp, bp); /* * Remove the leaf entry by marking it stale. */ blp[ent].address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); xfs_dir2_block_log_leaf(tp, bp, ent, ent); /* * Fix up bestfree, log the header if necessary. */ if (needscan) xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_data_check(dp, bp); /* * See if the size as a shortform is good enough. */ if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > XFS_IFORK_DSIZE(dp)) { xfs_da_buf_done(bp); return 0; } /* * If it works, do the conversion. */ return xfs_dir2_block_to_sf(args, bp, size, &sfh); } /* * Replace an entry in a V2 block directory. * Change the inode number to the new value. */ int /* error */ xfs_dir2_block_replace( xfs_da_args_t *args) /* directory operation args */ { xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ xfs_inode_t *dp; /* incore inode */ int ent; /* leaf entry index */ int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ trace_xfs_dir2_block_replace(args); /* * Lookup the entry in the directory. Get buffer and entry index. * This will always succeed since the caller has already done a lookup. */ if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { return error; } dp = args->dp; mp = dp->i_mount; block = bp->data; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry we need to change. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); ASSERT(be64_to_cpu(dep->inumber) != args->inumber); /* * Change the inode number to the new value. */ dep->inumber = cpu_to_be64(args->inumber); xfs_dir2_data_log_entry(args->trans, bp, dep); xfs_dir2_data_check(dp, bp); xfs_da_buf_done(bp); return 0; } /* * Qsort comparison routine for the block leaf entries. */ static int /* sort order */ xfs_dir2_block_sort( const void *a, /* first leaf entry */ const void *b) /* second leaf entry */ { const xfs_dir2_leaf_entry_t *la; /* first leaf entry */ const xfs_dir2_leaf_entry_t *lb; /* second leaf entry */ la = a; lb = b; return be32_to_cpu(la->hashval) < be32_to_cpu(lb->hashval) ? -1 : (be32_to_cpu(la->hashval) > be32_to_cpu(lb->hashval) ? 1 : 0); } /* * Convert a V2 leaf directory to a V2 block directory if possible. */ int /* error */ xfs_dir2_leaf_to_block( xfs_da_args_t *args, /* operation arguments */ xfs_dabuf_t *lbp, /* leaf buffer */ xfs_dabuf_t *dbp) /* data buffer */ { __be16 *bestsp; /* leaf bests table */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused data entry */ int error; /* error return value */ int from; /* leaf from index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_mount_t *mp; /* file system mount point */ int needlog; /* need to log data header */ int needscan; /* need to scan for bestfree */ xfs_dir2_sf_hdr_t sfh; /* shortform header */ int size; /* bytes used */ __be16 *tagp; /* end of entry (tag) */ int to; /* block/leaf to index */ xfs_trans_t *tp; /* transaction pointer */ trace_xfs_dir2_leaf_to_block(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; leaf = lbp->data; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); /* * If there are data blocks other than the first one, take this * opportunity to remove trailing empty data blocks that may have * been left behind during no-space-reservation operations. * These will show up in the leaf bests table. */ while (dp->i_d.di_size > mp->m_dirblksize) { bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == mp->m_dirblksize - (uint)sizeof(block->hdr)) { if ((error = xfs_dir2_leaf_trim_data(args, lbp, (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) goto out; } else { error = 0; goto out; } } /* * Read the data block if we don't already have it, give up if it fails. */ if (dbp == NULL && (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, XFS_DATA_FORK))) { goto out; } block = dbp->data; ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); /* * Size of the "leaf" area in the block. */ size = (uint)sizeof(block->tail) + (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); /* * Look at the last data entry. */ tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); /* * If it's not free or is too short we can't do it. */ if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || be16_to_cpu(dup->length) < size) { error = 0; goto out; } /* * Start converting it to block form. */ block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); needlog = 1; needscan = 0; /* * Use up the space at the end of the block (blp/btp). */ xfs_dir2_data_use_free(tp, dbp, dup, mp->m_dirblksize - size, size, &needlog, &needscan); /* * Initialize the block tail. */ btp = xfs_dir2_block_tail_p(mp, block); btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); btp->stale = 0; xfs_dir2_block_log_tail(tp, dbp); /* * Initialize the block leaf area. We compact out stale entries. */ lep = xfs_dir2_block_leaf_p(btp); for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) continue; lep[to++] = leaf->ents[from]; } ASSERT(to == be32_to_cpu(btp->count)); xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); /* * Scan the bestfree if we need it and log the data block header. */ if (needscan) xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * Pitch the old leaf block. */ error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); lbp = NULL; if (error) { goto out; } /* * Now see if the resulting block can be shrunken to shortform. */ if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > XFS_IFORK_DSIZE(dp)) { error = 0; goto out; } return xfs_dir2_block_to_sf(args, dbp, size, &sfh); out: if (lbp) xfs_da_buf_done(lbp); if (dbp) xfs_da_buf_done(dbp); return error; } /* * Convert the shortform directory to block form. */ int /* error */ xfs_dir2_sf_to_block( xfs_da_args_t *args) /* operation arguments */ { xfs_dir2_db_t blkno; /* dir-relative block # (0) */ xfs_dir2_block_t *block; /* block structure */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ char *buf; /* sf buffer */ int buf_len; xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ int dummy; /* trash */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ int endoffset; /* end of data objects */ int error; /* error return value */ int i; /* index */ xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log block header */ int needscan; /* need to scan block freespc */ int newoffset; /* offset from current entry */ int offset; /* target block offset */ xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ xfs_dir2_sf_t *sfp; /* shortform structure */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ struct xfs_name name; trace_xfs_dir2_sf_to_block(args); dp = args->dp; tp = args->trans; mp = dp->i_mount; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); /* * Bomb out if the shortform directory is way too short. */ if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { ASSERT(XFS_FORCED_SHUTDOWN(mp)); return XFS_ERROR(EIO); } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); /* * Copy the directory into the stack buffer. * Then pitch the incore inode data so we can make extents. */ buf_len = dp->i_df.if_bytes; buf = kmem_alloc(buf_len, KM_SLEEP); memcpy(buf, sfp, buf_len); xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK); dp->i_d.di_size = 0; xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); /* * Reset pointer - old sfp is gone. */ sfp = (xfs_dir2_sf_t *)buf; /* * Add block 0 to the inode. */ error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); if (error) { kmem_free(buf); return error; } /* * Initialize the data block. */ error = xfs_dir2_data_init(args, blkno, &bp); if (error) { kmem_free(buf); return error; } block = bp->data; block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); /* * Compute size of block "tail" area. */ i = (uint)sizeof(*btp) + (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); /* * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. */ dup = (xfs_dir2_data_unused_t *)block->u; needlog = needscan = 0; xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, &needscan); ASSERT(needscan == 0); /* * Fill in the tail. */ btp = xfs_dir2_block_tail_p(mp, block); btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ btp->stale = 0; blp = xfs_dir2_block_leaf_p(btp); endoffset = (uint)((char *)blp - (char *)block); /* * Remove the freespace, we'll manage it. */ xfs_dir2_data_use_free(tp, bp, dup, (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), be16_to_cpu(dup->length), &needlog, &needscan); /* * Create entry for . */ dep = (xfs_dir2_data_entry_t *) ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); /* * Create entry for .. */ dep = (xfs_dir2_data_entry_t *) ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); offset = XFS_DIR2_DATA_FIRST_OFFSET; /* * Loop over existing entries, stuff them in. */ if ((i = 0) == sfp->hdr.count) sfep = NULL; else sfep = xfs_dir2_sf_firstentry(sfp); /* * Need to preserve the existing offset values in the sf directory. * Insert holes (unused entries) where necessary. */ while (offset < endoffset) { /* * sfep is null when we reach the end of the list. */ if (sfep == NULL) newoffset = endoffset; else newoffset = xfs_dir2_sf_get_offset(sfep); /* * There should be a hole here, make one. */ if (offset < newoffset) { dup = (xfs_dir2_data_unused_t *) ((char *)block + offset); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->length = cpu_to_be16(newoffset - offset); *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( ((char *)dup - (char *)block)); xfs_dir2_data_log_unused(tp, bp, dup); (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, dup, &dummy); offset += be16_to_cpu(dup->length); continue; } /* * Copy a real entry. */ dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep))); dep->namelen = sfep->namelen; memcpy(dep->name, sfep->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); *tagp = cpu_to_be16((char *)dep - (char *)block); xfs_dir2_data_log_entry(tp, bp, dep); name.name = sfep->name; name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> hashname(&name)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); offset = (int)((char *)(tagp + 1) - (char *)block); if (++i == sfp->hdr.count) sfep = NULL; else sfep = xfs_dir2_sf_nextentry(sfp, sfep); } /* Done with the temporary buffer */ kmem_free(buf); /* * Sort the leaf entries by hash value. */ xfs_sort(blp, be32_to_cpu(btp->count), sizeof(*blp), xfs_dir2_block_sort); /* * Log the leaf entry area and tail. * Already logged the header in data_init, ignore needlog. */ ASSERT(needscan == 0); xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); xfs_dir2_block_log_tail(tp, bp); xfs_dir2_data_check(dp, bp); xfs_da_buf_done(bp); return 0; } xfsprogs-3.1.9ubuntu2/libxfs/xfs_ialloc_btree.c0000664000000000000000000001673111650373061016565 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include STATIC int xfs_inobt_get_minrecs( struct xfs_btree_cur *cur, int level) { return cur->bc_mp->m_inobt_mnr[level != 0]; } STATIC struct xfs_btree_cur * xfs_inobt_dup_cursor( struct xfs_btree_cur *cur) { return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_private.a.agbp, cur->bc_private.a.agno); } STATIC void xfs_inobt_set_root( struct xfs_btree_cur *cur, union xfs_btree_ptr *nptr, int inc) /* level change */ { struct xfs_buf *agbp = cur->bc_private.a.agbp; struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); agi->agi_root = nptr->s; be32_add_cpu(&agi->agi_level, inc); xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); } STATIC int xfs_inobt_alloc_block( struct xfs_btree_cur *cur, union xfs_btree_ptr *start, union xfs_btree_ptr *new, int length, int *stat) { xfs_alloc_arg_t args; /* block allocation args */ int error; /* error return value */ xfs_agblock_t sbno = be32_to_cpu(start->s); XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); args.minlen = 1; args.maxlen = 1; args.prod = 1; args.type = XFS_ALLOCTYPE_NEAR_BNO; error = xfs_alloc_vextent(&args); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } if (args.fsbno == NULLFSBLOCK) { XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); *stat = 0; return 0; } ASSERT(args.len == 1); XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno)); *stat = 1; return 0; } STATIC int xfs_inobt_free_block( struct xfs_btree_cur *cur, struct xfs_buf *bp) { xfs_fsblock_t fsbno; int error; fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); error = xfs_free_extent(cur->bc_tp, fsbno, 1); if (error) return error; xfs_trans_binval(cur->bc_tp, bp); return error; } STATIC int xfs_inobt_get_maxrecs( struct xfs_btree_cur *cur, int level) { return cur->bc_mp->m_inobt_mxr[level != 0]; } STATIC void xfs_inobt_init_key_from_rec( union xfs_btree_key *key, union xfs_btree_rec *rec) { key->inobt.ir_startino = rec->inobt.ir_startino; } STATIC void xfs_inobt_init_rec_from_key( union xfs_btree_key *key, union xfs_btree_rec *rec) { rec->inobt.ir_startino = key->inobt.ir_startino; } STATIC void xfs_inobt_init_rec_from_cur( struct xfs_btree_cur *cur, union xfs_btree_rec *rec) { rec->inobt.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); rec->inobt.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); rec->inobt.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); } /* * initial value of ptr for lookup */ STATIC void xfs_inobt_init_ptr_from_cur( struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr) { struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); ptr->s = agi->agi_root; } STATIC __int64_t xfs_inobt_key_diff( struct xfs_btree_cur *cur, union xfs_btree_key *key) { return (__int64_t)be32_to_cpu(key->inobt.ir_startino) - cur->bc_rec.i.ir_startino; } #ifdef DEBUG STATIC int xfs_inobt_keys_inorder( struct xfs_btree_cur *cur, union xfs_btree_key *k1, union xfs_btree_key *k2) { return be32_to_cpu(k1->inobt.ir_startino) < be32_to_cpu(k2->inobt.ir_startino); } STATIC int xfs_inobt_recs_inorder( struct xfs_btree_cur *cur, union xfs_btree_rec *r1, union xfs_btree_rec *r2) { return be32_to_cpu(r1->inobt.ir_startino) + XFS_INODES_PER_CHUNK <= be32_to_cpu(r2->inobt.ir_startino); } #endif /* DEBUG */ #ifdef XFS_BTREE_TRACE ktrace_t *xfs_inobt_trace_buf; STATIC void xfs_inobt_trace_enter( struct xfs_btree_cur *cur, const char *func, char *s, int type, int line, __psunsigned_t a0, __psunsigned_t a1, __psunsigned_t a2, __psunsigned_t a3, __psunsigned_t a4, __psunsigned_t a5, __psunsigned_t a6, __psunsigned_t a7, __psunsigned_t a8, __psunsigned_t a9, __psunsigned_t a10) { ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type, (void *)func, (void *)s, NULL, (void *)cur, (void *)a0, (void *)a1, (void *)a2, (void *)a3, (void *)a4, (void *)a5, (void *)a6, (void *)a7, (void *)a8, (void *)a9, (void *)a10); } STATIC void xfs_inobt_trace_cursor( struct xfs_btree_cur *cur, __uint32_t *s0, __uint64_t *l0, __uint64_t *l1) { *s0 = cur->bc_private.a.agno; *l0 = cur->bc_rec.i.ir_startino; *l1 = cur->bc_rec.i.ir_free; } STATIC void xfs_inobt_trace_key( struct xfs_btree_cur *cur, union xfs_btree_key *key, __uint64_t *l0, __uint64_t *l1) { *l0 = be32_to_cpu(key->inobt.ir_startino); *l1 = 0; } STATIC void xfs_inobt_trace_record( struct xfs_btree_cur *cur, union xfs_btree_rec *rec, __uint64_t *l0, __uint64_t *l1, __uint64_t *l2) { *l0 = be32_to_cpu(rec->inobt.ir_startino); *l1 = be32_to_cpu(rec->inobt.ir_freecount); *l2 = be64_to_cpu(rec->inobt.ir_free); } #endif /* XFS_BTREE_TRACE */ static const struct xfs_btree_ops xfs_inobt_ops = { .rec_len = sizeof(xfs_inobt_rec_t), .key_len = sizeof(xfs_inobt_key_t), .dup_cursor = xfs_inobt_dup_cursor, .set_root = xfs_inobt_set_root, .alloc_block = xfs_inobt_alloc_block, .free_block = xfs_inobt_free_block, .get_minrecs = xfs_inobt_get_minrecs, .get_maxrecs = xfs_inobt_get_maxrecs, .init_key_from_rec = xfs_inobt_init_key_from_rec, .init_rec_from_key = xfs_inobt_init_rec_from_key, .init_rec_from_cur = xfs_inobt_init_rec_from_cur, .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder, #endif #ifdef XFS_BTREE_TRACE .trace_enter = xfs_inobt_trace_enter, .trace_cursor = xfs_inobt_trace_cursor, .trace_key = xfs_inobt_trace_key, .trace_record = xfs_inobt_trace_record, #endif }; /* * Allocate a new inode btree cursor. */ struct xfs_btree_cur * /* new inode btree cursor */ xfs_inobt_init_cursor( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *agbp, /* buffer for agi structure */ xfs_agnumber_t agno) /* allocation group number */ { struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); struct xfs_btree_cur *cur; cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_nlevels = be32_to_cpu(agi->agi_level); cur->bc_btnum = XFS_BTNUM_INO; cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_ops = &xfs_inobt_ops; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; return cur; } /* * Calculate number of records in an inobt btree block. */ int xfs_inobt_maxrecs( struct xfs_mount *mp, int blocklen, int leaf) { blocklen -= XFS_INOBT_BLOCK_LEN(mp); if (leaf) return blocklen / sizeof(xfs_inobt_rec_t); return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t)); } xfsprogs-3.1.9ubuntu2/libxfs/kmem.c0000664000000000000000000000272511140033220014170 0ustar #include /* * Simple memory interface */ kmem_zone_t * kmem_zone_init(int size, char *name) { kmem_zone_t *ptr = malloc(sizeof(kmem_zone_t)); if (ptr == NULL) { fprintf(stderr, _("%s: zone init failed (%s, %d bytes): %s\n"), progname, name, (int)sizeof(kmem_zone_t), strerror(errno)); exit(1); } ptr->zone_unitsize = size; ptr->zone_name = name; ptr->allocated = 0; return ptr; } void * kmem_zone_alloc(kmem_zone_t *zone, int flags) { void *ptr = malloc(zone->zone_unitsize); if (ptr == NULL) { fprintf(stderr, _("%s: zone alloc failed (%s, %d bytes): %s\n"), progname, zone->zone_name, zone->zone_unitsize, strerror(errno)); exit(1); } zone->allocated++; return ptr; } void * kmem_zone_zalloc(kmem_zone_t *zone, int flags) { void *ptr = kmem_zone_alloc(zone, flags); memset(ptr, 0, zone->zone_unitsize); return ptr; } void * kmem_alloc(size_t size, int flags) { void *ptr = malloc(size); if (ptr == NULL) { fprintf(stderr, _("%s: malloc failed (%d bytes): %s\n"), progname, (int)size, strerror(errno)); exit(1); } return ptr; } void * kmem_zalloc(size_t size, int flags) { void *ptr = kmem_alloc(size, flags); memset(ptr, 0, size); return ptr; } void * kmem_realloc(void *ptr, size_t new_size, size_t old_size, int flags) { ptr = realloc(ptr, new_size); if (ptr == NULL) { fprintf(stderr, _("%s: realloc failed (%d bytes): %s\n"), progname, (int)new_size, strerror(errno)); exit(1); } return ptr; } xfsprogs-3.1.9ubuntu2/libxfs/init.c0000664000000000000000000005240411650373061014221 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "init.h" char *progname = "libxfs"; /* default, changed by each tool */ struct cache *libxfs_icache; /* global inode cache */ int libxfs_ihash_size; /* #buckets in icache */ struct cache *libxfs_bcache; /* global buffer cache */ int libxfs_bhash_size; /* #buckets in bcache */ int use_xfs_buf_lock; /* global flag: use xfs_buf_t locks for MT */ static void manage_zones(int); /* setup global zones */ /* * dev_map - map open devices to fd. */ #define MAX_DEVS 10 /* arbitary maximum */ int nextfakedev = -1; /* device number to give to next fake device */ static struct dev_to_fd { dev_t dev; int fd; } dev_map[MAX_DEVS]={{0}}; /* * Checks whether a given device has a mounted, writable * filesystem, returns 1 if it does & fatal (just warns * if not fatal, but allows us to proceed). * * Useful to tools which will produce uncertain results * if the filesystem is active - repair, check, logprint. */ static int check_isactive(char *name, char *block, int fatal) { struct stat64 st; if (stat64(block, &st) < 0) return 0; if ((st.st_mode & S_IFMT) != S_IFBLK) return 0; if (platform_check_ismounted(name, block, &st, 0) == 0) return 0; return platform_check_iswritable(name, block, &st, fatal); } /* libxfs_device_to_fd: * lookup a device number in the device map * return the associated fd */ int libxfs_device_to_fd(dev_t device) { int d; for (d = 0; d < MAX_DEVS; d++) if (dev_map[d].dev == device) return dev_map[d].fd; fprintf(stderr, _("%s: %s: device %lld is not open\n"), progname, __FUNCTION__, (long long)device); exit(1); /* NOTREACHED */ } /* libxfs_device_open: * open a device and return its device number */ dev_t libxfs_device_open(char *path, int creat, int xflags, int setblksize) { dev_t dev; int fd, d, flags; int readonly, dio, excl; struct stat64 statb; readonly = (xflags & LIBXFS_ISREADONLY); excl = (xflags & LIBXFS_EXCLUSIVELY) && !creat; dio = (xflags & LIBXFS_DIRECT) && !creat && platform_direct_blockdev(); retry: flags = (readonly ? O_RDONLY : O_RDWR) | \ (creat ? (O_CREAT|O_TRUNC) : 0) | \ (dio ? O_DIRECT : 0) | \ (excl ? O_EXCL : 0); if ((fd = open(path, flags, 0666)) < 0) { if (errno == EINVAL && --dio == 0) goto retry; fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); exit(1); } if (fstat64(fd, &statb) < 0) { fprintf(stderr, _("%s: cannot stat %s: %s\n"), progname, path, strerror(errno)); exit(1); } if (!readonly && setblksize && (statb.st_mode & S_IFMT) == S_IFBLK) { if (setblksize == 1) /* use the default blocksize */ (void)platform_set_blocksize(fd, path, statb.st_rdev, XFS_MIN_SECTORSIZE, 0); else { /* given an explicit blocksize to use */ if (platform_set_blocksize(fd, path, statb.st_rdev, setblksize, 1)) exit(1); } } /* * Get the device number from the stat buf - unless * we're not opening a real device, in which case * choose a new fake device number. */ dev = (statb.st_rdev) ? (statb.st_rdev) : (nextfakedev--); for (d = 0; d < MAX_DEVS; d++) if (dev_map[d].dev == dev) { fprintf(stderr, _("%s: device %lld is already open\n"), progname, (long long)dev); exit(1); } for (d = 0; d < MAX_DEVS; d++) if (!dev_map[d].dev) { dev_map[d].dev = dev; dev_map[d].fd = fd; return dev; } fprintf(stderr, _("%s: %s: too many open devices\n"), progname, __FUNCTION__); exit(1); /* NOTREACHED */ } void libxfs_device_close(dev_t dev) { int d; for (d = 0; d < MAX_DEVS; d++) if (dev_map[d].dev == dev) { int fd; fd = dev_map[d].fd; dev_map[d].dev = dev_map[d].fd = 0; fsync(fd); platform_flush_device(fd, dev); close(fd); return; } fprintf(stderr, _("%s: %s: device %lld is not open\n"), progname, __FUNCTION__, (long long)dev); exit(1); } static int check_open(char *path, int flags, char **rawfile, char **blockfile) { int readonly = (flags & LIBXFS_ISREADONLY); int inactive = (flags & LIBXFS_ISINACTIVE); int dangerously = (flags & LIBXFS_DANGEROUSLY); struct stat64 stbuf; if (stat64(path, &stbuf) < 0) { perror(path); return 0; } if (!(*rawfile = platform_findrawpath(path))) { fprintf(stderr, _("%s: " "can't find a character device matching %s\n"), progname, path); return 0; } if (!(*blockfile = platform_findblockpath(path))) { fprintf(stderr, _("%s: " "can't find a block device matching %s\n"), progname, path); return 0; } if (!readonly && !inactive && platform_check_ismounted(path, *blockfile, NULL, 1)) return 0; if (inactive && check_isactive(path, *blockfile, ((readonly|dangerously)?1:0))) return 0; return 1; } /* * libxfs initialization. * Caller gets a 0 on failure (and we print a message), 1 on success. */ int libxfs_init(libxfs_init_t *a) { char *blockfile; char curdir[MAXPATHLEN]; char *dname; char dpath[25]; int fd; char *logname; char logpath[25]; int needcd; char *rawfile; char *rtname; char rtpath[25]; int rval = 0; int flags; dpath[0] = logpath[0] = rtpath[0] = '\0'; dname = a->dname; logname = a->logname; rtname = a->rtname; a->dfd = a->logfd = a->rtfd = -1; a->ddev = a->logdev = a->rtdev = 0; a->dbsize = a->lbsize = a->rtbsize = 0; a->dsize = a->logBBsize = a->logBBstart = a->rtsize = 0; (void)getcwd(curdir,MAXPATHLEN); needcd = 0; fd = -1; flags = (a->isreadonly | a->isdirect); radix_tree_init(); if (a->volname) { if(!check_open(a->volname,flags,&rawfile,&blockfile)) goto done; needcd = 1; fd = open(rawfile, O_RDONLY); dname = a->dname = a->volname; a->volname = NULL; } if (dname) { if (dname[0] != '/' && needcd) chdir(curdir); if (a->disfile) { a->ddev= libxfs_device_open(dname, a->dcreat, flags, a->setblksize); a->dfd = libxfs_device_to_fd(a->ddev); } else { if (!check_open(dname, flags, &rawfile, &blockfile)) goto done; a->ddev = libxfs_device_open(rawfile, a->dcreat, flags, a->setblksize); a->dfd = libxfs_device_to_fd(a->ddev); platform_findsizes(rawfile, a->dfd, &a->dsize, &a->dbsize); } needcd = 1; } else a->dsize = 0; if (logname) { if (logname[0] != '/' && needcd) chdir(curdir); if (a->lisfile) { a->logdev = libxfs_device_open(logname, a->lcreat, flags, a->setblksize); a->logfd = libxfs_device_to_fd(a->logdev); } else { if (!check_open(logname, flags, &rawfile, &blockfile)) goto done; a->logdev = libxfs_device_open(rawfile, a->lcreat, flags, a->setblksize); a->logfd = libxfs_device_to_fd(a->logdev); platform_findsizes(rawfile, a->logfd, &a->logBBsize, &a->lbsize); } needcd = 1; } else a->logBBsize = 0; if (rtname) { if (rtname[0] != '/' && needcd) chdir(curdir); if (a->risfile) { a->rtdev = libxfs_device_open(rtname, a->rcreat, flags, a->setblksize); a->rtfd = libxfs_device_to_fd(a->rtdev); } else { if (!check_open(rtname, flags, &rawfile, &blockfile)) goto done; a->rtdev = libxfs_device_open(rawfile, a->rcreat, flags, a->setblksize); a->rtfd = libxfs_device_to_fd(a->rtdev); platform_findsizes(rawfile, a->rtfd, &a->rtsize, &a->rtbsize); } needcd = 1; } else a->rtsize = 0; if (a->dsize < 0) { fprintf(stderr, _("%s: can't get size for data subvolume\n"), progname); goto done; } if (a->logBBsize < 0) { fprintf(stderr, _("%s: can't get size for log subvolume\n"), progname); goto done; } if (a->rtsize < 0) { fprintf(stderr, _("%s: can't get size for realtime subvolume\n"), progname); goto done; } if (needcd) chdir(curdir); if (!libxfs_ihash_size) libxfs_ihash_size = LIBXFS_IHASHSIZE(sbp); libxfs_icache = cache_init(libxfs_ihash_size, &libxfs_icache_operations); if (!libxfs_bhash_size) libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp); libxfs_bcache = cache_init(libxfs_bhash_size, &libxfs_bcache_operations); use_xfs_buf_lock = a->usebuflock; manage_zones(0); rval = 1; done: if (dpath[0]) unlink(dpath); if (logpath[0]) unlink(logpath); if (rtpath[0]) unlink(rtpath); if (fd >= 0) close(fd); if (!rval && a->ddev) libxfs_device_close(a->ddev); if (!rval && a->logdev) libxfs_device_close(a->logdev); if (!rval && a->rtdev) libxfs_device_close(a->rtdev); return rval; } /* * Initialize/destroy all of the zone allocators we use. */ static void manage_zones(int release) { extern kmem_zone_t *xfs_buf_zone; extern kmem_zone_t *xfs_ili_zone; extern kmem_zone_t *xfs_inode_zone; extern kmem_zone_t *xfs_ifork_zone; extern kmem_zone_t *xfs_dabuf_zone; extern kmem_zone_t *xfs_buf_item_zone; extern kmem_zone_t *xfs_da_state_zone; extern kmem_zone_t *xfs_btree_cur_zone; extern kmem_zone_t *xfs_bmap_free_item_zone; extern kmem_zone_t *xfs_log_item_desc_zone; extern void xfs_dir_startup(); if (release) { /* free zone allocation */ kmem_free(xfs_buf_zone); kmem_free(xfs_inode_zone); kmem_free(xfs_ifork_zone); kmem_free(xfs_dabuf_zone); kmem_free(xfs_buf_item_zone); kmem_free(xfs_da_state_zone); kmem_free(xfs_btree_cur_zone); kmem_free(xfs_bmap_free_item_zone); kmem_free(xfs_log_item_desc_zone); return; } /* otherwise initialise zone allocation */ xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buffer"); xfs_inode_zone = kmem_zone_init(sizeof(xfs_inode_t), "xfs_inode"); xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); xfs_ili_zone = kmem_zone_init( sizeof(xfs_inode_log_item_t), "xfs_inode_log_item"); xfs_buf_item_zone = kmem_zone_init( sizeof(xfs_buf_log_item_t), "xfs_buf_log_item"); xfs_da_state_zone = kmem_zone_init( sizeof(xfs_da_state_t), "xfs_da_state"); xfs_btree_cur_zone = kmem_zone_init( sizeof(xfs_btree_cur_t), "xfs_btree_cur"); xfs_bmap_free_item_zone = kmem_zone_init( sizeof(xfs_bmap_free_item_t), "xfs_bmap_free_item"); xfs_log_item_desc_zone = kmem_zone_init( sizeof(struct xfs_log_item_desc), "xfs_log_item_desc"); xfs_dir_startup(); } /* * Get the bitmap and summary inodes into the mount structure * at mount time. */ static int rtmount_inodes(xfs_mount_t *mp) { int error; xfs_sb_t *sbp; sbp = &mp->m_sb; if (sbp->sb_rbmino == NULLFSINO) return 0; error = libxfs_iget(mp, NULL, sbp->sb_rbmino, 0, &mp->m_rbmip, 0); if (error) { fprintf(stderr, _("%s: cannot read realtime bitmap inode (%d)\n"), progname, error); return error; } ASSERT(mp->m_rbmip != NULL); ASSERT(sbp->sb_rsumino != NULLFSINO); error = libxfs_iget(mp, NULL, sbp->sb_rsumino, 0, &mp->m_rsumip, 0); if (error) { libxfs_iput(mp->m_rbmip, 0); fprintf(stderr, _("%s: cannot read realtime summary inode (%d)\n"), progname, error); return error; } ASSERT(mp->m_rsumip != NULL); return 0; } /* * Initialize realtime fields in the mount structure. */ static int rtmount_init( xfs_mount_t *mp, /* file system mount structure */ int flags) { xfs_buf_t *bp; /* buffer for last block of subvolume */ xfs_daddr_t d; /* address of last block of subvolume */ xfs_sb_t *sbp; /* filesystem superblock copy in mount */ sbp = &mp->m_sb; if (sbp->sb_rblocks == 0) return 0; if (mp->m_rtdev == 0 && !(flags & LIBXFS_MOUNT_DEBUGGER)) { fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"), progname); return -1; } mp->m_rsumlevels = sbp->sb_rextslog + 1; mp->m_rsumsize = (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels * sbp->sb_rbmblocks; mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize); mp->m_rbmip = mp->m_rsumip = NULL; /* * Allow debugger to be run without the realtime device present. */ if (flags & LIBXFS_MOUNT_DEBUGGER) return 0; /* * Check that the realtime section is an ok size. */ d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) { fprintf(stderr, _("%s: realtime init - %llu != %llu\n"), progname, (unsigned long long) XFS_BB_TO_FSB(mp, d), (unsigned long long) mp->m_sb.sb_rblocks); return -1; } bp = libxfs_readbuf(mp->m_rtdev, d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), 0); if (bp == NULL) { fprintf(stderr, _("%s: realtime size check failed\n"), progname); return -1; } libxfs_putbuf(bp); return 0; } /* * Core dir v1 mount code for allowing reading of these dirs. */ static void libxfs_dirv1_mount( xfs_mount_t *mp) { mp->m_dir_node_ents = mp->m_attr_node_ents = (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; mp->m_dirblksize = mp->m_sb.sb_blocksize; mp->m_dirblkfsbs = 1; } static int libxfs_initialize_perag( xfs_mount_t *mp, xfs_agnumber_t agcount, xfs_agnumber_t *maxagi) { xfs_agnumber_t index, max_metadata; xfs_agnumber_t first_initialised = 0; xfs_perag_t *pag; xfs_agino_t agino; xfs_ino_t ino; xfs_sb_t *sbp = &mp->m_sb; int error = -ENOMEM; /* * Walk the current per-ag tree so we don't try to initialise AGs * that already exist (growfs case). Allocate and insert all the * AGs we don't find ready for initialisation. */ for (index = 0; index < agcount; index++) { pag = xfs_perag_get(mp, index); if (pag) { xfs_perag_put(pag); continue; } if (!first_initialised) first_initialised = index; pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); if (!pag) goto out_unwind; pag->pag_agno = index; pag->pag_mount = mp; if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { error = -EEXIST; goto out_unwind; } } /* * If we mount with the inode64 option, or no inode overflows * the legacy 32-bit address space clear the inode32 option. */ agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32) mp->m_flags |= XFS_MOUNT_32BITINODES; else mp->m_flags &= ~XFS_MOUNT_32BITINODES; if (mp->m_flags & XFS_MOUNT_32BITINODES) { /* * Calculate how much should be reserved for inodes to meet * the max inode percentage. */ if (mp->m_maxicount) { __uint64_t icount; icount = sbp->sb_dblocks * sbp->sb_imax_pct; do_div(icount, 100); icount += sbp->sb_agblocks - 1; do_div(icount, sbp->sb_agblocks); max_metadata = icount; } else { max_metadata = agcount; } for (index = 0; index < agcount; index++) { ino = XFS_AGINO_TO_INO(mp, index, agino); if (ino > XFS_MAXINUMBER_32) { index++; break; } pag = xfs_perag_get(mp, index); pag->pagi_inodeok = 1; if (index < max_metadata) pag->pagf_metadata = 1; xfs_perag_put(pag); } } else { for (index = 0; index < agcount; index++) { pag = xfs_perag_get(mp, index); pag->pagi_inodeok = 1; xfs_perag_put(pag); } } if (maxagi) *maxagi = index; return 0; out_unwind: kmem_free(pag); for (; index > first_initialised; index--) { pag = radix_tree_delete(&mp->m_perag_tree, index); kmem_free(pag); } return error; } /* * Mount structure initialization, provides a filled-in xfs_mount_t * such that the numerous XFS_* macros can be used. If dev is zero, * no IO will be performed (no size checks, read root inodes). */ xfs_mount_t * libxfs_mount( xfs_mount_t *mp, xfs_sb_t *sb, dev_t dev, dev_t logdev, dev_t rtdev, int flags) { xfs_daddr_t d; xfs_buf_t *bp; xfs_sb_t *sbp; int error; mp->m_dev = dev; mp->m_rtdev = rtdev; mp->m_logdev = logdev; mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT); mp->m_sb = *sb; INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL); sbp = &(mp->m_sb); xfs_mount_common(mp, sb); xfs_alloc_compute_maxlevels(mp); xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); xfs_ialloc_compute_maxlevels(mp); if (sbp->sb_imax_pct) { /* Make sure the maximum inode count is a multiple of the * units we allocate inodes in. */ mp->m_maxicount = (sbp->sb_dblocks * sbp->sb_imax_pct) / 100; mp->m_maxicount = ((mp->m_maxicount / mp->m_ialloc_blks) * mp->m_ialloc_blks) << sbp->sb_inopblog; } else mp->m_maxicount = 0; mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; /* * Set whether we're using stripe alignment. */ if (xfs_sb_version_hasdalign(&mp->m_sb)) { mp->m_dalign = sbp->sb_unit; mp->m_swidth = sbp->sb_width; } /* * Set whether we're using inode alignment. */ if (xfs_sb_version_hasalign(&mp->m_sb) && mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1; else mp->m_inoalign_mask = 0; /* * If we are using stripe alignment, check whether * the stripe unit is a multiple of the inode alignment */ if (mp->m_dalign && mp->m_inoalign_mask && !(mp->m_dalign & mp->m_inoalign_mask)) mp->m_sinoalign = mp->m_dalign; else mp->m_sinoalign = 0; /* * Check that the data (and log if separate) are an ok size. */ d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { fprintf(stderr, _("%s: size check failed\n"), progname); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) return NULL; } /* Initialize the appropriate directory manager */ if (xfs_sb_version_hasdirv2(sbp)) xfs_dir_mount(mp); else { fprintf(stderr, _("%s: WARNING - filesystem uses v1 dirs," "limited functionality provided.\n"), progname); libxfs_dirv1_mount(mp); } /* Initialize cached values for the attribute manager */ mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100; if (xfs_sb_version_hasattr2(&mp->m_sb)) mp->m_flags |= LIBXFS_MOUNT_ATTR2; /* Initialize the precomputed transaction reservations values */ xfs_trans_init(mp); if (dev == 0) /* maxtrres, we have no device so leave now */ return mp; bp = libxfs_readbuf(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1), !(flags & LIBXFS_MOUNT_DEBUGGER)); if (!bp) { fprintf(stderr, _("%s: data size check failed\n"), progname); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) return NULL; } else libxfs_putbuf(bp); if (mp->m_logdev && mp->m_logdev != mp->m_dev) { d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) || (!(bp = libxfs_readbuf(mp->m_logdev, d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1), !(flags & LIBXFS_MOUNT_DEBUGGER)))) ) { fprintf(stderr, _("%s: log size checks failed\n"), progname); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) return NULL; } if (bp) libxfs_putbuf(bp); } /* Initialize realtime fields in the mount structure */ if (rtmount_init(mp, flags)) { fprintf(stderr, _("%s: realtime device init failed\n"), progname); return NULL; } error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); if (error) { fprintf(stderr, _("%s: perag init failed\n"), progname); exit(1); } /* * mkfs calls mount before the root inode is allocated. */ if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO) { error = libxfs_iget(mp, NULL, sbp->sb_rootino, 0, &mp->m_rootip, 0); if (error) { fprintf(stderr, _("%s: cannot read root inode (%d)\n"), progname, error); if (!(flags & LIBXFS_MOUNT_DEBUGGER)) return NULL; } ASSERT(mp->m_rootip != NULL); } if ((flags & LIBXFS_MOUNT_ROOTINOS) && rtmount_inodes(mp)) { if (mp->m_rootip) libxfs_iput(mp->m_rootip, 0); return NULL; } /* * mkfs calls mount before the AGF/AGI structures are written. */ if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO && xfs_sb_version_haslazysbcount(&mp->m_sb)) { error = xfs_initialize_perag_data(mp, sbp->sb_agcount); if (error) { fprintf(stderr, _("%s: cannot init perag data (%d)\n"), progname, error); return NULL; } } return mp; } void libxfs_rtmount_destroy(xfs_mount_t *mp) { if (mp->m_rsumip) libxfs_iput(mp->m_rsumip, 0); if (mp->m_rbmip) libxfs_iput(mp->m_rbmip, 0); mp->m_rsumip = mp->m_rbmip = NULL; } /* * Release any resource obtained during a mount. */ void libxfs_umount(xfs_mount_t *mp) { struct xfs_perag *pag; int agno; libxfs_rtmount_destroy(mp); libxfs_icache_purge(); libxfs_bcache_purge(); for (agno = 0; agno < mp->m_maxagi; agno++) { pag = radix_tree_delete(&mp->m_perag_tree, agno); kmem_free(pag); } } /* * Release any global resources used by libxfs. */ void libxfs_destroy(void) { manage_zones(1); cache_destroy(libxfs_icache); cache_destroy(libxfs_bcache); } int libxfs_device_alignment(void) { return platform_align_blockdev(); } void libxfs_report(FILE *fp) { time_t t; char *c; cache_report(fp, "libxfs_icache", libxfs_icache); cache_report(fp, "libxfs_bcache", libxfs_bcache); t = time(NULL); c = asctime(localtime(&t)); fprintf(fp, "%s", c); } int libxfs_nproc(void) { return platform_nproc(); } unsigned long libxfs_physmem(void) { return platform_physmem(); } xfsprogs-3.1.9ubuntu2/libxfs/radix-tree.c0000664000000000000000000004621211650373061015322 0ustar /* * Copyright (C) 2001 Momchil Velikov * Portions Copyright (C) 2001 Christoph Hellwig * Copyright (C) 2005 SGI, Christoph Lameter * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "radix-tree.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif #define RADIX_TREE_MAP_SHIFT 6 #define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT) #define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1) #ifdef RADIX_TREE_TAGS #define RADIX_TREE_TAG_LONGS \ ((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG) #endif struct radix_tree_node { unsigned int count; void *slots[RADIX_TREE_MAP_SIZE]; #ifdef RADIX_TREE_TAGS unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; #endif }; struct radix_tree_path { struct radix_tree_node *node; int offset; }; #define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) #define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2) static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH]; /* * Radix tree node cache. */ #define radix_tree_node_alloc(r) ((struct radix_tree_node *) \ calloc(1, sizeof(struct radix_tree_node))) #define radix_tree_node_free(n) free(n) #ifdef RADIX_TREE_TAGS static inline void tag_set(struct radix_tree_node *node, unsigned int tag, int offset) { *((__uint32_t *)node->tags[tag] + (offset >> 5)) |= (1 << (offset & 31)); } static inline void tag_clear(struct radix_tree_node *node, unsigned int tag, int offset) { __uint32_t *p = (__uint32_t*)node->tags[tag] + (offset >> 5); __uint32_t m = 1 << (offset & 31); *p &= ~m; } static inline int tag_get(struct radix_tree_node *node, unsigned int tag, int offset) { return 1 & (((const __uint32_t *)node->tags[tag])[offset >> 5] >> (offset & 31)); } /* * Returns 1 if any slot in the node has this tag set. * Otherwise returns 0. */ static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag) { int idx; for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { if (node->tags[tag][idx]) return 1; } return 0; } #endif /* * Return the maximum key which can be store into a * radix tree with height HEIGHT. */ static inline unsigned long radix_tree_maxindex(unsigned int height) { return height_to_maxindex[height]; } /* * Extend a radix tree so it can store key @index. */ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) { struct radix_tree_node *node; unsigned int height; #ifdef RADIX_TREE_TAGS char tags[RADIX_TREE_MAX_TAGS]; int tag; #endif /* Figure out what the height should be. */ height = root->height + 1; while (index > radix_tree_maxindex(height)) height++; if (root->rnode == NULL) { root->height = height; goto out; } #ifdef RADIX_TREE_TAGS /* * Prepare the tag status of the top-level node for propagation * into the newly-pushed top-level node(s) */ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { tags[tag] = 0; if (any_tag_set(root->rnode, tag)) tags[tag] = 1; } #endif do { if (!(node = radix_tree_node_alloc(root))) return -ENOMEM; /* Increase the height. */ node->slots[0] = root->rnode; #ifdef RADIX_TREE_TAGS /* Propagate the aggregated tag info into the new root */ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { if (tags[tag]) tag_set(node, tag, 0); } #endif node->count = 1; root->rnode = node; root->height++; } while (height > root->height); out: return 0; } /** * radix_tree_insert - insert into a radix tree * @root: radix tree root * @index: index key * @item: item to insert * * Insert an item into the radix tree at position @index. */ int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) { struct radix_tree_node *node = NULL, *slot; unsigned int height, shift; int offset; int error; /* Make sure the tree is high enough. */ if ((!index && !root->rnode) || index > radix_tree_maxindex(root->height)) { error = radix_tree_extend(root, index); if (error) return error; } slot = root->rnode; height = root->height; shift = (height-1) * RADIX_TREE_MAP_SHIFT; offset = 0; /* uninitialised var warning */ do { if (slot == NULL) { /* Have to add a child node. */ if (!(slot = radix_tree_node_alloc(root))) return -ENOMEM; if (node) { node->slots[offset] = slot; node->count++; } else root->rnode = slot; } /* Go a level down */ offset = (index >> shift) & RADIX_TREE_MAP_MASK; node = slot; slot = node->slots[offset]; shift -= RADIX_TREE_MAP_SHIFT; height--; } while (height > 0); if (slot != NULL) return -EEXIST; ASSERT(node); node->count++; node->slots[offset] = item; #ifdef RADIX_TREE_TAGS ASSERT(!tag_get(node, 0, offset)); ASSERT(!tag_get(node, 1, offset)); #endif return 0; } static inline void **__lookup_slot(struct radix_tree_root *root, unsigned long index) { unsigned int height, shift; struct radix_tree_node **slot; height = root->height; if (index > radix_tree_maxindex(height)) return NULL; shift = (height-1) * RADIX_TREE_MAP_SHIFT; slot = &root->rnode; while (height > 0) { if (*slot == NULL) return NULL; slot = (struct radix_tree_node **) ((*slot)->slots + ((index >> shift) & RADIX_TREE_MAP_MASK)); shift -= RADIX_TREE_MAP_SHIFT; height--; } return (void **)slot; } /** * radix_tree_lookup_slot - lookup a slot in a radix tree * @root: radix tree root * @index: index key * * Lookup the slot corresponding to the position @index in the radix tree * @root. This is useful for update-if-exists operations. */ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) { return __lookup_slot(root, index); } /** * radix_tree_lookup - perform lookup operation on a radix tree * @root: radix tree root * @index: index key * * Lookup the item at the position @index in the radix tree @root. */ void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index) { void **slot; slot = __lookup_slot(root, index); return slot != NULL ? *slot : NULL; } /** * raid_tree_first_key - find the first index key in the radix tree * @root: radix tree root * @index: where the first index will be placed * * Returns the first entry and index key in the radix tree @root. */ void *radix_tree_lookup_first(struct radix_tree_root *root, unsigned long *index) { unsigned int height, shift; struct radix_tree_node *slot; unsigned long i; height = root->height; *index = 0; if (height == 0) return NULL; shift = (height-1) * RADIX_TREE_MAP_SHIFT; slot = root->rnode; for (; height > 1; height--) { for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { if (slot->slots[i] != NULL) break; } ASSERT(i < RADIX_TREE_MAP_SIZE); *index |= (i << shift); shift -= RADIX_TREE_MAP_SHIFT; slot = slot->slots[i]; } for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { if (slot->slots[i] != NULL) { *index |= i; return slot->slots[i]; } } return NULL; } #ifdef RADIX_TREE_TAGS /** * radix_tree_tag_set - set a tag on a radix tree node * @root: radix tree root * @index: index key * @tag: tag index * * Set the search tag (which must be < RADIX_TREE_MAX_TAGS) * corresponding to @index in the radix tree. From * the root all the way down to the leaf node. * * Returns the address of the tagged item. Setting a tag on a not-present * item is a bug. */ void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, unsigned int tag) { unsigned int height, shift; struct radix_tree_node *slot; height = root->height; if (index > radix_tree_maxindex(height)) return NULL; shift = (height - 1) * RADIX_TREE_MAP_SHIFT; slot = root->rnode; while (height > 0) { int offset; offset = (index >> shift) & RADIX_TREE_MAP_MASK; if (!tag_get(slot, tag, offset)) tag_set(slot, tag, offset); slot = slot->slots[offset]; ASSERT(slot != NULL); shift -= RADIX_TREE_MAP_SHIFT; height--; } return slot; } /** * radix_tree_tag_clear - clear a tag on a radix tree node * @root: radix tree root * @index: index key * @tag: tag index * * Clear the search tag (which must be < RADIX_TREE_MAX_TAGS) * corresponding to @index in the radix tree. If * this causes the leaf node to have no tags set then clear the tag in the * next-to-leaf node, etc. * * Returns the address of the tagged item on success, else NULL. ie: * has the same return value and semantics as radix_tree_lookup(). */ void *radix_tree_tag_clear(struct radix_tree_root *root, unsigned long index, unsigned int tag) { struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; struct radix_tree_node *slot; unsigned int height, shift; void *ret = NULL; height = root->height; if (index > radix_tree_maxindex(height)) goto out; shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; slot = root->rnode; while (height > 0) { int offset; if (slot == NULL) goto out; offset = (index >> shift) & RADIX_TREE_MAP_MASK; pathp[1].offset = offset; pathp[1].node = slot; slot = slot->slots[offset]; pathp++; shift -= RADIX_TREE_MAP_SHIFT; height--; } ret = slot; if (ret == NULL) goto out; do { if (!tag_get(pathp->node, tag, pathp->offset)) goto out; tag_clear(pathp->node, tag, pathp->offset); if (any_tag_set(pathp->node, tag)) goto out; pathp--; } while (pathp->node); out: return ret; } #endif static unsigned int __lookup(struct radix_tree_root *root, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index) { unsigned int nr_found = 0; unsigned int shift, height; struct radix_tree_node *slot; unsigned long i; height = root->height; if (height == 0) goto out; shift = (height-1) * RADIX_TREE_MAP_SHIFT; slot = root->rnode; for ( ; height > 1; height--) { for (i = (index >> shift) & RADIX_TREE_MAP_MASK ; i < RADIX_TREE_MAP_SIZE; i++) { if (slot->slots[i] != NULL) break; index &= ~((1UL << shift) - 1); index += 1UL << shift; if (index == 0) goto out; /* 32-bit wraparound */ } if (i == RADIX_TREE_MAP_SIZE) goto out; shift -= RADIX_TREE_MAP_SHIFT; slot = slot->slots[i]; } /* Bottom level: grab some items */ for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { index++; if (slot->slots[i]) { results[nr_found++] = slot->slots[i]; if (nr_found == max_items) goto out; } } out: *next_index = index; return nr_found; } /** * radix_tree_gang_lookup - perform multiple lookup on a radix tree * @root: radix tree root * @results: where the results of the lookup are placed * @first_index: start the lookup from this key * @max_items: place up to this many items at *results * * Performs an index-ascending scan of the tree for present items. Places * them at *@results and returns the number of items which were placed at * *@results. * * The implementation is naive. */ unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items) { const unsigned long max_index = radix_tree_maxindex(root->height); unsigned long cur_index = first_index; unsigned int ret = 0; while (ret < max_items) { unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; nr_found = __lookup(root, results + ret, cur_index, max_items - ret, &next_index); ret += nr_found; if (next_index == 0) break; cur_index = next_index; } return ret; } /** * radix_tree_gang_lookup_ex - perform multiple lookup on a radix tree * @root: radix tree root * @results: where the results of the lookup are placed * @first_index: start the lookup from this key * @last_index: don't lookup past this key * @max_items: place up to this many items at *results * * Performs an index-ascending scan of the tree for present items starting * @first_index until @last_index up to as many as @max_items. Places * them at *@results and returns the number of items which were placed * at *@results. * * The implementation is naive. */ unsigned int radix_tree_gang_lookup_ex(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned long last_index, unsigned int max_items) { const unsigned long max_index = radix_tree_maxindex(root->height); unsigned long cur_index = first_index; unsigned int ret = 0; while (ret < max_items && cur_index < last_index) { unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; nr_found = __lookup(root, results + ret, cur_index, max_items - ret, &next_index); ret += nr_found; if (next_index == 0) break; cur_index = next_index; } return ret; } #ifdef RADIX_TREE_TAGS static unsigned int __lookup_tag(struct radix_tree_root *root, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index, unsigned int tag) { unsigned int nr_found = 0; unsigned int shift; unsigned int height = root->height; struct radix_tree_node *slot; shift = (height - 1) * RADIX_TREE_MAP_SHIFT; slot = root->rnode; while (height > 0) { unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK; for ( ; i < RADIX_TREE_MAP_SIZE; i++) { if (tag_get(slot, tag, i)) { ASSERT(slot->slots[i] != NULL); break; } index &= ~((1UL << shift) - 1); index += 1UL << shift; if (index == 0) goto out; /* 32-bit wraparound */ } if (i == RADIX_TREE_MAP_SIZE) goto out; height--; if (height == 0) { /* Bottom level: grab some items */ unsigned long j = index & RADIX_TREE_MAP_MASK; for ( ; j < RADIX_TREE_MAP_SIZE; j++) { index++; if (tag_get(slot, tag, j)) { ASSERT(slot->slots[j] != NULL); results[nr_found++] = slot->slots[j]; if (nr_found == max_items) goto out; } } } shift -= RADIX_TREE_MAP_SHIFT; slot = slot->slots[i]; } out: *next_index = index; return nr_found; } /** * radix_tree_gang_lookup_tag - perform multiple lookup on a radix tree * based on a tag * @root: radix tree root * @results: where the results of the lookup are placed * @first_index: start the lookup from this key * @max_items: place up to this many items at *results * @tag: the tag index (< RADIX_TREE_MAX_TAGS) * * Performs an index-ascending scan of the tree for present items which * have the tag indexed by @tag set. Places the items at *@results and * returns the number of items which were placed at *@results. */ unsigned int radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag) { const unsigned long max_index = radix_tree_maxindex(root->height); unsigned long cur_index = first_index; unsigned int ret = 0; while (ret < max_items) { unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; nr_found = __lookup_tag(root, results + ret, cur_index, max_items - ret, &next_index, tag); ret += nr_found; if (next_index == 0) break; cur_index = next_index; } return ret; } #endif /** * radix_tree_shrink - shrink height of a radix tree to minimal * @root radix tree root */ static inline void radix_tree_shrink(struct radix_tree_root *root) { /* try to shrink tree height */ while (root->height > 1 && root->rnode->count == 1 && root->rnode->slots[0]) { struct radix_tree_node *to_free = root->rnode; root->rnode = to_free->slots[0]; root->height--; /* must only free zeroed nodes into the slab */ #ifdef RADIX_TREE_TAGS tag_clear(to_free, 0, 0); tag_clear(to_free, 1, 0); #endif to_free->slots[0] = NULL; to_free->count = 0; radix_tree_node_free(to_free); } } /** * radix_tree_delete - delete an item from a radix tree * @root: radix tree root * @index: index key * * Remove the item at @index from the radix tree rooted at @root. * * Returns the address of the deleted item, or NULL if it was not present. */ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) { struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; struct radix_tree_path *orig_pathp; struct radix_tree_node *slot; unsigned int height, shift; void *ret = NULL; #ifdef RADIX_TREE_TAGS char tags[RADIX_TREE_MAX_TAGS]; int nr_cleared_tags; int tag; #endif int offset; height = root->height; if (index > radix_tree_maxindex(height)) goto out; shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; slot = root->rnode; for ( ; height > 0; height--) { if (slot == NULL) goto out; pathp++; offset = (index >> shift) & RADIX_TREE_MAP_MASK; pathp->offset = offset; pathp->node = slot; slot = slot->slots[offset]; shift -= RADIX_TREE_MAP_SHIFT; } ret = slot; if (ret == NULL) goto out; orig_pathp = pathp; #ifdef RADIX_TREE_TAGS /* * Clear all tags associated with the just-deleted item */ nr_cleared_tags = 0; for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { tags[tag] = 1; if (tag_get(pathp->node, tag, pathp->offset)) { tag_clear(pathp->node, tag, pathp->offset); if (!any_tag_set(pathp->node, tag)) { tags[tag] = 0; nr_cleared_tags++; } } } for (pathp--; nr_cleared_tags && pathp->node; pathp--) { for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { if (tags[tag]) continue; tag_clear(pathp->node, tag, pathp->offset); if (any_tag_set(pathp->node, tag)) { tags[tag] = 1; nr_cleared_tags--; } } } #endif /* Now free the nodes we do not need anymore */ for (pathp = orig_pathp; pathp->node; pathp--) { pathp->node->slots[pathp->offset] = NULL; pathp->node->count--; if (pathp->node->count) { if (pathp->node == root->rnode) radix_tree_shrink(root); goto out; } /* Node with zero slots in use so free it */ radix_tree_node_free(pathp->node); } root->rnode = NULL; root->height = 0; out: return ret; } #ifdef RADIX_TREE_TAGS /** * radix_tree_tagged - test whether any items in the tree are tagged * @root: radix tree root * @tag: tag to test */ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) { struct radix_tree_node *rnode; rnode = root->rnode; if (!rnode) return 0; return any_tag_set(rnode, tag); } #endif static unsigned long __maxindex(unsigned int height) { unsigned int tmp = height * RADIX_TREE_MAP_SHIFT; unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1; if (tmp >= RADIX_TREE_INDEX_BITS) index = ~0UL; return index; } static void radix_tree_init_maxindex(void) { unsigned int i; for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++) height_to_maxindex[i] = __maxindex(i); } void radix_tree_init(void) { radix_tree_init_maxindex(); } xfsprogs-3.1.9ubuntu2/libxfs/xfs_rtalloc.c0000664000000000000000000005052411330256617015601 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include /* * Prototypes for internal functions. */ STATIC int xfs_rtfind_back(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, xfs_rtblock_t, xfs_rtblock_t *); STATIC int xfs_rtfind_forw(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, xfs_rtblock_t, xfs_rtblock_t *); STATIC int xfs_rtmodify_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t, xfs_extlen_t, int); STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *); /* * Internal functions. */ /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. */ STATIC int /* error */ xfs_rtbuf_get( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t block, /* block number in bitmap or summary */ int issum, /* is summary not bitmap */ xfs_buf_t **bpp) /* output: buffer for the block */ { xfs_buf_t *bp; /* block buffer, result */ xfs_daddr_t d; /* disk addr of block */ int error; /* error value */ xfs_fsblock_t fsb; /* fs block number for block */ xfs_inode_t *ip; /* bitmap or summary inode */ ip = issum ? mp->m_rsumip : mp->m_rbmip; /* * Map from the file offset (block) and inode number to the * file system block. */ error = xfs_bmapi_single(tp, ip, XFS_DATA_FORK, &fsb, block); if (error) { return error; } ASSERT(fsb != NULLFSBLOCK); /* * Convert to disk address for buffer cache. */ d = XFS_FSB_TO_DADDR(mp, fsb); /* * Read the buffer. */ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, mp->m_bsize, 0, &bp); if (error) { return error; } ASSERT(bp && !XFS_BUF_GETERROR(bp)); *bpp = bp; return 0; } /* * Searching backward from start to limit, find the first block whose * allocated/free state is different from start's. */ STATIC int /* error */ xfs_rtfind_back( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to look at */ xfs_rtblock_t limit, /* last block to look at */ xfs_rtblock_t *rtblock) /* out: start block found */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_rtblock_t block; /* bitmap block number */ xfs_buf_t *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtblock_t firstbit; /* first useful bit in the word */ xfs_rtblock_t i; /* current bit number rel. to start */ xfs_rtblock_t len; /* length of inspected area */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ block = XFS_BITTOBLOCK(mp, start); error = xfs_rtbuf_get(mp, tp, block, 0, &bp); if (error) { return error; } bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Get the first word's index & point to it. */ word = XFS_BITTOWORD(mp, start); b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); len = start - limit + 1; /* * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the * partial word. */ if (bit < XFS_NBWORD - 1) { /* * Calculate first (leftmost) bit number to look at, * and mask for all the relevant bits in this word. */ firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0); mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) << firstbit; /* * Calculate the difference between the value there * and what we're looking for. */ if ((wdiff = (*b ^ want) & mask)) { /* * Different. Mark where we are and return. */ xfs_trans_brelse(tp, bp); i = bit - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; } i = bit - firstbit + 1; /* * Go on to previous block if that's where the previous word is * and we need the previous word. */ if (--word == -1 && i < len) { /* * If done with this block, get the previous one. */ xfs_trans_brelse(tp, bp); error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); if (error) { return error; } bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = XFS_BLOCKWMASK(mp); b = &bufp[word]; } else { /* * Go on to the previous word in the buffer. */ b--; } } else { /* * Starting on a word boundary, no partial word. */ i = 0; } /* * Loop over whole words in buffers. When we use up one buffer * we move on to the previous one. */ while (len - i >= XFS_NBWORD) { /* * Compute difference between actual and desired value. */ if ((wdiff = *b ^ want)) { /* * Different, mark where we are and return. */ xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; } i += XFS_NBWORD; /* * Go on to previous block if that's where the previous word is * and we need the previous word. */ if (--word == -1 && i < len) { /* * If done with this block, get the previous one. */ xfs_trans_brelse(tp, bp); error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); if (error) { return error; } bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = XFS_BLOCKWMASK(mp); b = &bufp[word]; } else { /* * Go on to the previous word in the buffer. */ b--; } } /* * If not ending on a word boundary, deal with the last * (partial) word. */ if (len - i) { /* * Calculate first (leftmost) bit number to look at, * and mask for all the relevant bits in this word. */ firstbit = XFS_NBWORD - (len - i); mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit; /* * Compute difference between actual and desired value. */ if ((wdiff = (*b ^ want) & mask)) { /* * Different, mark where we are and return. */ xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; } else i = len; } /* * No match, return that we scanned the whole area. */ xfs_trans_brelse(tp, bp); *rtblock = start - i + 1; return 0; } /* * Searching forward from start to limit, find the first block whose * allocated/free state is different from start's. */ STATIC int /* error */ xfs_rtfind_forw( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to look at */ xfs_rtblock_t limit, /* last block to look at */ xfs_rtblock_t *rtblock) /* out: start block found */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_rtblock_t block; /* bitmap block number */ xfs_buf_t *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtblock_t i; /* current bit number rel. to start */ xfs_rtblock_t lastbit; /* last useful bit in the word */ xfs_rtblock_t len; /* length of inspected area */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ block = XFS_BITTOBLOCK(mp, start); error = xfs_rtbuf_get(mp, tp, block, 0, &bp); if (error) { return error; } bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Get the first word's index & point to it. */ word = XFS_BITTOWORD(mp, start); b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); len = limit - start + 1; /* * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the * partial word. */ if (bit) { /* * Calculate last (rightmost) bit number to look at, * and mask for all the relevant bits in this word. */ lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; /* * Calculate the difference between the value there * and what we're looking for. */ if ((wdiff = (*b ^ want) & mask)) { /* * Different. Mark where we are and return. */ xfs_trans_brelse(tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *rtblock = start + i - 1; return 0; } i = lastbit - bit; /* * Go on to next block if that's where the next word is * and we need the next word. */ if (++word == XFS_BLOCKWSIZE(mp) && i < len) { /* * If done with this block, get the previous one. */ xfs_trans_brelse(tp, bp); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* * Go on to the previous word in the buffer. */ b++; } } else { /* * Starting on a word boundary, no partial word. */ i = 0; } /* * Loop over whole words in buffers. When we use up one buffer * we move on to the next one. */ while (len - i >= XFS_NBWORD) { /* * Compute difference between actual and desired value. */ if ((wdiff = *b ^ want)) { /* * Different, mark where we are and return. */ xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *rtblock = start + i - 1; return 0; } i += XFS_NBWORD; /* * Go on to next block if that's where the next word is * and we need the next word. */ if (++word == XFS_BLOCKWSIZE(mp) && i < len) { /* * If done with this block, get the next one. */ xfs_trans_brelse(tp, bp); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* * Go on to the next word in the buffer. */ b++; } } /* * If not ending on a word boundary, deal with the last * (partial) word. */ if ((lastbit = len - i)) { /* * Calculate mask for all the relevant bits in this word. */ mask = ((xfs_rtword_t)1 << lastbit) - 1; /* * Compute difference between actual and desired value. */ if ((wdiff = (*b ^ want) & mask)) { /* * Different, mark where we are and return. */ xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *rtblock = start + i - 1; return 0; } else i = len; } /* * No match, return that we scanned the whole area. */ xfs_trans_brelse(tp, bp); *rtblock = start + i - 1; return 0; } /* * Mark an extent specified by start and len freed. * Updates all the summary information as well as the bitmap. */ STATIC int /* error */ xfs_rtfree_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to free */ xfs_extlen_t len, /* length to free */ xfs_buf_t **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb) /* in/out: summary block number */ { xfs_rtblock_t end; /* end of the freed extent */ int error; /* error value */ xfs_rtblock_t postblock; /* first block freed > end */ xfs_rtblock_t preblock; /* first block freed < start */ end = start + len - 1; /* * Modify the bitmap to mark this extent freed. */ error = xfs_rtmodify_range(mp, tp, start, len, 1); if (error) { return error; } /* * Assume we're freeing out of the middle of an allocated extent. * We need to find the beginning and end of the extent so we can * properly update the summary. */ error = xfs_rtfind_back(mp, tp, start, 0, &preblock); if (error) { return error; } /* * Find the next allocated block (end of allocated extent). */ error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, &postblock); if (error) return error; /* * If there are blocks not being freed at the front of the * old extent, add summary data for them to be allocated. */ if (preblock < start) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(start - preblock), XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); if (error) { return error; } } /* * If there are blocks not being freed at the end of the * old extent, add summary data for them to be allocated. */ if (postblock > end) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock - end), XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); if (error) { return error; } } /* * Increment the summary information corresponding to the entire * (new) free extent. */ error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock + 1 - preblock), XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); return error; } /* * Set the given range of bitmap bits to the given value. * Do whatever I/O and logging is required. */ STATIC int /* error */ xfs_rtmodify_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to modify */ xfs_extlen_t len, /* length of extent to modify */ int val) /* 1 for free, 0 for allocated */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_rtblock_t block; /* bitmap block number */ xfs_buf_t *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtword_t *first; /* first used word in the buffer */ int i; /* current bit number rel. to start */ int lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask o frelevant bits for value */ int word; /* word number in the buffer */ /* * Compute starting bitmap block number. */ block = XFS_BITTOBLOCK(mp, start); /* * Read the bitmap block, and point to its data. */ error = xfs_rtbuf_get(mp, tp, block, 0, &bp); if (error) { return error; } bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Compute the starting word's address, and starting bit. */ word = XFS_BITTOWORD(mp, start); first = b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); /* * 0 (allocated) => all zeroes; 1 (free) => all ones. */ val = -val; /* * If not starting on a word boundary, deal with the first * (partial) word. */ if (bit) { /* * Compute first bit not changed and mask of relevant bits. */ lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; /* * Set/clear the active bits. */ if (val) *b |= mask; else *b &= ~mask; i = lastbit - bit; /* * Go on to the next block if that's where the next word is * and we need the next word. */ if (++word == XFS_BLOCKWSIZE(mp) && i < len) { /* * Log the changed part of this block. * Get the next one. */ xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), (uint)((char *)b - (char *)bufp)); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* * Go on to the next word in the buffer */ b++; } } else { /* * Starting on a word boundary, no partial word. */ i = 0; } /* * Loop over whole words in buffers. When we use up one buffer * we move on to the next one. */ while (len - i >= XFS_NBWORD) { /* * Set the word value correctly. */ *b = val; i += XFS_NBWORD; /* * Go on to the next block if that's where the next word is * and we need the next word. */ if (++word == XFS_BLOCKWSIZE(mp) && i < len) { /* * Log the changed part of this block. * Get the next one. */ xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), (uint)((char *)b - (char *)bufp)); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* * Go on to the next word in the buffer */ b++; } } /* * If not ending on a word boundary, deal with the last * (partial) word. */ if ((lastbit = len - i)) { /* * Compute a mask of relevant bits. */ bit = 0; mask = ((xfs_rtword_t)1 << lastbit) - 1; /* * Set/clear the active bits. */ if (val) *b |= mask; else *b &= ~mask; b++; } /* * Log any remaining changed bytes. */ if (b > first) xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), (uint)((char *)b - (char *)bufp - 1)); return 0; } /* * Read and modify the summary information for a given extent size, * bitmap block combination. * Keeps track of a current summary block, so we don't keep reading * it from the buffer cache. */ STATIC int /* error */ xfs_rtmodify_summary( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ int log, /* log2 of extent size */ xfs_rtblock_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ xfs_buf_t **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb) /* in/out: summary block number */ { xfs_buf_t *bp; /* buffer for the summary block */ int error; /* error value */ xfs_fsblock_t sb; /* summary fsblock */ int so; /* index into the summary file */ xfs_suminfo_t *sp; /* pointer to returned data */ /* * Compute entry number in the summary file. */ so = XFS_SUMOFFS(mp, log, bbno); /* * Compute the block number in the summary file. */ sb = XFS_SUMOFFSTOBLOCK(mp, so); /* * If we have an old buffer, and the block number matches, use that. */ if (rbpp && *rbpp && *rsb == sb) bp = *rbpp; /* * Otherwise we have to get the buffer. */ else { /* * If there was an old one, get rid of it first. */ if (rbpp && *rbpp) xfs_trans_brelse(tp, *rbpp); error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); if (error) { return error; } /* * Remember this buffer and block for the next call. */ if (rbpp) { *rbpp = bp; *rsb = sb; } } /* * Point to the summary information, modify and log it. */ sp = XFS_SUMPTR(mp, bp, so); *sp += delta; xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)), (uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1)); return 0; } /* * Free an extent in the realtime subvolume. Length is expressed in * realtime extents, as is the block number. */ int /* error */ xfs_rtfree_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to free */ xfs_extlen_t len) /* length of extent freed */ { int error; /* error value */ xfs_inode_t *ip; /* bitmap file inode */ xfs_mount_t *mp; /* file system mount structure */ xfs_fsblock_t sb; /* summary file block number */ xfs_buf_t *sumbp; /* summary file block buffer */ mp = tp->t_mountp; /* * Synchronize by locking the bitmap inode. */ if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip))) return error; #if defined(__KERNEL__) && defined(DEBUG) /* * Check to see that this whole range is currently allocated. */ { int stat; /* result from checking range */ error = xfs_rtcheck_alloc_range(mp, tp, bno, len, &stat); if (error) { return error; } ASSERT(stat); } #endif sumbp = NULL; /* * Free the range of realtime blocks. */ error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); if (error) { return error; } /* * Mark more blocks free in the superblock. */ xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len); /* * If we've now freed all the blocks, reset the file sequence * number to 0. */ if (tp->t_frextents_delta + mp->m_sb.sb_frextents == mp->m_sb.sb_rextents) { if (!(ip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) ip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; *(__uint64_t *)&ip->i_d.di_atime = 0; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } return 0; } xfsprogs-3.1.9ubuntu2/configure0000775000000000000000000157243212254353666013555 0ustar #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="include/libxfs.h" ac_default_prefix=/usr # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS have_zipped_manpages libblkid enable_blkid have_fiemap have_fallocate have_getmntinfo have_getmntent have_sendfile have_mincore have_madvise have_fadvise libpthread libuuid librt libdirsuffix rpmbuild RPMBUILD rpm_version rpm RPM xgettext XGETTEXT msgmerge MSGMERGE msgfmt MSGFMT sort SORT echo ECHO sed awk makedepend zip ZIP tar TAR make MAKE cc pkg_platform pkg_distribution pkg_group pkg_user malloc_lib opt_build debug_build pkg_release pkg_version pkg_name LOCALIZED_FILES root_libdir root_sbindir enable_lib64 libtermcap enable_editline libeditline enable_readline libreadline enable_gettext enable_shared CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL AWK RANLIB STRIP ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_gettext enable_readline enable_editline enable_termcap enable_blkid enable_lib64 ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-shared=yes/no Enable use of shared libraries default=yes --enable-gettext=yes/no Enable alternate language support default=yes --enable-readline=yes/no Enable readline command editing default=no --enable-editline=yes/no Enable editline command editing default=no --enable-termcap=yes/no Enable terminal capabilities library default=no --enable-blkid=yes/no Enable block device id library default=yes --enable-lib64=yes/no Enable lib64 support default=yes Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in . "$srcdir"/.; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers include/platform_defs.h" case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; else enable_shared=yes fi # Check whether --enable-gettext was given. if test "${enable_gettext+set}" = set; then : enableval=$enable_gettext; else enable_gettext=yes fi # Check whether --enable-readline was given. if test "${enable_readline+set}" = set; then : enableval=$enable_readline; test $enable_readline = yes && libreadline="-lreadline" else enable_readline=no fi # Check whether --enable-editline was given. if test "${enable_editline+set}" = set; then : enableval=$enable_editline; test $enable_editline = yes && libeditline="-ledit" else enable_editline=no fi # Check whether --enable-termcap was given. if test "${enable_termcap+set}" = set; then : enableval=$enable_termcap; test $enable_termcap = yes && libtermcap="-ltermcap" fi # AC_HAVE_BLKID_TOPO below wil find the library & check for topo support # Check whether --enable-blkid was given. if test "${enable_blkid+set}" = set; then : enableval=$enable_blkid; else enable_blkid=yes fi # Check whether --enable-lib64 was given. if test "${enable_lib64+set}" = set; then : enableval=$enable_lib64; else enable_lib64=yes fi # # If the user specified a libdir ending in lib64 do not append another # 64 to the library names. # base_libdir=`basename "$libdir"` case $base_libdir in lib64) enable_lib64=no esac # # Some important tools should be installed into the root partitions. # # Check whether exec_prefix=/usr: and install them to /sbin in that # case. If the user choses a different prefix assume he just wants # a local install for testing and not a system install. # case $exec_prefix:$prefix in NONE:NONE | NONE:/usr | /usr:*) root_sbindir='/sbin' root_libdir="/${base_libdir}" ;; *) root_sbindir="${sbindir}" root_libdir="${libdir}" ;; esac # Find localized files. Don't descend into any "dot directories" # (like .git or .pc from quilt). Strangely, the "-print" argument # to "find" is required, to avoid including such directories in the # list. LOCALIZED_FILES="" for lfile in `find ${srcdir} -path './.??*' -prune -o -name '*.c' -type f -print || exit 1`; do LOCALIZED_FILES="$LOCALIZED_FILES \$(TOPDIR)/$lfile" done pkg_name="xfsprogs" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu . ./VERSION pkg_version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION} pkg_release=$PKG_BUILD test -z "$BUILD_VERSION" || pkg_release="$BUILD_VERSION" DEBUG=${DEBUG:-'-DDEBUG'} debug_build="$DEBUG" OPTIMIZER=${OPTIMIZER:-'-g -O2'} opt_build="$OPTIMIZER" MALLOCLIB=${MALLOCLIB:-''} malloc_lib="$MALLOCLIB" pkg_user=`id -u -n` test -z "$INSTALL_USER" || pkg_user="$INSTALL_USER" pkg_group=`id -g -n` test -z "$INSTALL_GROUP" || pkg_group="$INSTALL_GROUP" pkg_distribution=`uname -s` test -z "$DISTRIBUTION" || pkg_distribution="$DISTRIBUTION" pkg_platform=`uname -s | tr 'A-Z' 'a-z' | tr -d / | sed -e 's/irix64/irix/'` test -z "$PLATFORM" || pkg_platform="$PLATFORM" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cc="$CC" if test -z ""$cc""; then echo echo FATAL ERROR: cc does not seem to be installed. echo xfsprogs cannot be built without a working C compiler installation. exit 1 fi if test -z "$MAKE"; then # Extract the first word of "gmake", so it can be a program name with args. set dummy gmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $MAKE in [\\/]* | ?:[\\/]*) ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/bin:/usr/local/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MAKE=$ac_cv_path_MAKE if test -n "$MAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 $as_echo "$MAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$MAKE"; then # Extract the first word of "make", so it can be a program name with args. set dummy make; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $MAKE in [\\/]* | ?:[\\/]*) ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MAKE=$ac_cv_path_MAKE if test -n "$MAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 $as_echo "$MAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi make=$MAKE if test -z ""$make""; then echo echo FATAL ERROR: make does not seem to be installed. echo xfsprogs cannot be built without a working GNU make installation. exit 1 fi if test -z "$TAR"; then # Extract the first word of "tar", so it can be a program name with args. set dummy tar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TAR+:} false; then : $as_echo_n "(cached) " >&6 else case $TAR in [\\/]* | ?:[\\/]*) ac_cv_path_TAR="$TAR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/freeware/bin:/bin:/usr/local/bin:/usr/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TAR=$ac_cv_path_TAR if test -n "$TAR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5 $as_echo "$TAR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi tar=$TAR if test -z "$ZIP"; then # Extract the first word of "gzip", so it can be a program name with args. set dummy gzip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $ZIP in [\\/]* | ?:[\\/]*) ac_cv_path_ZIP="$ZIP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin:/usr/local/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ZIP=$ac_cv_path_ZIP if test -n "$ZIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP" >&5 $as_echo "$ZIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi zip=$ZIP { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc -MM is supported" >&5 $as_echo_n "checking whether gcc -MM is supported... " >&6; } if ${ac_cv_gcc_nodeps+:} false; then : $as_echo_n "(cached) " >&6 else cat > conftest.c < int main() { exit(0); } EOF ac_cv_gcc_nodeps=no if ${CC} -MM conftest.c >/dev/null 2>&1; then ac_cv_gcc_nodeps=yes fi rm -f conftest.c a.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_nodeps" >&5 $as_echo "$ac_cv_gcc_nodeps" >&6; } makedepend="$cc -MM" if test $ac_cv_gcc_nodeps = no; then makedepend=/bin/true fi if test -z "$AWK"; then # Extract the first word of "awk", so it can be a program name with args. set dummy awk; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AWK+:} false; then : $as_echo_n "(cached) " >&6 else case $AWK in [\\/]* | ?:[\\/]*) ac_cv_path_AWK="$AWK" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_AWK="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AWK=$ac_cv_path_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi awk=$AWK if test -z "$SED"; then # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 $as_echo "$SED" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi sed=$SED if test -z "$ECHO"; then # Extract the first word of "echo", so it can be a program name with args. set dummy echo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ECHO+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHO in [\\/]* | ?:[\\/]*) ac_cv_path_ECHO="$ECHO" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ECHO="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ECHO=$ac_cv_path_ECHO if test -n "$ECHO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ECHO" >&5 $as_echo "$ECHO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi echo=$ECHO if test -z "$SORT"; then # Extract the first word of "sort", so it can be a program name with args. set dummy sort; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SORT+:} false; then : $as_echo_n "(cached) " >&6 else case $SORT in [\\/]* | ?:[\\/]*) ac_cv_path_SORT="$SORT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SORT=$ac_cv_path_SORT if test -n "$SORT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5 $as_echo "$SORT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi sort=$SORT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi if test "$enable_gettext" = yes; then if test -z "$MSGFMT"; then # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $MSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/bin:/usr/local/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MSGFMT=$ac_cv_path_MSGFMT if test -n "$MSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi msgfmt=$MSGFMT if test -z ""$msgfmt""; then echo echo FATAL ERROR: msgfmt does not seem to be installed. echo xfsprogs cannot be built without a working gettext installation. exit 1 fi if test -z "$MSGMERGE"; then # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case $MSGMERGE in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/bin:/usr/local/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MSGMERGE=$ac_cv_path_MSGMERGE if test -n "$MSGMERGE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi msgmerge=$MSGMERGE if test -z ""$msgmerge""; then echo echo FATAL ERROR: msgmerge does not seem to be installed. echo xfsprogs cannot be built without a working gettext installation. exit 1 fi if test -z "$XGETTEXT"; then # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case $XGETTEXT in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/bin:/usr/local/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XGETTEXT=$ac_cv_path_XGETTEXT if test -n "$XGETTEXT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi xgettext=$XGETTEXT if test -z ""$xgettext""; then echo echo FATAL ERROR: xgettext does not seem to be installed. echo xfsprogs cannot be built without a working gettext installation. exit 1 fi fi if test -z "$RPM"; then # Extract the first word of "rpm", so it can be a program name with args. set dummy rpm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_RPM+:} false; then : $as_echo_n "(cached) " >&6 else case $RPM in [\\/]* | ?:[\\/]*) ac_cv_path_RPM="$RPM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/bin:/usr/bin:/usr/freeware/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RPM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RPM=$ac_cv_path_RPM if test -n "$RPM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPM" >&5 $as_echo "$RPM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi rpm=$RPM rpm_version=0 test -n "$RPM" && test -x "$RPM" && rpm_version=`$RPM --version \ | awk '{print $NF}' | awk -F. '{V=1; print $V}'` if test $rpm_version -ge 4; then # Extract the first word of "rpmbuild", so it can be a program name with args. set dummy rpmbuild; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_RPMBUILD+:} false; then : $as_echo_n "(cached) " >&6 else case $RPMBUILD in [\\/]* | ?:[\\/]*) ac_cv_path_RPMBUILD="$RPMBUILD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RPMBUILD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RPMBUILD=$ac_cv_path_RPMBUILD if test -n "$RPMBUILD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPMBUILD" >&5 $as_echo "$RPMBUILD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rpmbuild=$RPMBUILD else rpmbuild=$RPM fi enable_lib64="$enable_lib64" libdirsuffix="" searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test "$enable_lib64" = "yes" -a -n "$searchpath"; then save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) libdirsuffix=64 ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) libdirsuffix=64 ;; esac ;; esac fi done IFS="$save_IFS" fi for ac_header in aio.h do : ac_fn_c_check_header_mongrel "$LINENO" "aio.h" "ac_cv_header_aio_h" "$ac_includes_default" if test "x$ac_cv_header_aio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_AIO_H 1 _ACEOF fi done if test $ac_cv_header_aio_h = no; then echo echo 'FATAL ERROR: could not find a valid header.' exit 1 fi for ac_func in lio_listio do : ac_fn_c_check_func "$LINENO" "lio_listio" "ac_cv_func_lio_listio" if test "x$ac_cv_func_lio_listio" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIO_LISTIO 1 _ACEOF fi done if test $ac_cv_func_lio_listio = yes; then librt="" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lio_listio in -lrt" >&5 $as_echo_n "checking for lio_listio in -lrt... " >&6; } if ${ac_cv_lib_rt_lio_listio+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt -lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char lio_listio (); int main () { return lio_listio (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_lio_listio=yes else ac_cv_lib_rt_lio_listio=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_lio_listio" >&5 $as_echo "$ac_cv_lib_rt_lio_listio" >&6; } if test "x$ac_cv_lib_rt_lio_listio" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" else echo echo 'FATAL ERROR: could not find a library with lio_listio.' exit 1 fi librt="-lrt" fi for ac_header in uuid.h sys/uuid.h uuid/uuid.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test $ac_cv_header_uuid_h = no -a \ $ac_cv_header_sys_uuid_h = no -a \ $ac_cv_header_uuid_uuid_h = no; then echo echo 'FATAL ERROR: could not find a valid UUID header.' echo 'Install the Universally Unique Identifiers development package.' exit 1 fi for ac_func in uuid_compare do : ac_fn_c_check_func "$LINENO" "uuid_compare" "ac_cv_func_uuid_compare" if test "x$ac_cv_func_uuid_compare" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UUID_COMPARE 1 _ACEOF fi done if test $ac_cv_func_uuid_compare = yes; then libuuid="" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_compare in -luuid" >&5 $as_echo_n "checking for uuid_compare in -luuid... " >&6; } if ${ac_cv_lib_uuid_uuid_compare+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char uuid_compare (); int main () { return uuid_compare (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_uuid_uuid_compare=yes else ac_cv_lib_uuid_uuid_compare=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_compare" >&5 $as_echo "$ac_cv_lib_uuid_uuid_compare" >&6; } if test "x$ac_cv_lib_uuid_uuid_compare" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBUUID 1 _ACEOF LIBS="-luuid $LIBS" else echo echo 'FATAL ERROR: could not find a valid UUID library.' echo 'Install the Universally Unique Identifiers library package.' exit 1 fi libuuid="-luuid" fi for ac_header in pthread.h do : ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTHREAD_H 1 _ACEOF fi done if test $ac_cv_header_pthread_h = no; then for ac_header in pthread.h do : ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTHREAD_H 1 _ACEOF else echo echo 'FATAL ERROR: could not find a valid pthread header.' exit 1 fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else echo echo 'FATAL ERROR: could not find a valid pthread library.' exit 1 fi libpthread=-lpthread { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fadvise " >&5 $as_echo_n "checking for fadvise ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include int main () { posix_fadvise(0, 1, 0, POSIX_FADV_NORMAL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_fadvise=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for madvise " >&5 $as_echo_n "checking for madvise ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include int main () { posix_madvise(0, 0, MADV_NORMAL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_madvise=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mincore " >&5 $as_echo_n "checking for mincore ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include int main () { mincore(0, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_mincore=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile " >&5 $as_echo_n "checking for sendfile ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include int main () { sendfile(0, 0, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_sendfile=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getmntent " >&5 $as_echo_n "checking for getmntent ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { getmntent(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_getmntent=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getmntinfo " >&5 $as_echo_n "checking for getmntinfo ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { getmntinfo(0, 0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_getmntinfo=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fallocate" >&5 $as_echo_n "checking for fallocate... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include int main () { fallocate(0, 0, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_fallocate=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fiemap" >&5 $as_echo_n "checking for fiemap... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include int main () { struct fiemap *fiemap; ioctl(0, FS_IOC_FIEMAP, 0, (unsigned long)fiemap); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_fiemap=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext enable_blkid="$enable_blkid" if test "$enable_blkid" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing blkid_probe_all" >&5 $as_echo_n "checking for library containing blkid_probe_all... " >&6; } if ${ac_cv_search_blkid_probe_all+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char blkid_probe_all (); int main () { return blkid_probe_all (); ; return 0; } _ACEOF for ac_lib in '' blkid; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_blkid_probe_all=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_blkid_probe_all+:} false; then : break fi done if ${ac_cv_search_blkid_probe_all+:} false; then : else ac_cv_search_blkid_probe_all=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_blkid_probe_all" >&5 $as_echo "$ac_cv_search_blkid_probe_all" >&6; } ac_res=$ac_cv_search_blkid_probe_all if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in blkid_probe_get_topology do : ac_fn_c_check_func "$LINENO" "blkid_probe_get_topology" "ac_cv_func_blkid_probe_get_topology" if test "x$ac_cv_func_blkid_probe_get_topology" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BLKID_PROBE_GET_TOPOLOGY 1 _ACEOF fi done if test $ac_cv_func_blkid_probe_get_topology = yes; then libblkid="-lblkid" else libblkd="" enable_blkid="no" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __psint_t " >&5 $as_echo_n "checking for __psint_t ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { __psint_t psint; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE___PSINT_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __psunsigned_t " >&5 $as_echo_n "checking for __psunsigned_t ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { __psunsigned_t psuint; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE___PSUNSIGNED_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __u32 " >&5 $as_echo_n "checking for __u32 ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { __u32 u32; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE___U32 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "$cross_compiling" = yes -a -z "$ac_cv_sizeof_long"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling; assuming 32bit long and 32bit pointers" >&5 $as_echo "$as_me: WARNING: Cross compiling; assuming 32bit long and 32bit pointers" >&2;} fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 $as_echo_n "checking size of char *... " >&6; } if ${ac_cv_sizeof_char_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$ac_includes_default"; then : else if test "$ac_cv_type_char_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 $as_echo "$ac_cv_sizeof_char_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR_P $ac_cv_sizeof_char_p _ACEOF if test $ac_cv_sizeof_long -eq 4 -o $ac_cv_sizeof_long -eq 0; then $as_echo "#define HAVE_32BIT_LONG 1" >>confdefs.h fi if test $ac_cv_sizeof_long -eq 8; then $as_echo "#define HAVE_64BIT_LONG 1" >>confdefs.h fi if test $ac_cv_sizeof_char_p -eq 4 -o $ac_cv_sizeof_char_p -eq 0; then $as_echo "#define HAVE_32BIT_PTR 1" >>confdefs.h fi if test $ac_cv_sizeof_char_p -eq 8; then $as_echo "#define HAVE_64BIT_PTR 1" >>confdefs.h fi have_zipped_manpages=false for d in ${prefix}/share/man ${prefix}/man ; do if test -f $d/man1/man.1.gz then have_zipped_manpages=true break fi done ac_config_files="$ac_config_files include/builddefs" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "include/platform_defs.h") CONFIG_HEADERS="$CONFIG_HEADERS include/platform_defs.h" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "include/builddefs") CONFIG_FILES="$CONFIG_FILES include/builddefs" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi xfsprogs-3.1.9ubuntu2/Makefile0000664000000000000000000000705012062210562013252 0ustar # # Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. # ifeq ("$(origin V)", "command line") BUILD_VERBOSE = $(V) endif ifndef BUILD_VERBOSE BUILD_VERBOSE = 0 endif ifeq ($(BUILD_VERBOSE),1) Q = else Q = @ endif MAKEOPTS = --no-print-directory Q=$(Q) TOPDIR = . HAVE_BUILDDEFS = $(shell test -f $(TOPDIR)/include/builddefs && echo yes || echo no) ifeq ($(HAVE_BUILDDEFS), yes) include $(TOPDIR)/include/builddefs endif SRCDIR = $(PKG_NAME)-$(PKG_VERSION) SRCTAR = $(PKG_NAME)-$(PKG_VERSION).tar.gz CONFIGURE = aclocal.m4 configure config.guess config.sub install-sh ltmain.sh LSRCFILES = configure.ac release.sh README VERSION $(CONFIGURE) LDIRT = config.log .ltdep .dep config.status config.cache confdefs.h \ conftest* built .census install.* install-dev.* *.gz \ autom4te.cache/* libtool include/builddefs include/platform_defs.h ifeq ($(HAVE_BUILDDEFS), yes) LDIRDIRT = $(SRCDIR) LDIRT += $(SRCTAR) endif LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ mdrestore repair rtcp m4 man doc po debian SUBDIRS = include $(LIB_SUBDIRS) $(TOOL_SUBDIRS) default: include/builddefs include/platform_defs.h ifeq ($(HAVE_BUILDDEFS), no) $(Q)$(MAKE) $(MAKEOPTS) -C . $@ else $(Q)$(MAKE) $(MAKEOPTS) $(SUBDIRS) endif # tool/lib dependencies $(LIB_SUBDIRS) $(TOOL_SUBDIRS): include copy mdrestore: libxfs db logprint: libxfs libxlog fsr: libhandle growfs: libxfs libxcmd io: libxcmd libhandle mkfs: libxfs quota: libxcmd repair: libxfs libxlog ifneq ($(ENABLE_BLKID), yes) mkfs: libdisk endif ifeq ($(HAVE_BUILDDEFS), yes) include $(BUILDRULES) else clean: # if configure hasn't run, nothing to clean endif # Recent versions of libtool require the -i option for copying auxiliary # files (config.sub, config.guess, install-sh, ltmain.sh), while older # versions will copy those files anyway, and don't understand -i. LIBTOOLIZE_INSTALL = `libtoolize -n -i >/dev/null 2>/dev/null && echo -i` configure: libtoolize -c $(LIBTOOLIZE_INSTALL) -f cp include/install-sh . aclocal -I m4 autoconf include/builddefs: configure ./configure $$LOCAL_CONFIGURE_OPTIONS include/platform_defs.h: include/builddefs ## Recover from the removal of $@ @if test -f $@; then :; else \ rm -f include/builddefs; \ $(MAKE) $(MAKEOPTS) $(AM_MAKEFLAGS) include/builddefs; \ fi install: $(addsuffix -install,$(SUBDIRS)) $(INSTALL) -m 755 -d $(PKG_DOC_DIR) $(INSTALL) -m 644 README $(PKG_DOC_DIR) install-dev: $(addsuffix -install-dev,$(SUBDIRS)) install-qa: install $(addsuffix -install-qa,$(SUBDIRS)) %-install: @echo "Installing $@" $(Q)$(MAKE) $(MAKEOPTS) -C $* install %-install-dev: @echo "Installing $@" $(Q)$(MAKE) $(MAKEOPTS) -C $* install-dev %-install-qa: @echo "Installing $@" $(Q)$(MAKE) $(MAKEOPTS) -C $* install-qa distclean: clean $(Q)rm -f $(LDIRT) realclean: distclean $(Q)rm -f $(CONFIGURE) # # All this gunk is to allow for a make dist on an unconfigured tree # dist: include/builddefs include/platform_defs.h default ifeq ($(HAVE_BUILDDEFS), no) $(Q)$(MAKE) $(MAKEOPTS) -C . $@ else $(Q)$(MAKE) $(MAKEOPTS) $(SRCTAR) endif deb: include/builddefs include/platform_defs.h ifeq ($(HAVE_BUILDDEFS), no) $(Q)$(MAKE) $(MAKEOPTS) -C . $@ else $(Q)$(MAKE) $(MAKEOPTS) $(SRCDIR) $(Q)$(MAKE) $(MAKEOPTS) -C po $(Q)$(MAKE) $(MAKEOPTS) source-link $(Q)cd $(SRCDIR) && dpkg-buildpackage endif $(SRCDIR) : $(_FORCE) rm -fr $@ mkdir -p $@ $(SRCTAR) : default $(SRCDIR) $(Q)$(MAKE) $(MAKEOPTS) source-link unset TAPE; $(TAR) -cf - $(SRCDIR) | $(ZIP) --best > $@ && \ echo Wrote: $@ xfsprogs-3.1.9ubuntu2/VERSION0000664000000000000000000000016312062210562012660 0ustar # # This file is used by configure to get version information # PKG_MAJOR=3 PKG_MINOR=1 PKG_REVISION=9 PKG_BUILD=1 xfsprogs-3.1.9ubuntu2/ltmain.sh0000664000000000000000000105202211711735051013437 0ustar # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 xfsprogs-3.1.9ubuntu2/libdisk/0000775000000000000000000000000012062211563013233 5ustar xfsprogs-3.1.9ubuntu2/libdisk/drivers.c0000664000000000000000000000422611140033220015045 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "drivers.h" void get_subvol_stripe_wrapper( char *dev, sv_type_t type, int *sunit, int *swidth, int *sectalign) { struct stat64 sb; if (dev == NULL) return; if (stat64(dev, &sb)) { fprintf(stderr, _("Cannot stat %s: %s\n"), dev, strerror(errno)); exit(1); } if ( dm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb)) return; if ( md_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb)) return; if ( lvm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb)) return; if ( xvm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb)) return; if (evms_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb)) return; /* ... add new device drivers here */ } #define DEVICES "/proc/devices" /* * General purpose routine which dredges through procfs trying to * match up device driver names with the associated major numbers * being used in the running kernel. */ int get_driver_block_major( const char *driver, int major) { FILE *f; char buf[64], puf[64]; int dmajor, match = 0; if ((f = fopen(DEVICES, "r")) == NULL) return match; while (fgets(buf, sizeof(buf), f)) /* skip to block dev section */ if (strncmp("Block devices:\n", buf, sizeof(buf)) == 0) break; while (fgets(buf, sizeof(buf), f)) if ((sscanf(buf, "%u %s\n", &dmajor, puf) == 2) && (strncmp(puf, driver, sizeof(puf)) == 0) && (dmajor == major)) match = 1; fclose(f); return match; } xfsprogs-3.1.9ubuntu2/libdisk/Makefile0000664000000000000000000000115011432663627014704 0ustar # # Copyright (c) 2000-2001,2004 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTLIBRARY = libdisk.la LT_CURRENT = 0 LT_REVISION = 0 LT_AGE = 0 CFILES = drivers.c fstype.c pttype.c HFILES = drivers.h fstype.h pttype.h md.h xvm.h evms.h LINUX_DRIVERS = dm.c md.c xvm.c evms.c lvm.c ifeq ($(PKG_PLATFORM),linux) CFILES += $(LINUX_DRIVERS) else LSRCFILES = $(LINUX_DRIVERS) endif ifneq ($(ENABLE_BLKID), yes) default: ltdepend $(LTLIBRARY) else default: endif include $(BUILDRULES) install: default install-dev: default install-qa: install-dev -include .ltdep xfsprogs-3.1.9ubuntu2/libdisk/pttype.c0000664000000000000000000000510511140033220014711 0ustar /* * Copyright (c) 2000-2001 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "pttype.h" #define blksize 512 static u_int32_t twos_complement_32bit_sum(u_int32_t *base, int size) { int i; u_int32_t sum = 0; size = size / sizeof(u_int32_t); for (i = 0; i < size; i++) sum = sum - ntohl(base[i]); return sum; } static int sgi_parttable(char *base) { u_int32_t csum; struct volume_header *vh = (struct volume_header *)base; if (ntohl(vh->vh_magic) != VHMAGIC) return 0; csum = twos_complement_32bit_sum((u_int32_t *)vh, sizeof(struct volume_header)); return !csum; } static int dos_parttable(char *base) { return (base[510] == 0x55 && base[511] == 0xaa); } static int aix_parttable(char *base) { return (aixlabel(base)->magic == AIX_LABEL_MAGIC || aixlabel(base)->magic == AIX_LABEL_MAGIC_SWAPPED); } static int sun_parttable(char *base) { unsigned short *ush; int csum = 0; if (sunlabel(base)->magic != SUN_LABEL_MAGIC && sunlabel(base)->magic != SUN_LABEL_MAGIC_SWAPPED) return csum; ush = ((unsigned short *) (sunlabel(base) + 1)) - 1; while (ush >= (unsigned short *)sunlabel(base)) csum ^= *ush--; return !csum; } static int mac_parttable(char *base) { return (ntohs(maclabel(base)->magic) == MAC_LABEL_MAGIC || ntohs(maclabel(base)->magic) == MAC_PARTITION_MAGIC || ntohs(maclabel(base)->magic) == MAC_OLD_PARTITION_MAGIC); } char * pttype(char *device) { int fd; char *type = NULL; char buf[blksize]; if ((fd = open(device, O_RDONLY)) < 0) ; else if (read(fd, buf, blksize) != blksize) ; else { if (sgi_parttable(buf)) type = "SGI"; else if (sun_parttable(buf)) type = "Sun"; else if (aix_parttable(buf)) type = "AIX"; else if (dos_parttable(buf)) type = "DOS"; else if (mac_parttable(buf)) type = "Mac"; } if (fd >= 0) close(fd); return type; } xfsprogs-3.1.9ubuntu2/libdisk/dm.c0000664000000000000000000000506611256276416014022 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "drivers.h" int mnt_is_dm_subvol( dev_t dev) { return get_driver_block_major("device-mapper", major(dev)); } int dm_get_subvol_stripe( char *dfile, sv_type_t type, int *sunit, int *swidth, int *sectalign, struct stat64 *sb) { int count, stripes = 0, stripesize = 0; int dmpipe[2]; char *largv[7]; FILE *stream; long long offset, size; static char *command = "table"; /* dmsetup table /dev/xxx */ char major_str[4], minor_str[4]; if (!mnt_is_dm_subvol(sb->st_rdev)) return 0; /* Quest for dmsetup */ if (!access("/usr/local/sbin/dmsetup", R_OK|X_OK)) largv[0] = "/usr/local/sbin/dmsetup"; else if (!access("/usr/sbin/dmsetup", R_OK|X_OK)) largv[0] = "/usr/sbin/dmsetup"; else if (!access("/sbin/dmsetup", R_OK|X_OK)) largv[0] = "/sbin/dmsetup"; else { fprintf(stderr, _("Warning - device mapper device, but no dmsetup(8) found\n")); return 0; } snprintf(major_str, 4, "%d", major(sb->st_rdev)); snprintf(minor_str, 4, "%d", minor(sb->st_rdev)); largv[1] = command; largv[2] = "-j"; largv[3] = major_str; largv[4] = "-m"; largv[5] = minor_str; largv[6] = NULL; /* Open pipe */ if (pipe(dmpipe) < 0) { fprintf(stderr, _("Could not open pipe\n")); exit(1); } /* Spawn dmsetup */ switch (fork()) { case 0: /* Plumbing */ close(dmpipe[0]); if (dmpipe[1] != STDOUT_FILENO) dup2(dmpipe[1], STDOUT_FILENO); execv(largv[0], largv); fprintf(stderr, _("Failed to execute %s\n"), largv[0]); exit(1); case -1: fprintf(stderr, _("Failed forking dmsetup process\n")); exit(1); default: break; } close(dmpipe[1]); stream = fdopen(dmpipe[0], "r"); count = fscanf(stream, "%lld %lld striped %d %d ", &offset, &size, &stripes, &stripesize); fclose(stream); if (count != 4) return 0; /* Update sizes */ *sunit = stripesize; *swidth = (stripes * stripesize); *sectalign = 0; return 1; } xfsprogs-3.1.9ubuntu2/libdisk/drivers.h0000664000000000000000000000320411140033220015045 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include /* * This stuff is all very platform specific. */ #ifdef __linux__ extern int dm_get_subvol_stripe(char*, sv_type_t, int*, int*, int*, struct stat64*); extern int md_get_subvol_stripe(char*, sv_type_t, int*, int*, int*, struct stat64*); extern int lvm_get_subvol_stripe(char*, sv_type_t, int*, int*, int*, struct stat64*); extern int xvm_get_subvol_stripe(char*, sv_type_t, int*, int*, int*, struct stat64*); extern int evms_get_subvol_stripe(char*, sv_type_t, int*, int*, int*, struct stat64*); #else #define stat64 stat #define dm_get_subvol_stripe(dev, type, a, b, c, stat) (-1) #define md_get_subvol_stripe(dev, type, a, b, c, stat) (-1) #define lvm_get_subvol_stripe(dev, type, a, b, c, stat) (-1) #define xvm_get_subvol_stripe(dev, type, a, b, c, stat) (-1) #define evms_get_subvol_stripe(dev, type, a, b, c, stat) (-1) #endif xfsprogs-3.1.9ubuntu2/libdisk/md.h0000664000000000000000000000353411140033220013775 0ustar /* * Copyright (c) 2002-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MD_MAJOR #define MD_MAJOR 9 /* we also check at runtime */ #endif #define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, struct md_array_info) #define MD_SB_CLEAN 0 #define MD_SB_ERRORS 1 struct md_array_info { /* * Generic constant information */ __uint32_t major_version; __uint32_t minor_version; __uint32_t patch_version; __uint32_t ctime; __uint32_t level; __uint32_t size; __uint32_t nr_disks; __uint32_t raid_disks; __uint32_t md_minor; __uint32_t not_persistent; /* * Generic state information */ __uint32_t utime; /* 0 Superblock update time */ __uint32_t state; /* 1 State bits (clean, ...) */ __uint32_t active_disks; /* 2 Number of currently active disks */ __uint32_t working_disks; /* 3 Number of working disks */ __uint32_t failed_disks; /* 4 Number of failed disks */ __uint32_t spare_disks; /* 5 Number of spare disks */ /* * Personality information */ __uint32_t layout; /* 0 the array's physical layout */ __uint32_t chunk_size; /* 1 chunk size in bytes */ }; /* * MDP = partitionable RAID arrays */ enum md_type { MD_TYPE_MD, MD_TYPE_MDP }; xfsprogs-3.1.9ubuntu2/libdisk/xvm.c0000664000000000000000000000437111140033220014202 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include "xvm.h" int mnt_is_xvm_subvol( dev_t dev) { return get_driver_block_major("xvm", major(dev)); } /* * If the logical device is a xvm striped volume, then it returns the * stripe unit and stripe width information. * Input parameters: the logical volume * the subvolume type - (SVTYPE_RT or * SVTYPE_DATA) * Output parameters: the stripe unit and width in 512 byte blocks * true/false - was this device an XVM volume? */ int xvm_get_subvol_stripe( char *dev, sv_type_t type, int *sunit, int *swidth, int *sectalign, struct stat64 *sb) { int fd; xvm_getdev_t getdev; xvm_subvol_stripe_t subvol_stripe; if (!mnt_is_xvm_subvol(sb->st_rdev)) return 0; /* * This will actually open the data subvolume. */ if ((fd = open(dev, O_RDONLY)) < 0) return 0; /* * Go and get the the information for the correct * subvolume. */ if (ioctl(fd, DIOCGETVOLDEV, &getdev) < 0) { close(fd); return 0; } if ( (type == SVTYPE_RT) && (getdev.rt_subvol_dev) ) subvol_stripe.dev = getdev.rt_subvol_dev; else if ( (type == SVTYPE_DATA) && (getdev.data_subvol_dev) ) subvol_stripe.dev = getdev.data_subvol_dev; else { close(fd); return 0; } if (ioctl(fd, DIOCGETVOLSTRIPE, &subvol_stripe) < 0) { close(fd); return 0; } *sunit = subvol_stripe.unit_size; *swidth = *sunit * subvol_stripe.width_size; *sectalign = 0; close(fd); return 1; } xfsprogs-3.1.9ubuntu2/libdisk/evms.h0000664000000000000000000000232011140033220014337 0ustar /* * Copyright (c) International Business Machines Corp., 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define EVMS_MAJOR 117 #define EVMS_GET_VOL_STRIPE_INFO \ _IOR(EVMS_MAJOR, 0xF0, struct evms_vol_stripe_info_s) /* * struct evms_vol_stripe_info_s - contains stripe information for a volume * * unit: the stripe unit specified in 512 byte block units * width: the number of stripe members or RAID data disks */ typedef struct evms_vol_stripe_info_s { u_int32_t size; u_int32_t width; } evms_vol_stripe_info_t; xfsprogs-3.1.9ubuntu2/libdisk/pttype.h0000664000000000000000000000310011140033220014707 0ustar typedef struct { unsigned char info[128]; /* Informative text string */ unsigned char spare0[14]; struct sun_info { unsigned char spare1; unsigned char id; unsigned char spare2; unsigned char flags; } infos[8]; unsigned char spare1[246]; /* Boot information etc. */ unsigned short rspeed; /* Disk rotational speed */ unsigned short pcylcount; /* Physical cylinder count */ unsigned short sparecyl; /* extra sects per cylinder */ unsigned char spare2[4]; /* More magic... */ unsigned short ilfact; /* Interleave factor */ unsigned short ncyl; /* Data cylinder count */ unsigned short nacyl; /* Alt. cylinder count */ unsigned short ntrks; /* Tracks per cylinder */ unsigned short nsect; /* Sectors per track */ unsigned char spare3[4]; /* Even more magic... */ struct sun_partition { u_int32_t start_cylinder; u_int32_t num_sectors; } partitions[8]; unsigned short magic; /* Magic number */ unsigned short csum; /* Label xor'd checksum */ } sun_partition; #define SUN_LABEL_MAGIC 0xDABE #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA #define sunlabel(x) ((sun_partition *)x) typedef struct { unsigned int magic; /* expect AIX_LABEL_MAGIC */ /* ... */ } aix_partition; #define AIX_LABEL_MAGIC 0xc9c2d4c1 #define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9 #define aixlabel(x) ((aix_partition *)x) typedef struct { unsigned short magic; /* ... */ } mac_partition; #define MAC_LABEL_MAGIC 0x4552 #define MAC_PARTITION_MAGIC 0x504d #define MAC_OLD_PARTITION_MAGIC 0x5453 #define maclabel(x) ((mac_partition *)x) xfsprogs-3.1.9ubuntu2/libdisk/evms.c0000664000000000000000000000311711140033220014337 0ustar /* * Copyright (c) International Business Machines Corp., 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include "evms.h" int mnt_is_evms_subvol( dev_t dev) { if (major(dev) == EVMS_MAJOR) return 1; return get_driver_block_major("evms", major(dev)); } int evms_get_subvol_stripe( char *device, sv_type_t type, int *sunit, int *swidth, int *sectalign, struct stat64 *sb) { if (mnt_is_evms_subvol(sb->st_rdev)) { evms_vol_stripe_info_t info; int fd; fd = open(device, O_RDONLY); if (fd == -1) return 0; if (ioctl(fd, EVMS_GET_VOL_STRIPE_INFO, &info)) { close(fd); return 0; } /* Update sizes */ *sunit = info.size; *swidth = *sunit * info.width; *sectalign = 0; close(fd); return 1; } return 0; } xfsprogs-3.1.9ubuntu2/libdisk/fstype.c0000664000000000000000000003162711330256617014730 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "fstype.h" /* * From mount(8) source by Andries Brouwer. Hacked for XFS by mkp. * Recent sync's to mount source: * - util-linux-2.10o ... 06 Sep 00 * - util-linux-2.10r ... 06 Dec 00 * - util-linux-2.11g ... 02 Jul 01 * - util-linux-2.11u ... 24 Aug 02 * - util-linux-2.11z ... 13 May 03 */ #define SIZE(a) (sizeof(a)/sizeof(a[0])) /* Most file system types can be recognized by a `magic' number in the superblock. Note that the order of the tests is significant: by coincidence a filesystem can have the magic numbers for several file system types simultaneously. For example, the romfs magic lives in the 1st sector; xiafs does not touch the 1st sector and has its magic in the 2nd sector; ext2 does not touch the first two sectors. */ static inline unsigned short swapped(unsigned short a) { return (a>>8) | (a<<8); } /* Probes the device and attempts to determine the type of filesystem contained within. Original routine by ; made into a function for mount(8) by Mike Grupenhoff . Corrected the test for xiafs - aeb Read the superblock only once - aeb Added a very weak heuristic for vfat - aeb Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb Added a test for high sierra (iso9660) - quinlan@bucknell.edu Added ufs from a patch by jj. But maybe there are several types of ufs? Added ntfs from a patch by Richard Russon. Added xfs - 2000-03-21 Martin K. Petersen Added cramfs, hfs, hpfs, adfs - Sepp Wijnands Added ext3 - Andrew Morton Added jfs - Christoph Hellwig Added sysv - Tim Launchbury Added udf - Bryce Nesbitt Added gfs/gfs2, btrfs - Eric Sandeen */ /* * udf magic - I find that trying to mount garbage as an udf fs * causes a very large kernel delay, almost killing the machine. * So, we do not try udf unless there is positive evidence that it * might work. Strings below taken from ECMA 167. */ /* * It seems that before udf 2.00 the volume descriptor was not well * defined. For 2.00 you're supposed to keep scanning records until * you find one NOT in this list. (See ECMA 2/8.3.1). */ static char *udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02", "NSR03", "TEA01" }; static int may_be_udf(const char *id) { char **m; for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++) if (!strncmp(*m, id, 5)) return 1; return 0; } /* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */ static int is_really_udf(int fd) { int j, bs; struct iso_volume_descriptor isosb; /* determine the block size by scanning in 2K increments (block sizes larger than 2K will be null padded) */ for (bs = 1; bs < 16; bs++) { lseek(fd, bs*2048+32768, SEEK_SET); if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) return 0; if (isosb.id[0]) break; } /* Scan up to another 64 blocks looking for additional VSD's */ for (j = 1; j < 64; j++) { if (j > 1) { lseek(fd, j*bs*2048+32768, SEEK_SET); if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) return 0; } /* If we find NSR0x then call it udf: NSR01 for UDF 1.00 NSR02 for UDF 1.50 NSR03 for UDF 2.00 */ if (!strncmp(isosb.id, "NSR0", 4)) return 1; if (!may_be_udf(isosb.id)) return 0; } return 0; } static int may_be_swap(const char *s) { return (strncmp(s-10, "SWAP-SPACE", 10) == 0 || strncmp(s-10, "SWAPSPACE2", 10) == 0); } /* rather weak necessary condition */ static int may_be_adfs(const struct adfs_super_block *sb) { char *p; int sum; p = (char *)sb->s_checksum; sum = 0; while(--p != (char *)sb) sum = (sum >> 8) + (sum & 0xff) + *p; return (sum & 0xff) == sb->s_checksum[0]; } static int is_reiserfs_magic_string (struct reiserfs_super_block * rs) { return (!strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) || !strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING))); } char * fstype(const char *device) { int fd; char *type = NULL; union { struct minix_super_block ms; struct ext_super_block es; struct ext2_super_block e2s; struct vxfs_super_block vs; struct hfs_super_block hs; } sb; /* stuff at 1024 */ union { struct xiafs_super_block xiasb; char romfs_magic[8]; char qnx4fs_magic[10]; /* ignore first 4 bytes */ unsigned int bfs_magic; struct ntfs_super_block ntfssb; struct fat_super_block fatsb; struct xfs_super_block xfsb; struct cramfs_super_block cramfssb; } xsb; struct ufs_super_block ufssb; union { struct iso_volume_descriptor iso; struct hs_volume_descriptor hs; } isosb; struct reiserfs_super_block reiserfssb; /* block 64 or 8 */ struct jfs_super_block jfssb; /* block 32 */ struct hpfs_super_block hpfssb; struct adfs_super_block adfssb; struct sysv_super_block svsb; struct gfs2_sb gfs2sb; struct btrfs_super_block btrfssb; struct stat statbuf; /* opening and reading an arbitrary unknown path can have undesired side effects - first check that `device' refers to a block device or ordinary file */ if (stat (device, &statbuf) || !(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode))) return NULL; fd = open(device, O_RDONLY); if (fd < 0) return NULL; /* do seeks and reads in disk order, otherwise a very short partition may cause a failure because of read error */ if (!type) { /* block 0 */ if (lseek(fd, 0, SEEK_SET) != 0 || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb)) goto try_iso9660; /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */ if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC) type = "xiafs"; else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8)) type = "romfs"; else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4)) type = "xfs"; else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6)) type = "qnx4"; else if(xsb.bfs_magic == 0x1badface) type = "bfs"; else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC, sizeof(xsb.ntfssb.s_magic))) type = "ntfs"; else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC || cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE) type = "cramfs"; else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) || !strncmp(xsb.fatsb.s_os, "MSWIN", 5) || !strncmp(xsb.fatsb.s_os, "MTOOL", 5) || !strncmp(xsb.fatsb.s_os, "mkdosfs", 7) || !strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) || /* Michal Svec: created by fdformat, old msdos utility for formatting large (1.7) floppy disks. */ !strncmp(xsb.fatsb.s_os, "CH-FOR18", 8)) && (!strncmp(xsb.fatsb.s_fs, "FAT12 ", 8) || !strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) || !strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8))) type = "vfat"; /* only guessing - might as well be fat or umsdos */ } if (!type) { /* sector 1 */ if (lseek(fd, 512 , SEEK_SET) != 512 || read(fd, (char *) &svsb, sizeof(svsb)) != sizeof(svsb)) goto io_error; if (sysvmagic(svsb) == SYSV_SUPER_MAGIC ) type = "sysv"; } if (!type) { /* block 1 */ if (lseek(fd, 1024, SEEK_SET) != 1024 || read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb)) goto io_error; /* ext2 has magic in little-endian on disk, so "swapped" is superfluous; however, there have existed strange byteswapped PPC ext2 systems */ if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC || ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC || ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC)) { type = "ext2"; /* maybe even ext3? */ if ((assemble4le(sb.e2s.s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && assemble4le(sb.e2s.s_journal_inum) != 0) type = "ext3"; /* "ext3,ext2" */ } else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC || minixmagic(sb.ms) == MINIX_SUPER_MAGIC2 || minixmagic(sb.ms) == swapped(MINIX_SUPER_MAGIC2) || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC2) type = "minix"; else if (extmagic(sb.es) == EXT_SUPER_MAGIC) type = "ext"; else if (vxfsmagic(sb.vs) == VXFS_SUPER_MAGIC) type = "vxfs"; else if (hfsmagic(sb.hs) == swapped(HFS_SUPER_MAGIC) || (hfsmagic(sb.hs) == swapped(HFSPLUS_SUPER_MAGIC) && hfsversion(sb.hs) == swapped(HFSPLUS_SUPER_VERSION))) type = "hfs"; } if (!type) { /* block 3 */ if (lseek(fd, 0xc00, SEEK_SET) != 0xc00 || read(fd, (char *) &adfssb, sizeof(adfssb)) != sizeof(adfssb)) goto io_error; /* only a weak test */ if (may_be_adfs(&adfssb) && (adfsblksize(adfssb) >= 8 && adfsblksize(adfssb) <= 10)) type = "adfs"; } if (!type) { int mag; /* block 8 */ if (lseek(fd, 8192, SEEK_SET) != 8192 || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb)) goto io_error; mag = ufsmagic(ufssb); if (mag == UFS_SUPER_MAGIC_LE || mag == UFS_SUPER_MAGIC_BE) type = "ufs"; } if (!type) { /* block 8 */ if (lseek(fd, REISERFS_OLD_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_OLD_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (is_reiserfs_magic_string(&reiserfssb)) type = "reiserfs"; } if (!type) { /* block 8 */ if (lseek(fd, 0x2000, SEEK_SET) != 0x2000 || read(fd, (char *) &hpfssb, sizeof(hpfssb)) != sizeof(hpfssb)) goto io_error; if (hpfsmagic(hpfssb) == HPFS_SUPER_MAGIC) type = "hpfs"; } if (!type) { /* block 32 */ if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) != JFS_SUPER1_OFF || read(fd, (char *) &jfssb, sizeof(jfssb)) != sizeof(jfssb)) goto io_error; if (!strncmp(jfssb.s_magic, JFS_MAGIC, 4)) type = "jfs"; } if (!type) { /* block 32 */ try_iso9660: if (lseek(fd, 0x8000, SEEK_SET) != 0x8000 || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb)) goto io_error; if (strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) { /* "CDROM" */ type = "iso9660"; } else if (strncmp(isosb.iso.id, ISO_STANDARD_ID, sizeof(isosb.iso.id)) == 0) { /* CD001 */ type = "iso9660"; if (is_really_udf(fd)) type = "udf"; } else if (may_be_udf(isosb.iso.id)) type = "udf"; } if (!type) { /* block 64 */ if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (is_reiserfs_magic_string(&reiserfssb)) type = "reiserfs"; } if (!type) { /* block 64 */ if (lseek(fd, GFS_SUPERBLOCK_OFFSET, SEEK_SET) != GFS_SUPERBLOCK_OFFSET || read(fd, (char *) &gfs2sb, sizeof(gfs2sb)) != sizeof(gfs2sb)) goto io_error; if (gfsmagic(gfs2sb)) { if (gfsformat(gfs2sb) == GFS_FORMAT_FS && gfsmultiformat(gfs2sb) == GFS_FORMAT_MULTI) type = "gfs"; else if (gfsformat(gfs2sb) == GFS2_FORMAT_FS && gfsmultiformat(gfs2sb) == GFS2_FORMAT_MULTI) type = "gfs2"; } } if (!type) { /* block 64 */ if (lseek(fd, BTRFS_SUPER_INFO_OFFSET, SEEK_SET) != BTRFS_SUPER_INFO_OFFSET || read(fd, (char *) &btrfssb, sizeof(btrfssb)) != sizeof(btrfssb)) goto io_error; if (!strncmp((char *)(btrfssb.magic), BTRFS_MAGIC, sizeof(btrfssb.magic))) { type = "btrfs"; } } if (!type) { /* perhaps the user tries to mount the swap space on a new disk; warn her before she does mkfs on it */ int pagesize = getpagesize(); int rd; char buf[128 * 1024]; /* 64k is current max pagesize */ if (pagesize > sizeof(buf)) abort(); rd = pagesize; if (rd < 8192) rd = 8192; if (rd > sizeof(buf)) rd = sizeof(buf); if (lseek(fd, 0, SEEK_SET) != 0 || read(fd, buf, rd) != rd) goto io_error; if (may_be_swap(buf+pagesize) || may_be_swap(buf+4096) || may_be_swap(buf+8192)) type = "swap"; } close (fd); return(type); io_error: close(fd); return NULL; } xfsprogs-3.1.9ubuntu2/libdisk/fstype.h0000664000000000000000000002200711140033220014703 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #undef XFS_SUPER_MAGIC /* * From mount(8) source by Andries Brouwer. Hacked for XFS by mkp. * Recent sync's to mount source: * - util-linux-2.10o ... 06 Sep 00 * - util-linux-2.10r ... 06 Dec 00 * - util-linux-2.11g ... 02 Jul 01 * - util-linux-2.11u ... 24 Aug 02 * - util-linux-2.11z ... 13 May 03 */ /* Including became more and more painful. Below a very abbreviated version of some declarations, only designed to be able to check a magic number in case no filesystem type was given. */ #define MINIX_SUPER_MAGIC 0x137F /* minix v1, 14 char names */ #define MINIX_SUPER_MAGIC2 0x138F /* minix v1, 30 char names */ #define MINIX2_SUPER_MAGIC 0x2468 /* minix v2, 14 char names */ #define MINIX2_SUPER_MAGIC2 0x2478 /* minix v2, 30 char names */ struct minix_super_block { char s_dummy[16]; char s_magic[2]; }; #define minixmagic(s) assemble2le(s.s_magic) #define ISODCL(from, to) (to - from + 1) #define ISO_STANDARD_ID "CD001" struct iso_volume_descriptor { char type[ISODCL(1,1)]; /* 711 */ char id[ISODCL(2,6)]; char version[ISODCL(7,7)]; char data[ISODCL(8,2048)]; }; #define HS_STANDARD_ID "CDROM" struct hs_volume_descriptor { char foo[ISODCL ( 1, 8)]; /* 733 */ char type[ISODCL ( 9, 9)]; /* 711 */ char id[ISODCL ( 10, 14)]; char version[ISODCL ( 15, 15)]; /* 711 */ char data[ISODCL(16,2048)]; }; #define EXT_SUPER_MAGIC 0x137D struct ext_super_block { char s_dummy[56]; char s_magic[2]; }; #define extmagic(s) assemble2le(s.s_magic) #define EXT2_PRE_02B_MAGIC 0xEF51 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 struct ext2_super_block { char s_dummy1[56]; char s_magic[2]; char s_dummy2[34]; char s_feature_compat[4]; char s_feature_incompat[4]; char s_feature_ro_compat[4]; char s_uuid[16]; char s_volume_name[16]; char s_dummy3[88]; char s_journal_inum[4]; /* ext3 only */ }; #define ext2magic(s) assemble2le(s.s_magic) struct reiserfs_super_block { char s_block_count[4]; char s_free_blocks[4]; char s_root_block[4]; char s_journal_block[4]; char s_journal_dev[4]; char s_orig_journal_size[4]; char s_journal_trans_max[4]; char s_journal_block_count[4]; char s_journal_max_batch[4]; char s_journal_max_commit_age[4]; char s_journal_max_trans_age[4]; char s_blocksize[2]; char s_oid_maxsize[2]; char s_oid_cursize[2]; char s_state[2]; char s_magic[12]; }; #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024) /* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */ #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024) #define _XIAFS_SUPER_MAGIC 0x012FD16D struct xiafs_super_block { char s_boot_segment[512]; /* 1st sector reserved for boot */ char s_dummy[60]; char s_magic[4]; }; #define xiafsmagic(s) assemble4le(s.s_magic) /* From jj@sunsite.ms.mff.cuni.cz Mon Mar 23 15:19:05 1998 */ #define UFS_SUPER_MAGIC_LE 0x00011954 #define UFS_SUPER_MAGIC_BE 0x54190100 struct ufs_super_block { char s_dummy[0x55c]; char s_magic[4]; }; #define ufsmagic(s) assemble4le(s.s_magic) /* From Richard.Russon@ait.co.uk Wed Feb 24 08:05:27 1999 */ #define NTFS_SUPER_MAGIC "NTFS" struct ntfs_super_block { char s_dummy[3]; char s_magic[4]; }; /* From inspection of a few FAT filesystems - aeb */ /* Unfortunately I find almost the same thing on an extended partition; it looks like a primary has some directory entries where the extended has a partition table: IO.SYS, MSDOS.SYS, WINBOOT.SYS */ struct fat_super_block { char s_dummy[3]; char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */ /* mtools-3.9.4 writes "MTOOL394" */ char s_dummy2[32]; char s_label[11]; /* for DOS? */ char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */ /* OS/2 BM has "FAT " here. */ char s_dummy3[9]; char s_label2[11]; /* for Windows? */ char s_fs2[8]; /* garbage or "FAT32 " */ }; #define XFS_SUPER_MAGIC "XFSB" struct xfs_super_block { char s_magic[4]; char s_dummy[28]; char s_uuid[16]; char s_dummy2[60]; char s_fname[12]; }; #define CRAMFS_SUPER_MAGIC 0x28cd3d45 #define CRAMFS_SUPER_MAGIC_BE 0x453dcd28 struct cramfs_super_block { char s_magic[4]; char s_dummy[12]; char s_id[16]; }; #define cramfsmagic(s) assemble4le(s.s_magic) #define HFS_SUPER_MAGIC 0x4244 #define HFSPLUS_SUPER_MAGIC 0x482B #define HFSPLUS_SUPER_VERSION 0x004 struct hfs_super_block { char s_magic[2]; char s_version[2]; }; #define hfsmagic(s) assemble2le(s.s_magic) #define hfsversion(s) assemble2le(s.s_version) #define HPFS_SUPER_MAGIC 0xf995e849 struct hpfs_super_block { char s_magic[4]; char s_magic2[4]; }; #define hpfsmagic(s) assemble4le(s.s_magic) struct adfs_super_block { char s_dummy[448]; char s_blksize[1]; char s_dummy2[62]; char s_checksum[1]; }; #define adfsblksize(s) ((uint) s.s_blksize[0]) /* found in first 4 bytes of block 1 */ struct vxfs_super_block { char s_magic[4]; }; #define vxfsmagic(s) assemble4le(s.s_magic) #define VXFS_SUPER_MAGIC 0xa501FCF5 struct jfs_super_block { char s_magic[4]; char s_version[4]; char s_dummy1[93]; char s_fpack[11]; char s_dummy2[24]; char s_uuid[16]; char s_label[16]; }; #define JFS_SUPER1_OFF 0x8000 #define JFS_MAGIC "JFS1" struct sysv_super_block { char s_dummy1[504]; char s_magic[4]; char type[4]; }; #define sysvmagic(s) assemble4le(s.s_magic) #define SYSV_SUPER_MAGIC 0xfd187e20 struct mdp_super_block { char md_magic[4]; }; #define MD_SB_MAGIC 0xa92b4efc #define mdsbmagic(s) assemble4le(s.md_magic) struct ocfs_volume_header { char minor_version[4]; char major_version[4]; char signature[128]; }; struct ocfs_volume_label { char disk_lock[48]; char label[64]; char label_len[2]; }; #define ocfslabellen(o) assemble2le(o.label_len) #define OCFS_MAGIC "OracleCFS" /* Common gfs/gfs2 constants: */ #define GFS_MAGIC 0x01161970 #define GFS_DEFAULT_BSIZE 4096 #define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE) #define GFS_LOCKNAME_LEN 64 /* gfs1 constants: */ #define GFS_FORMAT_FS 1309 #define GFS_FORMAT_MULTI 1401 /* gfs2 constants: */ #define GFS2_FORMAT_FS 1801 #define GFS2_FORMAT_MULTI 1900 struct gfs2_meta_header { char mh_magic[4]; char mh_type[4]; char __pad0[8]; /* Was generation number in gfs1 */ char mh_format[4]; char __pad1[4]; /* Was incarnation number in gfs1 */ }; struct gfs2_inum { char no_formal_ino[8]; char no_addr[8]; }; struct gfs2_sb { struct gfs2_meta_header sb_header; char sb_fs_format[4]; char sb_multihost_format[4]; char __pad0[4]; /* Was superblock flags in gfs1 */ char sb_bsize[4]; char sb_bsize_shift[4]; char __pad1[4]; /* Was journal segment size in gfs1 */ struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */ struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */ struct gfs2_inum sb_root_dir; char sb_lockproto[GFS_LOCKNAME_LEN]; char sb_locktable[GFS_LOCKNAME_LEN]; /* In gfs1, quota and license dinodes followed */ }; #define gfsmagic(s) assemble4be(s.sb_header.mh_magic) #define gfsformat(s) assemble4be(s.sb_fs_format) #define gfsmultiformat(s) assemble4be(s.sb_multihost_format) /* btrfs constants */ #define BTRFS_SUPER_INFO_OFFSET (64 * 1024) /* 32 bytes in various csum fields */ #define BTRFS_CSUM_SIZE 32 #define BTRFS_FSID_SIZE 16 #define BTRFS_MAGIC "_BHRfS_M" /* * the super block basically lists the main trees of the FS * it currently lacks any block count etc etc */ struct btrfs_super_block { char csum[BTRFS_CSUM_SIZE]; /* the first 3 fields must match struct btrfs_header */ char fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ char bytenr[8]; /* this block number */ char flags[8]; /* allowed to be different from the btrfs_header from here own down */ char magic[8]; /* more follows but this is all our libdisk cares about*/ } __attribute__ ((__packed__)); static inline int assemble2le(char *p) { return (p[0] | (p[1] << 8)); } static inline int assemble4le(char *p) { return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); } static inline int assemble4be(char *p) { return (p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24)); } xfsprogs-3.1.9ubuntu2/libdisk/md.c0000664000000000000000000000503011140033220013761 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "drivers.h" #include "md.h" int mnt_is_md_subvol( dev_t dev, enum md_type *type) { *type = MD_TYPE_MD; if (major(dev) == MD_MAJOR) return 1; if (get_driver_block_major("md", major(dev))) return 1; *type = MD_TYPE_MDP; if (get_driver_block_major("mdp", major(dev))) return 1; return 0; } int md_get_subvol_stripe( char *dfile, sv_type_t type, int *sunit, int *swidth, int *sectalign, struct stat64 *sb) { char *pc; char *dfile2 = NULL; enum md_type md_type; if (mnt_is_md_subvol(sb->st_rdev, &md_type)) { struct md_array_info md; int fd; if (md_type == MD_TYPE_MDP) { pc = strrchr(dfile, 'd'); if (pc) pc = strchr(pc, 'p'); if (!pc) { fprintf(stderr, _("Error getting MD array device from %s\n"), dfile); exit(1); } dfile2 = malloc(pc - dfile + 1); if (dfile2 == NULL) { fprintf(stderr, _("Couldn't malloc device string\n")); exit(1); } strncpy(dfile2, dfile, pc - dfile); dfile2[pc - dfile + 1] = '\0'; } /* Open device */ fd = open(dfile2 ? dfile2 : dfile, O_RDONLY); if (fd == -1) { free(dfile2); return 0; } /* Is this thing on... */ if (ioctl(fd, GET_ARRAY_INFO, &md)) { fprintf(stderr, _("Error getting MD array info from %s\n"), dfile2 ? dfile2 : dfile); exit(1); } close(fd); free(dfile2); /* * Ignore levels we don't want aligned (e.g. linear) * and deduct disk(s) from stripe width on RAID4/5/6 */ switch (md.level) { case 6: md.raid_disks--; /* fallthrough */ case 5: case 4: md.raid_disks--; /* fallthrough */ case 1: case 0: case 10: break; default: return 0; } /* Update sizes */ *sunit = md.chunk_size >> 9; *swidth = *sunit * md.raid_disks; *sectalign = (md.level == 4 || md.level == 5 || md.level == 6); return 1; } return 0; } xfsprogs-3.1.9ubuntu2/libdisk/xvm.h0000664000000000000000000000322511140033220014204 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define _DIOC_(x) (('d'<<8) | x) #define DIOCGETVOLDEV _DIOC_(36) /* subvolume devices */ #define DIOCGETVOLSTRIPE _DIOC_(47) /* subvolume stripe info */ /* * Structure returned by the DIOCGETVOLDEV ioctl to list the * subvolume device nodes in a volume. These are external device * numbers. */ #define XVM_GETDEV_VERS 1 typedef __uint32_t xvm_dev_t; typedef struct { __uint32_t version; xvm_dev_t data_subvol_dev; xvm_dev_t log_subvol_dev; xvm_dev_t rt_subvol_dev; xvm_dev_t sp_subvol_dev; } xvm_getdev_t; /* * Structure returned by the DIOCGETVOLSTRIPE ioctl to describe * the subvolume stripe units and width. */ #define XVM_SUBVOL_GEOMETRY_VERS 1 typedef struct xvm_subvol_stripe_s { __uint32_t version; __uint32_t unit_size; /* in blocks */ __uint32_t width_size; /* in blocks */ __uint32_t pad1; /* padding */ xvm_dev_t dev; } xvm_subvol_stripe_t; xfsprogs-3.1.9ubuntu2/libdisk/lvm.c0000664000000000000000000000511711140033220014165 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "drivers.h" #ifndef LVM_BLK_MAJOR #define LVM_BLK_MAJOR 58 #endif int mnt_is_lvm_subvol( dev_t dev) { if (major(dev) == LVM_BLK_MAJOR) return 1; return get_driver_block_major("lvm", major(dev)); } int lvm_get_subvol_stripe( char *dfile, sv_type_t type, int *sunit, int *swidth, int *sectalign, struct stat64 *sb) { int lvpipe[2], stripes = 0, stripesize = 0; char *largv[3], buf[1024]; FILE *stream; char tmppath[MAXPATHLEN]; if (!mnt_is_lvm_subvol(sb->st_rdev)) return 0; /* Quest for lvdisplay */ if (!access("/usr/local/sbin/lvdisplay", R_OK|X_OK)) largv[0] = "/usr/local/sbin/lvdisplay"; else if (!access("/usr/sbin/lvdisplay", R_OK|X_OK)) largv[0] = "/usr/sbin/lvdisplay"; else if (!access("/sbin/lvdisplay", R_OK|X_OK)) largv[0] = "/sbin/lvdisplay"; else { fprintf(stderr, _("Warning - LVM device, but no lvdisplay(8) found\n")); return 0; } /* realpath gives an absolute pathname */ largv[1] = realpath(dfile, tmppath); largv[2] = NULL; /* Open pipe */ if (pipe(lvpipe) < 0) { fprintf(stderr, _("Could not open pipe\n")); exit(1); } /* Spawn lvdisplay */ switch (fork()) { case 0: /* Plumbing */ close(lvpipe[0]); if (lvpipe[1] != STDOUT_FILENO) dup2(lvpipe[1], STDOUT_FILENO); execv(largv[0], largv); fprintf(stderr, _("Failed to execute %s\n"), largv[0]); exit(1); case -1: fprintf(stderr, _("Failed forking lvdisplay process\n")); exit(1); default: break; } close(lvpipe[1]); stream = fdopen(lvpipe[0], "r"); /* Scan stream for keywords */ while (fgets(buf, 1023, stream) != NULL) { if (!strncmp(buf, "Stripes", 7)) sscanf(buf, "Stripes %d", &stripes); if (!strncmp(buf, "Stripe size", 11)) sscanf(buf, "Stripe size (KByte) %d", &stripesize); } /* Update sizes */ *sunit = stripesize << 1; *swidth = (stripes * stripesize) << 1; *sectalign = 0; fclose(stream); return 1; } xfsprogs-3.1.9ubuntu2/fsr/0000775000000000000000000000000012062211564012405 5ustar xfsprogs-3.1.9ubuntu2/fsr/Makefile0000664000000000000000000000056611330256617014061 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_fsr CFILES = xfs_fsr.c LLDLIBS = $(LIBHANDLE) default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/fsr/xfs_fsr.c0000664000000000000000000012060112062210562014220 0ustar /* * Copyright (c) 2000-2002 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef XFS_XFLAG_NODEFRAG #define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */ #endif #define _PATH_FSRLAST "/var/tmp/.fsrlast_xfs" #define _PATH_PROC_MOUNTS "/proc/mounts" char *progname; int vflag; int gflag; static int Mflag; /* static int nflag; */ int dflag = 0; /* static int sflag; */ int argv_blksz_dio; extern int max_ext_size; static int npasses = 10; static int startpass = 0; struct getbmap *outmap = NULL; int outmap_size = 0; int RealUid; int tmp_agi; static __int64_t minimumfree = 2048; #define MNTTYPE_XFS "xfs" #define SMBUFSZ 1024 #define ROOT 0 #define NULLFD -1 #define GRABSZ 64 #define TARGETRANGE 10 #define V_NONE 0 #define V_OVERVIEW 1 #define V_ALL 2 #define BUFFER_SIZE (1<<16) #define BUFFER_MAX (1<<24) #define min(x, y) ((x) < (y) ? (x) : (y)) static time_t howlong = 7200; /* default seconds of reorganizing */ static char *leftofffile = _PATH_FSRLAST; /* where we left off last */ static time_t endtime; static time_t starttime; static xfs_ino_t leftoffino = 0; static int pagesize; void usage(int ret); static int fsrfile(char *fname, xfs_ino_t ino); static int fsrfile_common( char *fname, char *tname, char *mnt, int fd, xfs_bstat_t *statp); static int packfile(char *fname, char *tname, int fd, xfs_bstat_t *statp, struct fsxattr *fsxp); static void fsrdir(char *dirname); static int fsrfs(char *mntdir, xfs_ino_t ino, int targetrange); static void initallfs(char *mtab); static void fsrallfs(char *mtab, int howlong, char *leftofffile); static void fsrall_cleanup(int timeout); static int getnextents(int); int xfsrtextsize(int fd); int xfs_getrt(int fd, struct statvfs64 *sfbp); char * gettmpname(char *fname); char * getparent(char *fname); int fsrprintf(const char *fmt, ...); int read_fd_bmap(int, xfs_bstat_t *, int *); int cmp(const void *, const void *); static void tmp_init(char *mnt); static char * tmp_next(char *mnt); static void tmp_close(char *mnt); int xfs_getgeom(int , xfs_fsop_geom_v1_t * ); xfs_fsop_geom_v1_t fsgeom; /* geometry of active mounted system */ #define NMOUNT 64 static int numfs; typedef struct fsdesc { char *dev; char *mnt; int npass; } fsdesc_t; fsdesc_t *fs, *fsbase, *fsend; int fsbufsize = 10; /* A starting value */ int nfrags = 0; /* Debug option: Coerse into specific number * of extents */ int openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT; int xfs_fsgeometry(int fd, xfs_fsop_geom_v1_t *geom) { return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, geom); } int xfs_bulkstat_single(int fd, xfs_ino_t *lastip, xfs_bstat_t *ubuffer) { xfs_fsop_bulkreq_t bulkreq; bulkreq.lastip = (__u64 *)lastip; bulkreq.icount = 1; bulkreq.ubuffer = ubuffer; bulkreq.ocount = NULL; return ioctl(fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq); } int xfs_bulkstat(int fd, xfs_ino_t *lastip, int icount, xfs_bstat_t *ubuffer, __s32 *ocount) { xfs_fsop_bulkreq_t bulkreq; bulkreq.lastip = (__u64 *)lastip; bulkreq.icount = icount; bulkreq.ubuffer = ubuffer; bulkreq.ocount = ocount; return ioctl(fd, XFS_IOC_FSBULKSTAT, &bulkreq); } int xfs_swapext(int fd, xfs_swapext_t *sx) { return ioctl(fd, XFS_IOC_SWAPEXT, sx); } int xfs_fscounts(int fd, xfs_fsop_counts_t *counts) { return ioctl(fd, XFS_IOC_FSCOUNTS, counts); } void aborter(int unused) { fsrall_cleanup(1); exit(1); } /* * Check if the argument is either the device name or mountpoint of an XFS * filesystem. Note that we do not care about bind mounted regular files * here - the code that handles defragmentation of invidual files takes care * of that. */ static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) { struct mntent *t; struct stat64 ms; FILE *mtabp; char *mntp = NULL; mtabp = setmntent(mtab, "r"); if (!mtabp) { fprintf(stderr, _("%s: cannot read %s\n"), progname, mtab); exit(1); } while ((t = getmntent(mtabp))) { if (S_ISDIR(sb->st_mode)) { /* mount point */ if (stat64(t->mnt_dir, &ms) < 0) continue; if (sb->st_ino != ms.st_ino) continue; if (sb->st_dev != ms.st_dev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) continue; } else { /* device */ struct stat64 sb2; if (stat64(t->mnt_fsname, &ms) < 0) continue; if (sb->st_rdev != ms.st_rdev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) continue; /* * Make sure the mountpoint given by mtab is accessible * before using it. */ if (stat64(t->mnt_dir, &sb2) < 0) continue; } mntp = t->mnt_dir; break; } endmntent(mtabp); return mntp; } int main(int argc, char **argv) { struct stat64 sb; char *argname; int c; char *mntp; char *mtab = NULL; setlinebuf(stdout); progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); gflag = ! isatty(0); while ((c = getopt(argc, argv, "C:p:e:MgsdnvTt:f:m:b:N:FV")) != -1) { switch (c) { case 'M': Mflag = 1; break; case 'g': gflag = 1; break; case 'n': /* nflag = 1; */ break; case 'v': ++vflag; break; case 'd': dflag = 1; break; case 's': /* frag stats only */ /* sflag = 1; */ fprintf(stderr, _("%s: Stats not yet supported for XFS\n"), progname); usage(1); break; case 't': howlong = atoi(optarg); break; case 'f': leftofffile = optarg; break; case 'm': mtab = optarg; break; case 'b': argv_blksz_dio = atoi(optarg); break; case 'p': npasses = atoi(optarg); break; case 'C': /* Testing opt: coerses frag count in result */ if (getenv("FSRXFSTEST") != NULL) { nfrags = atoi(optarg); openopts |= O_SYNC; } break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); default: usage(1); } } /* * If the user did not specify an explicit mount table, try to use * /proc/mounts if it is available, else /etc/mtab. We prefer * /proc/mounts because it is kernel controlled, while /etc/mtab * may contain garbage that userspace tools like pam_mounts wrote * into it. */ if (!mtab) { if (access(_PATH_PROC_MOUNTS, R_OK) == 0) mtab = _PATH_PROC_MOUNTS; else mtab = _PATH_MOUNTED; } if (vflag) setbuf(stdout, NULL); starttime = time(0); /* Save the caller's real uid */ RealUid = getuid(); pagesize = getpagesize(); if (optind < argc) { for (; optind < argc; optind++) { argname = argv[optind]; if (lstat64(argname, &sb) < 0) { fprintf(stderr, _("%s: could not stat: %s: %s\n"), progname, argname, strerror(errno)); continue; } if (S_ISLNK(sb.st_mode)) { struct stat64 sb2; if (stat64(argname, &sb2) == 0 && (S_ISBLK(sb2.st_mode) || S_ISCHR(sb2.st_mode))) sb = sb2; } mntp = find_mountpoint(mtab, argname, &sb); if (mntp != NULL) { fsrfs(mntp, 0, 100); } else if (S_ISCHR(sb.st_mode)) { fprintf(stderr, _( "%s: char special not supported: %s\n"), progname, argname); exit(1); } else if (S_ISDIR(sb.st_mode) || S_ISREG(sb.st_mode)) { if (!platform_test_xfs_path(argname)) { fprintf(stderr, _( "%s: cannot defragment: %s: Not XFS\n"), progname, argname); continue; } if (S_ISDIR(sb.st_mode)) fsrdir(argname); else fsrfile(argname, sb.st_ino); } else { printf( _("%s: not fsys dev, dir, or reg file, ignoring\n"), argname); } } } else { initallfs(mtab); fsrallfs(mtab, howlong, leftofffile); } return 0; } void usage(int ret) { fprintf(stderr, _( "Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" " %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n\n" "Options:\n" " -n Do nothing, only interesting with -v. Not\n" " effective with in mtab mode.\n" " -s Print statistics only.\n" " -g Print to syslog (default if stdout not a tty).\n" " -t time How long to run in seconds.\n" " -p passes Number of passes before terminating global re-org.\n" " -f leftoff Use this instead of %s.\n" " -m mtab Use something other than /etc/mtab.\n" " -d Debug, print even more.\n" " -v Verbose, more -v's more verbose.\n" ), progname, progname, _PATH_FSRLAST); exit(ret); } /* * initallfs -- read the mount table and set up an internal form */ static void initallfs(char *mtab) { FILE *fp; struct mntent *mp; int mi; char *cp; struct stat64 sb; fp = setmntent(mtab, "r"); if (fp == NULL) { fsrprintf(_("could not open mtab file: %s\n"), mtab); exit(1); } /* malloc a number of descriptors, increased later if needed */ if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { fsrprintf(_("out of memory: %s\n"), strerror(errno)); exit(1); } fsend = (fsbase + fsbufsize - 1); /* find all rw xfs file systems */ mi = 0; fs = fsbase; while ((mp = getmntent(fp))) { int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || stat64(mp->mnt_fsname, &sb) == -1 || !S_ISBLK(sb.st_mode)) continue; cp = strtok(mp->mnt_opts,","); do { if (strcmp("rw", cp) == 0) rw++; } while ((cp = strtok(NULL, ",")) != NULL); if (rw == 0) { if (dflag) fsrprintf(_("Skipping %s: not mounted rw\n"), mp->mnt_fsname); continue; } if (mi == fsbufsize) { fsbufsize += NMOUNT; if ((fsbase = (fsdesc_t *)realloc((char *)fsbase, fsbufsize * sizeof(fsdesc_t))) == NULL) { fsrprintf(_("out of memory: %s\n"), strerror(errno)); exit(1); } if (!fsbase) { fsrprintf(_("out of memory on realloc: %s\n"), strerror(errno)); exit(1); } fs = (fsbase + mi); /* Needed ? */ } fs->dev = strdup(mp->mnt_fsname); fs->mnt = strdup(mp->mnt_dir); if (fs->mnt == NULL || fs->mnt == NULL) { fsrprintf(_("strdup(%s) failed\n"), mp->mnt_fsname); exit(1); } mi++; fs++; } numfs = mi; fsend = (fsbase + numfs); endmntent(fp); if (numfs == 0) { fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab); exit(0); } if (vflag || dflag) { fsrprintf(_("Found %d mounted, writable, XFS filesystems\n"), numfs); if (dflag) for (fs = fsbase; fs < fsend; fs++) fsrprintf("\t%-30.30s%-30.30s\n", fs->dev, fs->mnt); } } static void fsrallfs(char *mtab, int howlong, char *leftofffile) { int fd; int error; int found = 0; char *fsname; char buf[SMBUFSZ]; int mdonly = Mflag; char *ptr; xfs_ino_t startino = 0; fsdesc_t *fsp; struct stat64 sb, sb2; fsrprintf("xfs_fsr -m %s -t %d -f %s ...\n", mtab, howlong, leftofffile); endtime = starttime + howlong; fs = fsbase; /* where'd we leave off last time? */ if (lstat64(leftofffile, &sb) == 0) { if ( (fd = open(leftofffile, O_RDONLY)) == -1 ) { fsrprintf(_("%s: open failed\n"), leftofffile); } else if ( fstat64(fd, &sb2) == 0) { /* * Verify that lstat & fstat point to the * same regular file (no links/no quick spoofs) */ if ( (sb.st_dev != sb2.st_dev) || (sb.st_ino != sb2.st_ino) || ((sb.st_mode & S_IFMT) != S_IFREG) || ((sb2.st_mode & S_IFMT) != S_IFREG) || (sb2.st_uid != ROOT) || (sb2.st_nlink != 1) ) { fsrprintf(_("Can't use %s: mode=0%o own=%d" " nlink=%d\n"), leftofffile, sb.st_mode, sb.st_uid, sb.st_nlink); close(fd); fd = NULLFD; } } else { close(fd); fd = NULLFD; } } else { fd = NULLFD; } if (fd != NULLFD) { if (read(fd, buf, SMBUFSZ) == -1) { fs = fsbase; fsrprintf(_("could not read %s, starting with %s\n"), leftofffile, *fs->dev); } else { for (fs = fsbase; fs < fsend; fs++) { fsname = fs->dev; if ((strncmp(buf,fsname,strlen(fsname)) == 0) && buf[strlen(fsname)] == ' ') { found = 1; break; } } if (! found) fs = fsbase; ptr = strchr(buf, ' '); if (ptr) { startpass = atoi(++ptr); ptr = strchr(ptr, ' '); if (ptr) { startino = strtoull(++ptr, NULL, 10); } } if (startpass < 0) startpass = 0; /* Init pass counts */ for (fsp = fsbase; fsp < fs; fsp++) { fsp->npass = startpass + 1; } for (fsp = fs; fsp <= fsend; fsp++) { fsp->npass = startpass; } } close(fd); } if (vflag) { fsrprintf(_("START: pass=%d ino=%llu %s %s\n"), fs->npass, (unsigned long long)startino, fs->dev, fs->mnt); } signal(SIGABRT, aborter); signal(SIGHUP, aborter); signal(SIGINT, aborter); signal(SIGQUIT, aborter); signal(SIGTERM, aborter); /* reorg for 'howlong' -- checked in 'fsrfs' */ while (endtime > time(0)) { pid_t pid; if (fs == fsend) fs = fsbase; if (fs->npass == npasses) { fsrprintf(_("Completed all %d passes\n"), npasses); break; } if (npasses > 1 && !fs->npass) Mflag = 1; else Mflag = mdonly; pid = fork(); switch(pid) { case -1: fsrprintf(_("couldn't fork sub process:")); exit(1); break; case 0: error = fsrfs(fs->mnt, startino, TARGETRANGE); exit (error); break; default: wait(&error); close(fd); if (WIFEXITED(error) && WEXITSTATUS(error) == 1) { /* child timed out & did fsrall_cleanup */ exit(0); } break; } startino = 0; /* reset after the first time through */ fs->npass++; fs++; } fsrall_cleanup(endtime <= time(0)); } /* * fsrall_cleanup -- close files, print next starting location, etc. */ static void fsrall_cleanup(int timeout) { int fd; int ret; char buf[SMBUFSZ]; /* record where we left off */ unlink(leftofffile); fd = open(leftofffile, O_WRONLY|O_CREAT|O_EXCL, 0644); if (fd == -1) fsrprintf(_("open(%s) failed: %s\n"), leftofffile, strerror(errno)); else { if (timeout) { ret = sprintf(buf, "%s %d %llu\n", fs->dev, fs->npass, (unsigned long long)leftoffino); if (write(fd, buf, ret) < strlen(buf)) fsrprintf(_("write(%s) failed: %s\n"), leftofffile, strerror(errno)); close(fd); } } if (timeout) fsrprintf(_("%s startpass %d, endpass %d, time %d seconds\n"), progname, startpass, fs->npass, time(0) - endtime + howlong); } /* * fsrfs -- reorganize a file system */ static int fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) { int fsfd, fd; int count = 0; int ret; __s32 buflenout; xfs_bstat_t buf[GRABSZ]; char fname[64]; char *tname; jdm_fshandle_t *fshandlep; xfs_ino_t lastino = startino; fsrprintf(_("%s start inode=%llu\n"), mntdir, (unsigned long long)startino); fshandlep = jdm_getfshandle( mntdir ); if ( ! fshandlep ) { fsrprintf(_("unable to get handle: %s: %s\n"), mntdir, strerror( errno )); return -1; } if ((fsfd = open(mntdir, O_RDONLY)) < 0) { fsrprintf(_("unable to open: %s: %s\n"), mntdir, strerror( errno )); return -1; } if (xfs_getgeom(fsfd, &fsgeom) < 0 ) { fsrprintf(_("Skipping %s: could not get XFS geometry\n"), mntdir); return -1; } tmp_init(mntdir); while ((ret = xfs_bulkstat(fsfd, &lastino, GRABSZ, &buf[0], &buflenout) == 0)) { xfs_bstat_t *p; xfs_bstat_t *endp; if (buflenout == 0) goto out0; /* Each loop through, defrag targetrange percent of the files */ count = (buflenout * targetrange) / 100; qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp); for (p = buf, endp = (buf + buflenout); p < endp ; p++) { /* Do some obvious checks now */ if (((p->bs_mode & S_IFMT) != S_IFREG) || (p->bs_extents < 2)) continue; if ((fd = jdm_open(fshandlep, p, O_RDWR)) < 0) { /* This probably means the file was * removed while in progress of handling * it. Just quietly ignore this file. */ if (dflag) fsrprintf(_("could not open: " "inode %llu\n"), p->bs_ino); continue; } /* Don't know the pathname, so make up something */ sprintf(fname, "ino=%lld", (long long)p->bs_ino); /* Get a tmp file name */ tname = tmp_next(mntdir); ret = fsrfile_common(fname, tname, mntdir, fd, p); leftoffino = p->bs_ino; close(fd); if (ret == 0) { if (--count <= 0) break; } } if (endtime && endtime < time(0)) { tmp_close(mntdir); close(fsfd); fsrall_cleanup(1); exit(1); } } if (ret < 0) fsrprintf(_("%s: xfs_bulkstat: %s\n"), progname, strerror(errno)); out0: tmp_close(mntdir); close(fsfd); return 0; } /* * To compare bstat structs for qsort. */ int cmp(const void *s1, const void *s2) { return( ((xfs_bstat_t *)s2)->bs_extents - ((xfs_bstat_t *)s1)->bs_extents); } /* * reorganize by directory hierarchy. * Stay in dev (a restriction based on structure of this program -- either * call efs_{n,u}mount() around each file, something smarter or this) */ static void fsrdir(char *dirname) { fsrprintf(_("%s: Directory defragmentation not supported\n"), dirname); } /* * Sets up the defragmentation of a file based on the * filepath. It collects the bstat information, does * an open on the file and passes this all to fsrfile_common. */ static int fsrfile(char *fname, xfs_ino_t ino) { xfs_bstat_t statbuf; jdm_fshandle_t *fshandlep; int fd, fsfd; int error = 0; char *tname; fshandlep = jdm_getfshandle(getparent (fname) ); if (! fshandlep) { fsrprintf(_("unable to construct sys handle for %s: %s\n"), fname, strerror(errno)); return -1; } /* * Need to open something on the same filesystem as the * file. Open the parent. */ fsfd = open(getparent(fname), O_RDONLY); if (fsfd < 0) { fsrprintf(_("unable to open sys handle for %s: %s\n"), fname, strerror(errno)); return -1; } if ((xfs_bulkstat_single(fsfd, &ino, &statbuf)) < 0) { fsrprintf(_("unable to get bstat on %s: %s\n"), fname, strerror(errno)); close(fsfd); return -1; } fd = jdm_open( fshandlep, &statbuf, O_RDWR); if (fd < 0) { fsrprintf(_("unable to open handle %s: %s\n"), fname, strerror(errno)); close(fsfd); return -1; } /* Get the fs geometry */ if (xfs_getgeom(fsfd, &fsgeom) < 0 ) { fsrprintf(_("Unable to get geom on fs for: %s\n"), fname); close(fsfd); return -1; } close(fsfd); tname = gettmpname(fname); if (tname) error = fsrfile_common(fname, tname, NULL, fd, &statbuf); close(fd); return error; } /* * This is the common defrag code for either a full fs * defragmentation or a single file. Check as much as * possible with the file, fork a process to setuid to the * target file owner's uid and defragment the file. * This is done so the new extents created in a tmp file are * reflected in the owners' quota without having to do any * special code in the kernel. When the existing extents * are removed, the quotas will be correct. It's ugly but * it saves us from doing some quota re-construction in * the extent swap. The price is that the defragmentation * will fail if the owner of the target file is already at * their quota limit. */ static int fsrfile_common( char *fname, char *tname, char *fsname, int fd, xfs_bstat_t *statp) { int error; struct statvfs64 vfss; struct fsxattr fsx; unsigned long bsize; if (vflag) fsrprintf("%s\n", fname); if (fsync(fd) < 0) { fsrprintf(_("sync failed: %s: %s\n"), fname, strerror(errno)); return -1; } if (statp->bs_size == 0) { if (vflag) fsrprintf(_("%s: zero size, ignoring\n"), fname); return(0); } /* Check if a mandatory lock is set on the file to try and * avoid blocking indefinitely on the reads later. Note that * someone could still set a mandatory lock after this check * but before all reads have completed to block fsr reads. * This change just closes the window a bit. */ if ( (statp->bs_mode & S_ISGID) && ( ! (statp->bs_mode&S_IXGRP) ) ) { struct flock fl; fl.l_type = F_RDLCK; fl.l_whence = SEEK_SET; fl.l_start = (off_t)0; fl.l_len = 0; if ((fcntl(fd, F_GETLK, &fl)) < 0 ) { if (vflag) fsrprintf(_("locking check failed: %s\n"), fname); return(-1); } if (fl.l_type != F_UNLCK) { /* Mandatory lock is set */ if (vflag) fsrprintf(_("mandatory lock: %s: ignoring\n"), fname); return(-1); } } /* * Check if there is room to copy the file. * * Note that xfs_bstat.bs_blksize returns the filesystem blocksize, * not the optimal I/O size as struct stat. */ if (statvfs64(fsname ? fsname : fname, &vfss) < 0) { fsrprintf(_("unable to get fs stat on %s: %s\n"), fname, strerror(errno)); return -1; } bsize = vfss.f_frsize ? vfss.f_frsize : vfss.f_bsize; if (statp->bs_blksize * statp->bs_blocks > vfss.f_bfree * bsize - minimumfree) { fsrprintf(_("insufficient freespace for: %s: " "size=%lld: ignoring\n"), fname, statp->bs_blksize * statp->bs_blocks); return 1; } if ((ioctl(fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { fsrprintf(_("failed to get inode attrs: %s\n"), fname); return(-1); } if (fsx.fsx_xflags & (XFS_XFLAG_IMMUTABLE|XFS_XFLAG_APPEND)) { if (vflag) fsrprintf(_("%s: immutable/append, ignoring\n"), fname); return(0); } if (fsx.fsx_xflags & XFS_XFLAG_NODEFRAG) { if (vflag) fsrprintf(_("%s: marked as don't defrag, ignoring\n"), fname); return(0); } if (fsx.fsx_xflags & XFS_XFLAG_REALTIME) { if (xfs_getrt(fd, &vfss) < 0) { fsrprintf(_("cannot get realtime geometry for: %s\n"), fname); return(-1); } if (statp->bs_size > ((vfss.f_bfree * bsize) - minimumfree)) { fsrprintf(_("low on realtime free space: %s: " "ignoring file\n"), fname); return(-1); } } if ((RealUid != ROOT) && (RealUid != statp->bs_uid)) { fsrprintf(_("cannot open: %s: Permission denied\n"), fname); return -1; } /* * Previously the code forked here, & the child changed it's uid to * that of the file's owner and then called packfile(), to keep * quota counts correct. (defragged files could use fewer blocks). * * Instead, just fchown() the temp file to the uid,gid of the * file we're defragging, in packfile(). */ if ((error = packfile(fname, tname, fd, statp, &fsx))) return error; return -1; /* no error */ } /* * Attempt to set the attr fork up correctly. This is simple for attr1 * filesystems as they have a fixed inode fork offset. In that case * just create an attribute and that's all we need to do. * * For attr2 filesystems, see if we have the actual fork offset in * the bstat structure. If so, just create additional attributes on * the temporary inode until the offset matches. * * If it doesn't exist, we can only do best effort. Add an attribute at a time * to move the inode fork around, but take into account that the attribute * might be too small to move the fork every time we add one. This should * hopefully put the fork offset in the right place. It's not a big deal if we * don't get it right - the kernel will reject it when we try to swap extents. */ static int fsr_setup_attr_fork( int fd, int tfd, xfs_bstat_t *bstatp) { struct stat64 tstatbuf; int i; int last_forkoff = 0; int no_change_cnt = 0; int ret; if (!(bstatp->bs_xflags & XFS_XFLAG_HASATTR)) return 0; /* * use the old method if we have attr1 or the kernel does not yet * support passing the fork offset in the bulkstat data. */ if (!(fsgeom.flags & XFS_FSOP_GEOM_FLAGS_ATTR2) || bstatp->bs_forkoff == 0) { /* attr1 */ ret = fsetxattr(tfd, "user.X", "X", 1, XATTR_CREATE); if (ret) { fsrprintf(_("could not set ATTR\n")); return -1; } goto out; } /* attr2 w/ fork offsets */ if (fstat64(tfd, &tstatbuf) < 0) { fsrprintf(_("unable to stat temp file: %s\n"), strerror(errno)); return -1; } i = 0; do { xfs_bstat_t tbstat; xfs_ino_t ino; char name[64]; int diff; /* * bulkstat the temp inode to see what the forkoff is. Use * this to compare against the target and determine what we * need to do. */ ino = tstatbuf.st_ino; if ((xfs_bulkstat_single(tfd, &ino, &tbstat)) < 0) { fsrprintf(_("unable to get bstat on temp file: %s\n"), strerror(errno)); return -1; } if (dflag) fsrprintf(_("orig forkoff %d, temp forkoff %d\n"), bstatp->bs_forkoff, tbstat.bs_forkoff); snprintf(name, sizeof(name), "user.%d", i); /* * If there is no attribute, then we need to create one to get * an attribute fork at the default location. */ if (!tbstat.bs_forkoff) { ret = fsetxattr(tfd, name, "XX", 2, XATTR_CREATE); if (ret) { fsrprintf(_("could not set ATTR\n")); return -1; } continue; } /* * make a progress check so we don't get stuck trying to extend * a large btree form attribute fork. */ if (last_forkoff == tbstat.bs_forkoff) { if (no_change_cnt++ > 10) break; } no_change_cnt = 0; last_forkoff = tbstat.bs_forkoff; /* work out which way to grow the fork */ diff = tbstat.bs_forkoff - bstatp->bs_forkoff; if (abs(diff) > fsgeom.inodesize - sizeof(struct xfs_dinode)) { fsrprintf(_("forkoff diff %d too large!\n"), diff); return -1; } /* if they are equal, we are done */ if (!diff) goto out; /* * if the temp inode fork offset is smaller then we have to * grow the data fork */ if (diff < 0) { /* * create some temporary extents in the inode to move * the fork in the direction we need. This can be done * by preallocating some single block extents at * non-contiguous offsets. */ /* XXX: unimplemented! */ goto out; } /* we need to grow the attr fork, so create another attr */ ret = fsetxattr(tfd, name, "XX", 2, XATTR_CREATE); if (ret) { fsrprintf(_("could not set ATTR\n")); return -1; } } while (++i < 100); /* don't go forever */ out: if (dflag) fsrprintf(_("set temp attr\n")); return 0; } /* * Do the defragmentation of a single file. * We already are pretty sure we can and want to * defragment the file. Create the tmp file, copy * the data (maintaining holes) and call the kernel * extent swap routinte. */ static int packfile(char *fname, char *tname, int fd, xfs_bstat_t *statp, struct fsxattr *fsxp) { int tfd; int srval; int nextents, extent, cur_nextents, new_nextents; unsigned blksz_dio; unsigned dio_min; struct dioattr dio; static xfs_swapext_t sx; struct xfs_flock64 space; off64_t cnt, pos; void *fbuf; int ct, wc, wc_b4; char ffname[SMBUFSZ]; int ffd = -1; /* * Work out the extent map - nextents will be set to the * minimum number of extents needed for the file (taking * into account holes), cur_nextents is the current number * of extents. */ nextents = read_fd_bmap(fd, statp, &cur_nextents); if (cur_nextents == 1 || cur_nextents <= nextents) { if (vflag) fsrprintf(_("%s already fully defragmented.\n"), fname); return 1; /* indicates no change/no error */ } if (dflag) fsrprintf(_("%s extents=%d can_save=%d tmp=%s\n"), fname, cur_nextents, (cur_nextents - nextents), tname); if ((tfd = open(tname, openopts, 0666)) < 0) { if (vflag) fsrprintf(_("could not open tmp file: %s: %s\n"), tname, strerror(errno)); return -1; } unlink(tname); /* Setup extended attributes */ if (fsr_setup_attr_fork(fd, tfd, statp) != 0) { fsrprintf(_("failed to set ATTR fork on tmp: %s:\n"), tname); close(tfd); return -1; } /* Setup extended inode flags, project identifier, etc */ if (fsxp->fsx_xflags || fsxp->fsx_projid) { if (ioctl(tfd, XFS_IOC_FSSETXATTR, fsxp) < 0) { fsrprintf(_("could not set inode attrs on tmp: %s\n"), tname); close(tfd); return -1; } } if ((ioctl(tfd, XFS_IOC_DIOINFO, &dio)) < 0 ) { fsrprintf(_("could not get DirectIO info on tmp: %s\n"), tname); close(tfd); return -1; } dio_min = dio.d_miniosz; if (statp->bs_size <= dio_min) { blksz_dio = dio_min; } else { blksz_dio = min(dio.d_maxiosz, BUFFER_MAX - pagesize); if (argv_blksz_dio != 0) blksz_dio = min(argv_blksz_dio, blksz_dio); blksz_dio = (min(statp->bs_size, blksz_dio) / dio_min) * dio_min; } if (dflag) { fsrprintf(_("DEBUG: " "fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n"), statp->bs_size, blksz_dio, dio.d_miniosz, dio.d_maxiosz, pagesize); } if (!(fbuf = (char *)memalign(dio.d_mem, blksz_dio))) { fsrprintf(_("could not allocate buf: %s\n"), tname); close(tfd); return -1; } if (nfrags) { /* Create new tmp file in same AG as first */ sprintf(ffname, "%s.frag", tname); /* Open the new file for sync writes */ if ((ffd = open(ffname, openopts, 0666)) < 0) { fsrprintf(_("could not open fragfile: %s : %s\n"), ffname, strerror(errno)); close(tfd); free(fbuf); return -1; } unlink(ffname); } /* Loop through block map allocating new extents */ for (extent = 0; extent < nextents; extent++) { pos = outmap[extent].bmv_offset; if (outmap[extent].bmv_block == -1) { space.l_whence = SEEK_SET; space.l_start = pos; space.l_len = outmap[extent].bmv_length; if (ioctl(tfd, XFS_IOC_UNRESVSP64, &space) < 0) { fsrprintf(_("could not trunc tmp %s\n"), tname); } lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); continue; } else if (outmap[extent].bmv_length == 0) { /* to catch holes at the beginning of the file */ continue; } if (! nfrags) { space.l_whence = SEEK_CUR; space.l_start = 0; space.l_len = outmap[extent].bmv_length; if (ioctl(tfd, XFS_IOC_RESVSP64, &space) < 0) { fsrprintf(_("could not pre-allocate tmp space:" " %s\n"), tname); close(tfd); free(fbuf); return -1; } lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); } } /* end of space allocation loop */ if (lseek64(tfd, 0, SEEK_SET)) { fsrprintf(_("Couldn't rewind on temporary file\n")); close(tfd); free(fbuf); return -1; } /* Check if the temporary file has fewer extents */ new_nextents = getnextents(tfd); if (dflag) fsrprintf(_("Temporary file has %d extents (%d in original)\n"), new_nextents, cur_nextents); if (cur_nextents <= new_nextents) { if (vflag) fsrprintf(_("No improvement will be made (skipping): %s\n"), fname); free(fbuf); close(tfd); return 1; /* no change/no error */ } /* Loop through block map copying the file. */ for (extent = 0; extent < nextents; extent++) { pos = outmap[extent].bmv_offset; if (outmap[extent].bmv_block == -1) { lseek64(tfd, outmap[extent].bmv_length, SEEK_CUR); lseek64(fd, outmap[extent].bmv_length, SEEK_CUR); continue; } else if (outmap[extent].bmv_length == 0) { /* to catch holes at the beginning of the file */ continue; } for (cnt = outmap[extent].bmv_length; cnt > 0; cnt -= ct, pos += ct) { if (nfrags && --nfrags) { ct = min(cnt, dio_min); } else if (cnt % dio_min == 0) { ct = min(cnt, blksz_dio); } else { ct = min(cnt + dio_min - (cnt % dio_min), blksz_dio); } ct = read(fd, fbuf, ct); if (ct == 0) { /* EOF, stop trying to read */ extent = nextents; break; } /* Ensure we do direct I/O to correct block * boundaries. */ if (ct % dio_min != 0) { wc = ct + dio_min - (ct % dio_min); } else { wc = ct; } wc_b4 = wc; if (ct < 0 || ((wc = write(tfd, fbuf, wc)) != wc_b4)) { if (ct < 0) fsrprintf(_("bad read of %d bytes " "from %s: %s\n"), wc_b4, fname, strerror(errno)); else if (wc < 0) fsrprintf(_("bad write of %d bytes " "to %s: %s\n"), wc_b4, tname, strerror(errno)); else { /* * Might be out of space * * Try to finish write */ int resid = ct-wc; if ((wc = write(tfd, ((char *)fbuf)+wc, resid)) == resid) { /* worked on second attempt? */ continue; } else if (wc < 0) { fsrprintf(_("bad write2 of %d " "bytes to %s: %s\n"), resid, tname, strerror(errno)); } else { fsrprintf(_("bad copy to %s\n"), tname); } } free(fbuf); close(tfd); return -1; } if (nfrags) { /* Do a matching write to the tmp file */ wc_b4 = wc; if (((wc = write(ffd, fbuf, wc)) != wc_b4)) { fsrprintf(_("bad write of %d bytes " "to %s: %s\n"), wc_b4, ffname, strerror(errno)); } } } } ftruncate64(tfd, statp->bs_size); if (ffd > 0) close(ffd); fsync(tfd); free(fbuf); sx.sx_stat = *statp; /* struct copy */ sx.sx_version = XFS_SX_VERSION; sx.sx_fdtarget = fd; sx.sx_fdtmp = tfd; sx.sx_offset = 0; sx.sx_length = statp->bs_size; /* switch to the owner's id, to keep quota in line */ if (fchown(tfd, statp->bs_uid, statp->bs_gid) < 0) { if (vflag) fsrprintf(_("failed to fchown tmpfile %s: %s\n"), tname, strerror(errno)); close(tfd); return -1; } /* Swap the extents */ srval = xfs_swapext(fd, &sx); if (srval < 0) { if (errno == ENOTSUP) { if (vflag || dflag) fsrprintf(_("%s: file type not supported\n"), fname); } else if (errno == EFAULT) { /* The file has changed since we started the copy */ if (vflag || dflag) fsrprintf(_("%s: file modified defrag aborted\n"), fname); } else if (errno == EBUSY) { /* Timestamp has changed or mmap'ed file */ if (vflag || dflag) fsrprintf(_("%s: file busy\n"), fname); } else { fsrprintf(_("XFS_IOC_SWAPEXT failed: %s: %s\n"), fname, strerror(errno)); } close(tfd); return -1; } /* Report progress */ if (vflag) fsrprintf(_("extents before:%d after:%d %s %s\n"), cur_nextents, new_nextents, (new_nextents <= nextents ? "DONE" : " " ), fname); close(tfd); return 0; } char * gettmpname(char *fname) { static char buf[PATH_MAX+1]; char sbuf[SMBUFSZ]; char *ptr; sprintf(sbuf, "/.fsr%d", getpid()); strcpy(buf, fname); ptr = strrchr(buf, '/'); if (ptr) { *ptr = '\0'; } else { strcpy(buf, "."); } if ((strlen(buf) + strlen (sbuf)) > PATH_MAX) { fsrprintf(_("tmp file name too long: %s\n"), fname); return(NULL); } strcat(buf, sbuf); return(buf); } char * getparent(char *fname) { static char buf[PATH_MAX+1]; char *ptr; strcpy(buf, fname); ptr = strrchr(buf, '/'); if (ptr) { if (ptr == &buf[0]) ++ptr; *ptr = '\0'; } else { strcpy(buf, "."); } return(buf); } /* * Read in block map of the input file, coalesce contiguous * extents into a single range, keep all holes. Convert from 512 byte * blocks to bytes. * * This code was borrowed from mv.c with some minor mods. */ #define MAPSIZE 128 #define OUTMAP_SIZE_INCREMENT MAPSIZE int read_fd_bmap(int fd, xfs_bstat_t *sin, int *cur_nextents) { int i, cnt; struct getbmap map[MAPSIZE]; #define BUMP_CNT \ if (++cnt >= outmap_size) { \ outmap_size += OUTMAP_SIZE_INCREMENT; \ outmap = (struct getbmap *)realloc(outmap, \ outmap_size*sizeof(*outmap)); \ if (outmap == NULL) { \ fsrprintf(_("realloc failed: %s\n"), \ strerror(errno)); \ exit(1); \ } \ } /* Initialize the outmap array. It always grows - never shrinks. * Left-over memory allocation is saved for the next files. */ if (outmap_size == 0) { outmap_size = OUTMAP_SIZE_INCREMENT; /* Initial size */ outmap = (struct getbmap *)malloc(outmap_size*sizeof(*outmap)); if (!outmap) { fsrprintf(_("malloc failed: %s\n"), strerror(errno)); exit(1); } } outmap[0].bmv_block = 0; outmap[0].bmv_offset = 0; outmap[0].bmv_length = sin->bs_size; /* * If a non regular file is involved then forget holes */ if (!S_ISREG(sin->bs_mode)) return(1); outmap[0].bmv_length = 0; map[0].bmv_offset = 0; map[0].bmv_block = 0; map[0].bmv_entries = 0; map[0].bmv_count = MAPSIZE; map[0].bmv_length = -1; cnt = 0; *cur_nextents = 0; do { if (ioctl(fd, XFS_IOC_GETBMAP, map) < 0) { fsrprintf(_("failed reading extents: inode %llu"), (unsigned long long)sin->bs_ino); exit(1); } /* Concatenate extents together and replicate holes into * the output map. */ *cur_nextents += map[0].bmv_entries; for (i = 0; i < map[0].bmv_entries; i++) { if (map[i + 1].bmv_block == -1) { BUMP_CNT; outmap[cnt] = map[i+1]; } else if (outmap[cnt].bmv_block == -1) { BUMP_CNT; outmap[cnt] = map[i+1]; } else { outmap[cnt].bmv_length += map[i + 1].bmv_length; } } } while (map[0].bmv_entries == (MAPSIZE-1)); for (i = 0; i <= cnt; i++) { outmap[i].bmv_offset = BBTOB(outmap[i].bmv_offset); outmap[i].bmv_length = BBTOB(outmap[i].bmv_length); } outmap[cnt].bmv_length = sin->bs_size - outmap[cnt].bmv_offset; return(cnt+1); } /* * Read the block map and return the number of extents. */ int getnextents(int fd) { int nextents; struct getbmap map[MAPSIZE]; map[0].bmv_offset = 0; map[0].bmv_block = 0; map[0].bmv_entries = 0; map[0].bmv_count = MAPSIZE; map[0].bmv_length = -1; nextents = 0; do { if (ioctl(fd,XFS_IOC_GETBMAP, map) < 0) { fsrprintf(_("failed reading extents")); exit(1); } nextents += map[0].bmv_entries; } while (map[0].bmv_entries == (MAPSIZE-1)); return(nextents); } /* * Get the fs geometry */ int xfs_getgeom(int fd, xfs_fsop_geom_v1_t * fsgeom) { if (xfs_fsgeometry(fd, fsgeom) < 0) { return -1; } return 0; } /* * Get xfs realtime space information */ int xfs_getrt(int fd, struct statvfs64 *sfbp) { unsigned long bsize; unsigned long factor; xfs_fsop_counts_t cnt; if (!fsgeom.rtblocks) return -1; if (xfs_fscounts(fd, &cnt) < 0) { close(fd); return -1; } bsize = (sfbp->f_frsize ? sfbp->f_frsize : sfbp->f_bsize); factor = fsgeom.blocksize / bsize; /* currently this is == 1 */ sfbp->f_bfree = (cnt.freertx * fsgeom.rtextsize) * factor; return 0; } int fsrprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); if (gflag) { static int didopenlog; if (!didopenlog) { openlog("fsr", LOG_PID, LOG_USER); didopenlog = 1; } vsyslog(LOG_INFO, fmt, ap); } else vprintf(fmt, ap); va_end(ap); return 0; } /* * Initialize a directory for tmp file use. This is used * by the full filesystem defragmentation when we're walking * the inodes and do not know the path for the individual * files. Multiple directories are used to spread out the * tmp data around to different ag's (since file data is * usually allocated to the same ag as the directory and * directories allocated round robin from the same * parent directory). */ static void tmp_init(char *mnt) { int i; static char buf[SMBUFSZ]; mode_t mask; tmp_agi = 0; sprintf(buf, "%s/.fsr", mnt); mask = umask(0); if (mkdir(buf, 0700) < 0) { if (errno == EEXIST) { if (dflag) fsrprintf(_("tmpdir already exists: %s\n"), buf); } else { fsrprintf(_("could not create tmpdir: %s: %s\n"), buf, strerror(errno)); exit(-1); } } for (i=0; i < fsgeom.agcount; i++) { sprintf(buf, "%s/.fsr/ag%d", mnt, i); if (mkdir(buf, 0700) < 0) { if (errno == EEXIST) { if (dflag) fsrprintf( _("tmpdir already exists: %s\n"), buf); } else { fsrprintf(_("cannot create tmpdir: %s: %s\n"), buf, strerror(errno)); exit(-1); } } } (void)umask(mask); return; } static char * tmp_next(char *mnt) { static char buf[SMBUFSZ]; sprintf(buf, "%s/.fsr/ag%d/tmp%d", ( (strcmp(mnt, "/") == 0) ? "" : mnt), tmp_agi, getpid()); if (++tmp_agi == fsgeom.agcount) tmp_agi = 0; return(buf); } static void tmp_close(char *mnt) { static char buf[SMBUFSZ]; int i; /* No data is ever actually written so we can just do rmdir's */ for (i=0; i < fsgeom.agcount; i++) { sprintf(buf, "%s/.fsr/ag%d", mnt, i); if (rmdir(buf) < 0) { if (errno != ENOENT) { fsrprintf( _("could not remove tmpdir: %s: %s\n"), buf, strerror(errno)); } } } sprintf(buf, "%s/.fsr", mnt); if (rmdir(buf) < 0) { if (errno != ENOENT) { fsrprintf(_("could not remove tmpdir: %s: %s\n"), buf, strerror(errno)); } } } xfsprogs-3.1.9ubuntu2/install-sh0000775000000000000000000001542511711735052013631 0ustar #! /bin/bash # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # # This script emulates bsd install and also recognises # two environment variables, with the following semantics :- # # $DIST_MANIFEST - if set, the name of the file to append manifest # information in the following format: # File : f mode owner group src target # Directory: d mode owner group target # Symlink : l linkval target # # $DIST_ROOT - if set, prepend to target # # The sematics of all combinations of these two variables # are as follows: # # $DIST_MANIFEST? $DIST_ROOT? | Copy? Append Manifest? # -----------------------------+-------------------------- # not set not set | yes no # not set set | yes no # set not set | no yes # set set | yes yes # _usage() { echo "Usage: $prog [-o owner] [-g group] [-m mode] -d directory" echo "or $prog [-D] [-o owner] [-g group] [-m mode] file directory/file" echo "or $prog [-o owner] [-g group] [-m mode] file [file ...] directory" echo "or $prog -S file target (creates \"target\" symlink)" echo "or $prog -T lt_arg [-o owner] [-g group] [-m mode] libtool.lai directory" echo "" echo "The \$DIST_MANIFEST and \$DIST_ROOT environment variables affect the" echo "behaviour of this command - see comments in the script." echo "The -D flag is only available for the second usage, and causes" echo "the target directory to be created before installing the file." echo "" exit 1 } _chown () { _st=255 if [ $# -eq 3 ] ; then chown $1:$2 $3 _st=$? if [ $_st -ne 0 ] ; then if [ $REAL_UID != '0' ] ; then if [ ! -f $DIST_ROOT/.chown.quiet ] ; then echo '===============================================' echo Ownership of files under ${DIST_ROOT:-/} echo cannot be changed echo '===============================================' if [ -n "$DIST_ROOT" ] ; then touch $DIST_ROOT/.chown.quiet fi fi _st=0 fi fi fi return $_st } _manifest () { echo $* | sed -e 's/\/\//\//g' >>${DIST_MANIFEST:-/dev/null} } prog=`basename $0` HERE=`pwd` dflag=false Dflag=false Sflag=false Tflag=false DIRMODE=755 FILEMODE=644 OWNER=`id -u` GROUP=`id -g` REAL_UID=$OWNER # default is to install and don't append manifest INSTALL=true MANIFEST=: [ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false [ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest" [ $# -eq 0 ] && _usage if $INSTALL then CP=cp; LN=ln; MKDIR=mkdir; CHMOD=chmod; CHOWN=_chown else CP=true; LN=true; MKDIR=true; CHMOD=true; CHOWN=true fi [ -n "$DIST_ROOT" -a $REAL_UID -ne 0 ] && CHOWN=true while getopts "Dcm:d:S:o:g:T:" c $* do case $c in c) ;; g) GROUP=$OPTARG ;; o) OWNER=$OPTARG ;; m) DIRMODE=`expr $OPTARG` FILEMODE=$DIRMODE ;; D) Dflag=true ;; S) symlink=$OPTARG Sflag=true ;; d) dir=$DIST_ROOT/$OPTARG dflag=true ;; T) lt_install=$OPTARG Tflag=true ;; *) _usage ;; esac done shift `expr $OPTIND - 1` status=0 if $dflag then # # first usage # $MKDIR -p $dir status=$? if [ $status -eq 0 ] then $CHMOD $DIRMODE $dir status=$? fi if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir status=$? fi $MANIFEST d $DIRMODE $OWNER $GROUP ${dir#$DIST_ROOT} elif $Sflag then # # fourth usage (symlink) # if [ $# -ne 1 ] then _usage else target=$DIST_ROOT/$1 fi $LN -s -f $symlink $target status=$? $MANIFEST l $symlink ${target#$DIST_ROOT} elif $Tflag then # # -T (install libs built by libtool) # if [ $# -ne 2 ] then _usage else libtool_lai=$1 # source the libtool variables if [ ! -f $libtool_lai ] then echo "$prog: Unable to find libtool library file $libtool_lai" exit 2 fi . ./$libtool_lai target=$DIST_ROOT/$2 fi case $lt_install in so_dot_version) # Loop until we find libfoo.so.x.y.z, then break out. for solib in $library_names do # does it have enough parts? libfoo.so.x.y.z == 5 cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w` if [ $cnt -eq 5 ] then install_name=$target/$solib $CP $solib $install_name status=$? $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$solib ${install_name#$DIST_ROOT} break fi done ;; so_*) case $lt_install in so_dot_current) # ln -s libfoo.so.x.y.z to libfoo.so.x from_parts=5 # libfoo.so.x.y.z to_parts=3 # libfoo.so.x ;; so_base) # ln -s libfoo.so.x to libfoo.so from_parts=3 # libfoo.so.x to_parts=2 # libfoo.so ;; *) echo "$prog: -T $lt_install invalid" exit 2 ;; esac # Loop until we find the names, then break out. for solib in $library_names do # does it have enough parts? cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w` if [ $cnt -eq $from_parts ] then from_name=$solib elif [ $cnt -eq $to_parts ] then to_name=$solib fi if [ -n "$from_name" ] && [ -n "$to_name" ] then install_name=$target/$to_name $LN -s -f $from_name $install_name status=$? $MANIFEST l $from_name ${install_name#$DIST_ROOT} break fi done ;; old_lib) install_name=$target/$old_library $CP $old_library $install_name status=$? $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$old_library ${install_name#$DIST_ROOT} ;; *) echo "$prog: -T $lt_install invalid" exit 2 ;; esac case $lt_install in old_lib|so_dot_version) if [ $status -eq 0 ] then $CHMOD $FILEMODE $install_name $CHOWN $OWNER $GROUP $install_name fi ;; esac else list="" dir="" if [ $# -eq 2 ] then # # second usage # f=$1 dir=$DIST_ROOT/$2 if $Dflag then mkdir -p `dirname $dir` fi $CP $f $dir status=$? if [ $status -eq 0 ] then if [ -f $dir/$f ] then $CHMOD $FILEMODE $dir/$f status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir/$f status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f else $CHMOD $FILEMODE $dir status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$dir ${dir#$DIST_ROOT} fi fi else # # third usage # n=1 while [ $# -gt 0 ] do if [ $# -gt 1 ] then list="$list $1" else dir=$DIST_ROOT/$1 fi shift done # echo DIR=$dir list=\"$list\" for f in $list do $CP $f $dir status=$? if [ $status -eq 0 ] then $CHMOD $FILEMODE $dir/$f status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir/$f status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f fi [ $status -ne 0 ] && break done fi fi exit $status xfsprogs-3.1.9ubuntu2/config.sub0000775000000000000000000010460611711735051013607 0ustar #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. timestamp='2011-03-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: xfsprogs-3.1.9ubuntu2/mkfs/0000775000000000000000000000000012062211564012553 5ustar xfsprogs-3.1.9ubuntu2/mkfs/Makefile0000664000000000000000000000153111650373061014216 0ustar # # Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = mkfs.xfs FSTYP = fstyp HFILES = xfs_mkfs.h CFILES = maxtrres.c proto.c xfs_mkfs.c ifeq ($(ENABLE_BLKID),yes) LLDLIBS += $(LIBBLKID) CFLAGS += -DENABLE_BLKID else LLDLIBS += $(LIBDISK) LTDEPENDENCIES += $(LIBDISK) endif LLDLIBS += $(LIBXFS) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES += $(LIBXFS) LLDFLAGS = -static LSRCFILES = $(FSTYP).c LDIRT = $(FSTYP) default: depend $(LTCOMMAND) ifneq ($(ENABLE_BLKID),yes) default: $(FSTYP) endif include $(BUILDRULES) $(FSTYP): @echo " [CC] $@" $(Q)$(LTLINK) $@.c -o $@ $(CFLAGS) $(LDFLAGS) $(LIBDISK) $(PLDLIBS) install: default $(INSTALL) -m 755 -d $(PKG_ROOT_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_ROOT_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/mkfs/proto.c0000664000000000000000000004255411650373061014077 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "xfs_mkfs.h" /* * Prototypes for internal functions. */ static long getnum(char **pp); static char *getstr(char **pp); static void fail(char *msg, int i); static void getres(xfs_trans_t *tp, uint blocks); static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len); static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, xfs_bmap_free_t *flist, xfs_fsblock_t *first, int dolocal, int logit, char *buf, int len); static char *newregfile(char **pp, int *len); static void rtinit(xfs_mount_t *mp); static long filesize(int fd); /* * Use this for block reservations needed for mkfs's conditions * (basically no fragmentation). */ #define MKFS_BLOCKRES_INODE \ ((uint)(XFS_IALLOC_BLOCKS(mp) + ((mp)->m_in_maxlevels - 1))) #define MKFS_BLOCKRES(rb) \ ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb))) char * setup_proto( char *fname) { char *buf; static char dflt[] = "d--755 0 0 $"; int fd; long size; if (!fname) return dflt; if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) { fprintf(stderr, _("%s: failed to open %s: %s\n"), progname, fname, strerror(errno)); exit(1); } buf = malloc(size + 1); if (read(fd, buf, size) < size) { fprintf(stderr, _("%s: read failed on %s: %s\n"), progname, fname, strerror(errno)); exit(1); } if (buf[size - 1] != '\n') { fprintf(stderr, _("%s: proto file %s premature EOF\n"), progname, fname); exit(1); } buf[size] = '\0'; /* * Skip past the stuff there for compatibility, a string and 2 numbers. */ (void)getstr(&buf); /* boot image name */ (void)getnum(&buf); /* block count */ (void)getnum(&buf); /* inode count */ return buf; } static long getnum( char **pp) { char *s; s = getstr(pp); return atol(s); } static void fail( char *msg, int i) { fprintf(stderr, "%s: %s [%d - %s]\n", progname, msg, i, strerror(i)); exit(1); } void res_failed( int i) { fail(_("cannot reserve space"), i); } static void getres( xfs_trans_t *tp, uint blocks) { int i; xfs_mount_t *mp; uint r; mp = tp->t_mountp; for (i = 0, r = MKFS_BLOCKRES(blocks); r >= blocks; r--) { i = libxfs_trans_reserve(tp, r, 0, 0, 0, 0); if (i == 0) return; } res_failed(i); /* NOTREACHED */ } static char * getstr( char **pp) { char c; char *p; char *rval; p = *pp; while ((c = *p)) { switch (c) { case ' ': case '\t': case '\n': p++; continue; case ':': p++; while (*p++ != '\n') ; continue; default: rval = p; while (c != ' ' && c != '\t' && c != '\n' && c != '\0') c = *++p; *p++ = '\0'; *pp = p; return rval; } } if (c != '\0') { fprintf(stderr, _("%s: premature EOF in prototype file\n"), progname); exit(1); } return NULL; } static void rsvfile( xfs_mount_t *mp, xfs_inode_t *ip, long long llen) { int error; xfs_trans_t *tp; error = libxfs_alloc_file_space(ip, 0, llen, 1, 0); if (error) { fail(_("error reserving space for a file"), error); exit(1); } /* * update the inode timestamp, mode, and prealloc flag bits */ tp = libxfs_trans_alloc(mp, 0); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); ip->i_d.di_mode &= ~S_ISUID; /* * Note that we don't have to worry about mandatory * file locking being disabled here because we only * clear the S_ISGID bit if the Group execute bit is * on, but if it was on then mandatory locking wouldn't * have been enabled. */ if (ip->i_d.di_mode & S_IXGRP) ip->i_d.di_mode &= ~S_ISGID; libxfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); libxfs_trans_commit(tp, 0); } static int newfile( xfs_trans_t *tp, xfs_inode_t *ip, xfs_bmap_free_t *flist, xfs_fsblock_t *first, int dolocal, int logit, char *buf, int len) { xfs_buf_t *bp; xfs_daddr_t d; int error; int flags; xfs_bmbt_irec_t map; xfs_mount_t *mp; xfs_extlen_t nb; int nmap; flags = 0; mp = ip->i_mount; if (dolocal && len <= XFS_IFORK_DSIZE(ip)) { xfs_idata_realloc(ip, len, XFS_DATA_FORK); if (buf) memmove(ip->i_df.if_u1.if_data, buf, len); ip->i_d.di_size = len; ip->i_df.if_flags &= ~XFS_IFEXTENTS; ip->i_df.if_flags |= XFS_IFINLINE; ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; flags = XFS_ILOG_DDATA; } else if (len > 0) { nb = XFS_B_TO_FSB(mp, len); nmap = 1; error = libxfs_bmapi(tp, ip, 0, nb, XFS_BMAPI_WRITE, first, nb, &map, &nmap, flist); if (error) { fail(_("error allocating space for a file"), error); } if (nmap != 1) { fprintf(stderr, _("%s: cannot allocate space for file\n"), progname); exit(1); } d = XFS_FSB_TO_DADDR(mp, map.br_startblock); bp = libxfs_trans_get_buf(logit ? tp : 0, mp->m_dev, d, nb << mp->m_blkbb_log, 0); memmove(XFS_BUF_PTR(bp), buf, len); if (len < XFS_BUF_COUNT(bp)) memset(XFS_BUF_PTR(bp) + len, 0, XFS_BUF_COUNT(bp) - len); if (logit) libxfs_trans_log_buf(tp, bp, 0, XFS_BUF_COUNT(bp) - 1); else libxfs_writebuf(bp, LIBXFS_EXIT_ON_FAILURE); } ip->i_d.di_size = len; return flags; } static char * newregfile( char **pp, int *len) { char *buf; int fd; char *fname; long size; fname = getstr(pp); if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, fname, strerror(errno)); exit(1); } if ((*len = (int)size)) { buf = malloc(size); if (read(fd, buf, size) < size) { fprintf(stderr, _("%s: read failed on %s: %s\n"), progname, fname, strerror(errno)); exit(1); } } else buf = 0; close(fd); return buf; } static void newdirent( xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *pip, struct xfs_name *name, xfs_ino_t inum, xfs_fsblock_t *first, xfs_bmap_free_t *flist, xfs_extlen_t total) { int error; error = libxfs_dir_createname(tp, pip, name, inum, first, flist, total); if (error) fail(_("directory createname error"), error); } static void newdirectory( xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *dp, xfs_inode_t *pdp) { int error; error = libxfs_dir_init(tp, dp, pdp); if (error) fail(_("directory create error"), error); } static void parseproto( xfs_mount_t *mp, xfs_inode_t *pip, struct fsxattr *fsxp, char **pp, char *name) { #define IF_REGULAR 0 #define IF_RESERVED 1 #define IF_BLOCK 2 #define IF_CHAR 3 #define IF_DIRECTORY 4 #define IF_SYMLINK 5 #define IF_FIFO 6 char *buf; int committed; int error; xfs_fsblock_t first; int flags; xfs_bmap_free_t flist; int fmt; int i; xfs_inode_t *ip; int len; long long llen; int majdev; int mindev; int mode; char *mstr; xfs_trans_t *tp; int val; int isroot = 0; cred_t creds; char *value; struct xfs_name xname; memset(&creds, 0, sizeof(creds)); mstr = getstr(pp); switch (mstr[0]) { case '-': fmt = IF_REGULAR; break; case 'r': fmt = IF_RESERVED; break; case 'b': fmt = IF_BLOCK; break; case 'c': fmt = IF_CHAR; break; case 'd': fmt = IF_DIRECTORY; break; case 'l': fmt = IF_SYMLINK; break; case 'p': fmt = IF_FIFO; break; default: fprintf(stderr, _("%s: bad format string %s\n"), progname, mstr); exit(1); } mode = 0; switch (mstr[1]) { case '-': break; case 'u': mode |= S_ISUID; break; default: fprintf(stderr, _("%s: bad format string %s\n"), progname, mstr); exit(1); } switch (mstr[2]) { case '-': break; case 'g': mode |= S_ISGID; break; default: fprintf(stderr, _("%s: bad format string %s\n"), progname, mstr); exit(1); } val = 0; for (i = 3; i < 6; i++) { if (mstr[i] < '0' || mstr[i] > '7') { fprintf(stderr, _("%s: bad format string %s\n"), progname, mstr); exit(1); } val = val * 8 + mstr[i] - '0'; } mode |= val; creds.cr_uid = (int)getnum(pp); creds.cr_gid = (int)getnum(pp); xname.name = (uchar_t *)name; xname.len = name ? strlen(name) : 0; tp = libxfs_trans_alloc(mp, 0); flags = XFS_ILOG_CORE; xfs_bmap_init(&flist, &first); switch (fmt) { case IF_REGULAR: buf = newregfile(pp, &len); getres(tp, XFS_B_TO_FSB(mp, len)); error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0, &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); flags |= newfile(tp, ip, &flist, &first, 0, 0, buf, len); if (buf) free(buf); libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; case IF_RESERVED: /* pre-allocated space only */ value = getstr(pp); llen = cvtnum(mp->m_sb.sb_blocksize, mp->m_sb.sb_sectsize, value); getres(tp, XFS_B_TO_FSB(mp, llen)); error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0, &creds, fsxp, &ip); if (error) fail(_("Inode pre-allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); libxfs_trans_log_inode(tp, ip, flags); error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) fail(_("Pre-allocated file creation failed"), error); libxfs_trans_commit(tp, 0); rsvfile(mp, ip, llen); return; case IF_BLOCK: getres(tp, 0); majdev = (int)getnum(pp); mindev = (int)getnum(pp); error = libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1, IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip); if (error) { fail(_("Inode allocation failed"), error); } libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); flags |= XFS_ILOG_DEV; break; case IF_CHAR: getres(tp, 0); majdev = (int)getnum(pp); mindev = (int)getnum(pp); error = libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1, IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); flags |= XFS_ILOG_DEV; break; case IF_FIFO: getres(tp, 0); error = libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0, &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; case IF_SYMLINK: buf = getstr(pp); len = (int)strlen(buf); getres(tp, XFS_B_TO_FSB(mp, len)); error = libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0, &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len); libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); libxfs_trans_ihold(tp, pip); break; case IF_DIRECTORY: getres(tp, 0); error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0, &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); ip->i_d.di_nlink++; /* account for . */ if (!pip) { pip = ip; mp->m_sb.sb_rootino = ip->i_ino; libxfs_mod_sb(tp, XFS_SB_ROOTINO); mp->m_rootip = ip; isroot = 1; } else { libxfs_trans_ijoin(tp, pip, 0); newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1); pip->i_d.di_nlink++; libxfs_trans_ihold(tp, pip); libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); } newdirectory(mp, tp, ip, pip); libxfs_trans_log_inode(tp, ip, flags); error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) fail(_("Directory creation failed"), error); libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, 0); /* * RT initialization. Do this here to ensure that * the RT inodes get placed after the root inode. */ if (isroot) rtinit(mp); tp = NULL; for (;;) { name = getstr(pp); if (!name) break; if (strcmp(name, "$") == 0) break; parseproto(mp, ip, fsxp, pp, name); } libxfs_iput(ip, 0); return; } libxfs_trans_log_inode(tp, ip, flags); error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Error encountered creating file from prototype file"), error); } libxfs_trans_commit(tp, 0); } void parse_proto( xfs_mount_t *mp, struct fsxattr *fsx, char **pp) { parseproto(mp, NULL, fsx, pp, NULL); } /* * Allocate the realtime bitmap and summary inodes, and fill in data if any. */ static void rtinit( xfs_mount_t *mp) { xfs_dfiloff_t bno; int committed; xfs_dfiloff_t ebno; xfs_bmbt_irec_t *ep; int error; xfs_fsblock_t first; xfs_bmap_free_t flist; int i; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; xfs_extlen_t nsumblocks; int nmap; xfs_inode_t *rbmip; xfs_inode_t *rsumip; xfs_trans_t *tp; struct cred creds; struct fsxattr fsxattrs; /* * First, allocate the inodes. */ tp = libxfs_trans_alloc(mp, 0); if ((i = libxfs_trans_reserve(tp, MKFS_BLOCKRES_INODE, 0, 0, 0, 0))) res_failed(i); memset(&creds, 0, sizeof(creds)); memset(&fsxattrs, 0, sizeof(fsxattrs)); error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs, &rbmip); if (error) { fail(_("Realtime bitmap inode allocation failed"), error); } /* * Do our thing with rbmip before allocating rsumip, * because the next call to ialloc() may * commit the transaction in which rbmip was allocated. */ mp->m_sb.sb_rbmino = rbmip->i_ino; rbmip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; rbmip->i_d.di_flags = XFS_DIFLAG_NEWRTBM; *(__uint64_t *)&rbmip->i_d.di_atime = 0; libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); libxfs_mod_sb(tp, XFS_SB_RBMINO); libxfs_trans_ihold(tp, rbmip); mp->m_rbmip = rbmip; error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs, &rsumip); if (error) { fail(_("Realtime summary inode allocation failed"), error); } mp->m_sb.sb_rsumino = rsumip->i_ino; rsumip->i_d.di_size = mp->m_rsumsize; libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE); libxfs_mod_sb(tp, XFS_SB_RSUMINO); libxfs_trans_ihold(tp, rsumip); libxfs_trans_commit(tp, 0); mp->m_rsumip = rsumip; /* * Next, give the bitmap file some zero-filled blocks. */ tp = libxfs_trans_alloc(mp, 0); if ((i = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0))) res_failed(i); libxfs_trans_ijoin(tp, rbmip, 0); libxfs_trans_ihold(tp, rbmip); bno = 0; xfs_bmap_init(&flist, &first); while (bno < mp->m_sb.sb_rbmblocks) { nmap = XFS_BMAP_MAX_NMAP; error = libxfs_bmapi(tp, rbmip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, map, &nmap, &flist); if (error) { fail(_("Allocation of the realtime bitmap failed"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { libxfs_device_zero(mp->m_dev, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; } } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Completion of the realtime bitmap failed"), error); } libxfs_trans_commit(tp, 0); /* * Give the summary file some zero-filled blocks. */ tp = libxfs_trans_alloc(mp, 0); nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog; if ((i = libxfs_trans_reserve(tp, nsumblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0))) res_failed(i); libxfs_trans_ijoin(tp, rsumip, 0); libxfs_trans_ihold(tp, rsumip); bno = 0; xfs_bmap_init(&flist, &first); while (bno < nsumblocks) { nmap = XFS_BMAP_MAX_NMAP; error = libxfs_bmapi(tp, rsumip, bno, (xfs_extlen_t)(nsumblocks - bno), XFS_BMAPI_WRITE, &first, nsumblocks, map, &nmap, &flist); if (error) { fail(_("Allocation of the realtime summary failed"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { libxfs_device_zero(mp->m_dev, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; } } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Completion of the realtime summary failed"), error); } libxfs_trans_commit(tp, 0); /* * Free the whole area using transactions. * Do one transaction per bitmap block. */ for (bno = 0; bno < mp->m_sb.sb_rextents; bno = ebno) { tp = libxfs_trans_alloc(mp, 0); if ((i = libxfs_trans_reserve(tp, 0, 0, 0, 0, 0))) res_failed(i); xfs_bmap_init(&flist, &first); ebno = XFS_RTMIN(mp->m_sb.sb_rextents, bno + NBBY * mp->m_sb.sb_blocksize); error = libxfs_rtfree_extent(tp, bno, (xfs_extlen_t)(ebno-bno)); if (error) { fail(_("Error initializing the realtime space"), error); } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { fail(_("Error completing the realtime space"), error); } libxfs_trans_commit(tp, 0); } } static long filesize( int fd) { struct stat64 stb; if (fstat64(fd, &stb) < 0) return -1; return (long)stb.st_size; } xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.c0000664000000000000000000022203612062210562014541 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #ifdef ENABLE_BLKID #include #else #include #include #endif #include "xfs_mkfs.h" /* * Device topology information. */ struct fs_topology { int dsunit; /* stripe unit - data subvolume */ int dswidth; /* stripe width - data subvolume */ int rtswidth; /* stripe width - rt subvolume */ int lsectorsize; /* logical sector size &*/ int psectorsize; /* physical sector size */ int sectoralign; }; /* * Prototypes for internal functions. */ static void conflict(char opt, char *tab[], int oldidx, int newidx); static void illegal(char *value, char *opt); static __attribute__((noreturn)) void usage (void); static __attribute__((noreturn)) void reqval(char opt, char *tab[], int idx); static void respec(char opt, char *tab[], int idx); static void unknown(char opt, char *s); static int ispow2(unsigned int i); /* * option tables for getsubopt calls */ char *bopts[] = { #define B_LOG 0 "log", #define B_SIZE 1 "size", NULL }; char *dopts[] = { #define D_AGCOUNT 0 "agcount", #define D_FILE 1 "file", #define D_NAME 2 "name", #define D_SIZE 3 "size", #define D_SUNIT 4 "sunit", #define D_SWIDTH 5 "swidth", #define D_AGSIZE 6 "agsize", #define D_SU 7 "su", #define D_SW 8 "sw", #define D_SECTLOG 9 "sectlog", #define D_SECTSIZE 10 "sectsize", #define D_NOALIGN 11 "noalign", #define D_RTINHERIT 12 "rtinherit", #define D_PROJINHERIT 13 "projinherit", #define D_EXTSZINHERIT 14 "extszinherit", NULL }; char *iopts[] = { #define I_ALIGN 0 "align", #define I_LOG 1 "log", #define I_MAXPCT 2 "maxpct", #define I_PERBLOCK 3 "perblock", #define I_SIZE 4 "size", #define I_ATTR 5 "attr", #define I_PROJID32BIT 6 "projid32bit", NULL }; char *lopts[] = { #define L_AGNUM 0 "agnum", #define L_INTERNAL 1 "internal", #define L_SIZE 2 "size", #define L_VERSION 3 "version", #define L_SUNIT 4 "sunit", #define L_SU 5 "su", #define L_DEV 6 "logdev", #define L_SECTLOG 7 "sectlog", #define L_SECTSIZE 8 "sectsize", #define L_FILE 9 "file", #define L_NAME 10 "name", #define L_LAZYSBCNTR 11 "lazy-count", NULL }; char *nopts[] = { #define N_LOG 0 "log", #define N_SIZE 1 "size", #define N_VERSION 2 "version", NULL, }; char *ropts[] = { #define R_EXTSIZE 0 "extsize", #define R_SIZE 1 "size", #define R_DEV 2 "rtdev", #define R_FILE 3 "file", #define R_NAME 4 "name", #define R_NOALIGN 5 "noalign", NULL }; char *sopts[] = { #define S_LOG 0 "log", #define S_SECTLOG 1 "sectlog", #define S_SIZE 2 "size", #define S_SECTSIZE 3 "sectsize", NULL }; #define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog))) #define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog))) #define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog))) /* * Use this macro before we have superblock and mount structure */ #define DTOBT(d) ((xfs_drfsbno_t)((d) >> (blocklog - BBSHIFT))) /* * Use this for block reservations needed for mkfs's conditions * (basically no fragmentation). */ #define MKFS_BLOCKRES_INODE \ ((uint)(XFS_IALLOC_BLOCKS(mp) + (XFS_IN_MAXLEVELS(mp) - 1))) #define MKFS_BLOCKRES(rb) \ ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \ (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb))) /* amount (in bytes) we zero at the beginning and end of the device to * remove traces of other filesystems, raid superblocks, etc. */ #define WHACK_SIZE (128 * 1024) static void calc_stripe_factors( int dsu, int dsw, int dsectsz, int lsu, int lsectsz, int *dsunit, int *dswidth, int *lsunit) { /* Handle data sunit/swidth options */ if (*dsunit || *dswidth) { if (dsu || dsw) { fprintf(stderr, _("data su/sw must not be used in " "conjunction with data sunit/swidth\n")); usage(); } if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) { fprintf(stderr, _("both data sunit and data swidth options " "must be specified\n")); usage(); } } if (dsu || dsw) { if (*dsunit || *dswidth) { fprintf(stderr, _("data sunit/swidth must not be used in " "conjunction with data su/sw\n")); usage(); } if ((dsu && !dsw) || (!dsu && dsw)) { fprintf(stderr, _("both data su and data sw options " "must be specified\n")); usage(); } if (dsu % dsectsz) { fprintf(stderr, _("data su must be a multiple of the " "sector size (%d)\n"), dsectsz); usage(); } *dsunit = (int)BTOBBT(dsu); *dswidth = *dsunit * dsw; } if (*dsunit && (*dswidth % *dsunit != 0)) { fprintf(stderr, _("data stripe width (%d) must be a multiple of the " "data stripe unit (%d)\n"), *dswidth, *dsunit); usage(); } /* Handle log sunit options */ if (*lsunit) { if (lsu) { fprintf(stderr, _("log su should not be used in " "conjunction with log sunit\n")); usage(); } } if (lsu) { if (*lsunit) { fprintf(stderr, _("log sunit should not be used in " "conjunction with log su\n")); usage(); } *lsunit = (int)BTOBBT(lsu); } } #ifdef ENABLE_BLKID /* * Check for existing filesystem or partition table on device. * Returns: * 1 for existing fs or partition * 0 for nothing found * -1 for internal error */ static int check_overwrite( char *device) { const char *type; blkid_probe pr = NULL; int ret; int fd; long long size; int bsz; if (!device || !*device) return 0; ret = -1; /* will reset on success of all setup calls */ fd = open(device, O_RDONLY); if (fd < 0) goto out; platform_findsizes(device, fd, &size, &bsz); close(fd); /* nothing to overwrite on a 0-length device */ if (size == 0) { ret = 0; goto out; } pr = blkid_new_probe_from_filename(device); if (!pr) goto out; ret = blkid_probe_enable_partitions(pr, 1); if (ret < 0) goto out; ret = blkid_do_fullprobe(pr); if (ret < 0) goto out; /* * Blkid returns 1 for nothing found and 0 when it finds a signature, * but we want the exact opposite, so reverse the return value here. * * In addition print some useful diagnostics about what actually is * on the device. */ if (ret) { ret = 0; goto out; } if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { fprintf(stderr, _("%s: %s appears to contain an existing " "filesystem (%s).\n"), progname, device, type); } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { fprintf(stderr, _("%s: %s appears to contain a partition " "table (%s).\n"), progname, device, type); } else { fprintf(stderr, _("%s: %s appears to contain something weird " "according to blkid\n"), progname, device); } ret = 1; out: if (pr) blkid_free_probe(pr); if (ret == -1) fprintf(stderr, _("%s: probe of %s failed, cannot detect " "existing filesystem.\n"), progname, device); return ret; } static void blkid_get_topology( const char *device, int *sunit, int *swidth, int *lsectorsize, int *psectorsize, int force_overwrite) { blkid_topology tp; blkid_probe pr; unsigned long val; struct stat statbuf; /* can't get topology info from a file */ if (!stat(device, &statbuf) && S_ISREG(statbuf.st_mode)) return; pr = blkid_new_probe_from_filename(device); if (!pr) return; tp = blkid_probe_get_topology(pr); if (!tp) goto out_free_probe; /* * Blkid reports the information in terms of bytes, but we want it in * terms of 512 bytes blocks (just to convert it to bytes later..) * * If the reported values are just the normal 512 byte block size * do not bother to report anything. It will just causes warnings * if people specifier larger stripe units or widths manually. */ val = blkid_topology_get_minimum_io_size(tp) >> 9; if (val > 1) *sunit = val; val = blkid_topology_get_optimal_io_size(tp) >> 9; if (val > 1) *swidth = val; val = blkid_topology_get_logical_sector_size(tp); *lsectorsize = val; val = blkid_topology_get_physical_sector_size(tp); *psectorsize = val; if (blkid_topology_get_alignment_offset(tp) != 0) { fprintf(stderr, _("warning: device is not properly aligned %s\n"), device); if (!force_overwrite) { fprintf(stderr, _("Use -f to force usage of a misaligned device\n")); exit(EXIT_FAILURE); } /* Do not use physical sector size if the device is misaligned */ *psectorsize = *lsectorsize; } blkid_free_probe(pr); return; out_free_probe: blkid_free_probe(pr); fprintf(stderr, _("warning: unable to probe device toplology for device %s\n"), device); } static void get_topology( libxfs_init_t *xi, struct fs_topology *ft, int force_overwrite) { if (!xi->disfile) { const char *dfile = xi->volname ? xi->volname : xi->dname; blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth, &ft->lsectorsize, &ft->psectorsize, force_overwrite); } if (xi->rtname && !xi->risfile) { int dummy; blkid_get_topology(xi->rtname, &dummy, &ft->rtswidth, &dummy, &dummy, force_overwrite); } } #else /* ENABLE_BLKID */ static int check_overwrite( char *device) { char *type; if (device && *device) { if ((type = fstype(device)) != NULL) { fprintf(stderr, _("%s: %s appears to contain an existing " "filesystem (%s).\n"), progname, device, type); return 1; } if ((type = pttype(device)) != NULL) { fprintf(stderr, _("%s: %s appears to contain a partition " "table (%s).\n"), progname, device, type); return 1; } } return 0; } static void get_topology( libxfs_init_t *xi, struct fs_topology *ft, int force_overwrite) { char *dfile = xi->volname ? xi->volname : xi->dname; int bsz = BBSIZE; if (!xi->disfile) { int fd; long long dummy; get_subvol_stripe_wrapper(dfile, SVTYPE_DATA, &ft->dsunit, &ft->dswidth, &ft->sectoralign); fd = open(dfile, O_RDONLY); /* If this fails we just fall back to BBSIZE */ if (fd >= 0) { platform_findsizes(dfile, fd, &dummy, &bsz); close(fd); } } ft->lsectorsize = bsz; ft->psectorsize = bsz; if (xi->rtname && !xi->risfile) { int dummy1; get_subvol_stripe_wrapper(dfile, SVTYPE_RT, &dummy1, &ft->rtswidth, &dummy1); } } #endif /* ENABLE_BLKID */ static void fixup_log_stripe_unit( int lsflag, int sunit, xfs_drfsbno_t *logblocks, int blocklog) { __uint64_t tmp_logblocks; /* * Make sure that the log size is a multiple of the stripe unit */ if ((*logblocks % sunit) != 0) { if (!lsflag) { tmp_logblocks = ((*logblocks + (sunit - 1)) / sunit) * sunit; /* * If the log is too large, round down * instead of round up */ if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) || ((tmp_logblocks << blocklog) > XFS_MAX_LOG_BYTES)) { tmp_logblocks = (*logblocks / sunit) * sunit; } *logblocks = tmp_logblocks; } else { fprintf(stderr, _("log size %lld is not a multiple " "of the log stripe unit %d\n"), (long long) *logblocks, sunit); usage(); } } } static xfs_dfsbno_t fixup_internal_log_stripe( xfs_mount_t *mp, int lsflag, xfs_dfsbno_t logstart, __uint64_t agsize, int sunit, xfs_drfsbno_t *logblocks, int blocklog, int *lalign) { if ((logstart % sunit) != 0) { logstart = ((logstart + (sunit - 1))/sunit) * sunit; *lalign = 1; } fixup_log_stripe_unit(lsflag, sunit, logblocks, blocklog); if (*logblocks > agsize - XFS_FSB_TO_AGBNO(mp, logstart)) { fprintf(stderr, _("Due to stripe alignment, the internal log size " "(%lld) is too large.\n"), (long long) *logblocks); fprintf(stderr, _("Must fit within an allocation group.\n")); usage(); } return logstart; } void validate_log_size(__uint64_t logblocks, int blocklog, int min_logblocks) { if (logblocks < min_logblocks) { fprintf(stderr, _("log size %lld blocks too small, minimum size is %d blocks\n"), (long long)logblocks, min_logblocks); usage(); } if (logblocks > XFS_MAX_LOG_BLOCKS) { fprintf(stderr, _("log size %lld blocks too large, maximum size is %lld blocks\n"), (long long)logblocks, XFS_MAX_LOG_BLOCKS); usage(); } if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) { fprintf(stderr, _("log size %lld bytes too large, maximum size is %lld bytes\n"), (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES); usage(); } } static int calc_default_imaxpct( int blocklog, __uint64_t dblocks) { /* * This returns the % of the disk space that is used for * inodes, it changes relatively to the FS size: * - over 50 TB, use 1%, * - 1TB - 50 TB, use 5%, * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%). */ if (dblocks < TERABYTES(1, blocklog)) { return XFS_DFL_IMAXIMUM_PCT; } else if (dblocks < TERABYTES(50, blocklog)) { return 5; } return 1; } void calc_default_ag_geometry( int blocklog, __uint64_t dblocks, int multidisk, __uint64_t *agsize, __uint64_t *agcount) { __uint64_t blocks = 0; int shift = 0; /* * First handle the high extreme - the point at which we will * always use the maximum AG size. * * This applies regardless of storage configuration. */ if (dblocks >= TERABYTES(32, blocklog)) { blocks = XFS_AG_MAX_BLOCKS(blocklog); goto done; } /* * For the remainder we choose an AG size based on the * number of data blocks available, trying to keep the * number of AGs relatively small (especially compared * to the original algorithm). AG count is calculated * based on the preferred AG size, not vice-versa - the * count can be increased by growfs, so prefer to use * smaller counts at mkfs time. * * For a single underlying storage device between 128MB * and 4TB in size, just use 4 AGs, otherwise scale up * smoothly between min/max AG sizes. */ if (!multidisk && dblocks >= MEGABYTES(128, blocklog)) { if (dblocks >= TERABYTES(4, blocklog)) { blocks = XFS_AG_MAX_BLOCKS(blocklog); goto done; } shift = 2; } else if (dblocks > GIGABYTES(512, blocklog)) shift = 5; else if (dblocks > GIGABYTES(8, blocklog)) shift = 4; else if (dblocks >= MEGABYTES(128, blocklog)) shift = 3; else if (dblocks >= MEGABYTES(64, blocklog)) shift = 2; else if (dblocks >= MEGABYTES(32, blocklog)) shift = 1; else shift = 0; /* * If dblocks is not evenly divisible by the number of * desired AGs, round "blocks" up so we don't lose the * last bit of the filesystem. The same principle applies * to the AG count, so we don't lose the last AG! */ blocks = dblocks >> shift; if (dblocks & xfs_mask32lo(shift)) { if (blocks < XFS_AG_MAX_BLOCKS(blocklog)) blocks++; } done: *agsize = blocks; *agcount = dblocks / blocks + (dblocks % blocks != 0); } static void validate_ag_geometry( int blocklog, __uint64_t dblocks, __uint64_t agsize, __uint64_t agcount) { if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) { fprintf(stderr, _("agsize (%lld blocks) too small, need at least %lld blocks\n"), (long long)agsize, (long long)XFS_AG_MIN_BLOCKS(blocklog)); usage(); } if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) { fprintf(stderr, _("agsize (%lld blocks) too big, maximum is %lld blocks\n"), (long long)agsize, (long long)XFS_AG_MAX_BLOCKS(blocklog)); usage(); } if (agsize > dblocks) { fprintf(stderr, _("agsize (%lld blocks) too big, data area is %lld blocks\n"), (long long)agsize, (long long)dblocks); usage(); } if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) { fprintf(stderr, _("too many allocation groups for size = %lld\n"), (long long)agsize); fprintf(stderr, _("need at most %lld allocation groups\n"), (long long)(dblocks / XFS_AG_MIN_BLOCKS(blocklog) + (dblocks % XFS_AG_MIN_BLOCKS(blocklog) != 0))); usage(); } if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) { fprintf(stderr, _("too few allocation groups for size = %lld\n"), (long long)agsize); fprintf(stderr, _("need at least %lld allocation groups\n"), (long long)(dblocks / XFS_AG_MAX_BLOCKS(blocklog) + (dblocks % XFS_AG_MAX_BLOCKS(blocklog) != 0))); usage(); } /* * If the last AG is too small, reduce the filesystem size * and drop the blocks. */ if ( dblocks % agsize != 0 && (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) { fprintf(stderr, _("last AG size %lld blocks too small, minimum size is %lld blocks\n"), (long long)(dblocks % agsize), (long long)XFS_AG_MIN_BLOCKS(blocklog)); usage(); } /* * If agcount is too large, make it smaller. */ if (agcount > XFS_MAX_AGNUMBER + 1) { fprintf(stderr, _("%lld allocation groups is too many, maximum is %lld\n"), (long long)agcount, (long long)XFS_MAX_AGNUMBER + 1); usage(); } } static void zero_old_xfs_structures( libxfs_init_t *xi, xfs_sb_t *new_sb) { void *buf; xfs_sb_t sb; __uint32_t bsize; int i; xfs_off_t off; /* * read in existing filesystem superblock, use its geometry * settings and zero the existing secondary superblocks. */ buf = memalign(libxfs_device_alignment(), new_sb->sb_sectsize); if (!buf) { fprintf(stderr, _("error reading existing superblock -- failed to memalign buffer\n")); return; } memset(buf, 0, new_sb->sb_sectsize); if (pread(xi->dfd, buf, new_sb->sb_sectsize, 0) != new_sb->sb_sectsize) { fprintf(stderr, _("existing superblock read failed: %s\n"), strerror(errno)); free(buf); return; } libxfs_sb_from_disk(&sb, buf); /* * perform same basic superblock validation to make sure we * actually zero secondary blocks */ if (sb.sb_magicnum != XFS_SB_MAGIC || sb.sb_blocksize == 0) goto done; for (bsize = 1, i = 0; bsize < sb.sb_blocksize && i < sizeof(sb.sb_blocksize) * NBBY; i++) bsize <<= 1; if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG || i != sb.sb_blocklog) goto done; if (sb.sb_dblocks > ((__uint64_t)sb.sb_agcount * sb.sb_agblocks) || sb.sb_dblocks < ((__uint64_t)(sb.sb_agcount - 1) * sb.sb_agblocks + XFS_MIN_AG_BLOCKS)) goto done; /* * block size and basic geometry seems alright, zero the secondaries. */ memset(buf, 0, new_sb->sb_sectsize); off = 0; for (i = 1; i < sb.sb_agcount; i++) { off += sb.sb_agblocks; if (pwrite64(xi->dfd, buf, new_sb->sb_sectsize, off << sb.sb_blocklog) == -1) break; } done: free(buf); } static void discard_blocks(dev_t dev, __uint64_t nsectors) { int fd; /* * We intentionally ignore errors from the discard ioctl. It is * not necessary for the mkfs functionality but just an optimization. */ fd = libxfs_device_to_fd(dev); if (fd > 0) platform_discard_blocks(fd, 0, nsectors << 9); } int main( int argc, char **argv) { __uint64_t agcount; xfs_agf_t *agf; xfs_agi_t *agi; xfs_agnumber_t agno; __uint64_t agsize; xfs_alloc_rec_t *arec; int attrversion; int projid32bit; struct xfs_btree_block *block; int blflag; int blocklog; unsigned int blocksize; int bsflag; int bsize; xfs_buf_t *buf; int c; int daflag; int dasize; xfs_drfsbno_t dblocks; char *dfile; int dirblocklog; int dirblocksize; int dirversion; char *dsize; int dsu; int dsw; int dsunit; int dswidth; int force_overwrite; struct fsxattr fsx; int iaflag; int ilflag; int imaxpct; int imflag; int inodelog; int inopblock; int ipflag; int isflag; int isize; char *label = NULL; int laflag; int lalign; int ldflag; int liflag; xfs_agnumber_t logagno; xfs_drfsbno_t logblocks; char *logfile; int loginternal; char *logsize; xfs_dfsbno_t logstart; int logversion; int lvflag; int lsflag; int lsectorlog; int lsectorsize; int lslflag; int lssflag; int lsu; int lsunit; int max_tr_res; int min_logblocks; xfs_mount_t *mp; xfs_mount_t mbuf; xfs_extlen_t nbmblocks; int nlflag; int nodsflag; int norsflag; xfs_alloc_rec_t *nrec; int nsflag; int nvflag; int nci; int Nflag; int discard = 1; char *p; char *protofile; char *protostring; int qflag; xfs_drfsbno_t rtblocks; xfs_extlen_t rtextblocks; xfs_drtbno_t rtextents; char *rtextsize; char *rtfile; char *rtsize; xfs_sb_t *sbp; int sectorlog; unsigned int sectorsize; __uint64_t sector_mask; int slflag; int ssflag; __uint64_t tmp_agsize; uuid_t uuid; int worst_freelist; libxfs_init_t xi; struct fs_topology ft; int lazy_sb_counters; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); attrversion = 2; projid32bit = 0; blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0; blocklog = blocksize = 0; sectorlog = lsectorlog = XFS_MIN_SECTORSIZE_LOG; sectorsize = lsectorsize = XFS_MIN_SECTORSIZE; agsize = daflag = dasize = dblocks = 0; ilflag = imflag = ipflag = isflag = 0; liflag = laflag = lsflag = ldflag = lvflag = 0; loginternal = 1; logversion = 2; logagno = logblocks = rtblocks = rtextblocks = 0; Nflag = nlflag = nsflag = nvflag = nci = 0; dirblocklog = dirblocksize = 0; dirversion = XFS_DFL_DIR_VERSION; qflag = 0; imaxpct = inodelog = inopblock = isize = 0; iaflag = XFS_IFLAG_ALIGN; dfile = logfile = rtfile = NULL; dsize = logsize = rtsize = rtextsize = protofile = NULL; dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0; nodsflag = norsflag = 0; force_overwrite = 0; worst_freelist = 0; lazy_sb_counters = 1; memset(&fsx, 0, sizeof(fsx)); memset(&xi, 0, sizeof(xi)); xi.isdirect = LIBXFS_DIRECT; xi.isreadonly = LIBXFS_EXCLUSIVELY; while ((c = getopt(argc, argv, "b:d:i:l:L:n:KNp:qr:s:CfV")) != EOF) { switch (c) { case 'C': case 'f': force_overwrite = 1; break; case 'b': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)bopts, &value)) { case B_LOG: if (!value || *value == '\0') reqval('b', bopts, B_LOG); if (blflag) respec('b', bopts, B_LOG); if (bsflag) conflict('b', bopts, B_SIZE, B_LOG); blocklog = atoi(value); if (blocklog <= 0) illegal(value, "b log"); blocksize = 1 << blocklog; blflag = 1; break; case B_SIZE: if (!value || *value == '\0') reqval('b', bopts, B_SIZE); if (bsflag) respec('b', bopts, B_SIZE); if (blflag) conflict('b', bopts, B_LOG, B_SIZE); blocksize = cvtnum( blocksize, sectorsize, value); if (blocksize <= 0 || !ispow2(blocksize)) illegal(value, "b size"); blocklog = libxfs_highbit32(blocksize); bsflag = 1; break; default: unknown('b', value); } } break; case 'd': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)dopts, &value)) { case D_AGCOUNT: if (!value || *value == '\0') reqval('d', dopts, D_AGCOUNT); if (daflag) respec('d', dopts, D_AGCOUNT); agcount = (__uint64_t) strtoul(value, NULL, 10); if ((__int64_t)agcount <= 0) illegal(value, "d agcount"); daflag = 1; break; case D_AGSIZE: if (!value || *value == '\0') reqval('d', dopts, D_AGSIZE); if (dasize) respec('d', dopts, D_AGSIZE); agsize = cvtnum( blocksize, sectorsize, value); dasize = 1; break; case D_FILE: if (!value || *value == '\0') value = "1"; xi.disfile = atoi(value); if (xi.disfile < 0 || xi.disfile > 1) illegal(value, "d file"); if (xi.disfile && !Nflag) xi.dcreat = 1; break; case D_NAME: if (!value || *value == '\0') reqval('d', dopts, D_NAME); if (xi.dname) respec('d', dopts, D_NAME); xi.dname = value; break; case D_SIZE: if (!value || *value == '\0') reqval('d', dopts, D_SIZE); if (dsize) respec('d', dopts, D_SIZE); dsize = value; break; case D_SUNIT: if (!value || *value == '\0') reqval('d', dopts, D_SUNIT); if (dsunit) respec('d', dopts, D_SUNIT); if (nodsflag) conflict('d', dopts, D_NOALIGN, D_SUNIT); if (!isdigits(value)) { fprintf(stderr, _("%s: Specify data sunit in 512-byte blocks, no unit suffix\n"), progname); exit(1); } dsunit = cvtnum(0, 0, value); break; case D_SWIDTH: if (!value || *value == '\0') reqval('d', dopts, D_SWIDTH); if (dswidth) respec('d', dopts, D_SWIDTH); if (nodsflag) conflict('d', dopts, D_NOALIGN, D_SWIDTH); if (!isdigits(value)) { fprintf(stderr, _("%s: Specify data swidth in 512-byte blocks, no unit suffix\n"), progname); exit(1); } dswidth = cvtnum(0, 0, value); break; case D_SU: if (!value || *value == '\0') reqval('d', dopts, D_SU); if (dsu) respec('d', dopts, D_SU); if (nodsflag) conflict('d', dopts, D_NOALIGN, D_SU); dsu = cvtnum( blocksize, sectorsize, value); break; case D_SW: if (!value || *value == '\0') reqval('d', dopts, D_SW); if (dsw) respec('d', dopts, D_SW); if (nodsflag) conflict('d', dopts, D_NOALIGN, D_SW); if (!isdigits(value)) { fprintf(stderr, _("%s: Specify data sw as multiple of su, no unit suffix\n"), progname); exit(1); } dsw = cvtnum(0, 0, value); break; case D_NOALIGN: if (dsu) conflict('d', dopts, D_SU, D_NOALIGN); if (dsunit) conflict('d', dopts, D_SUNIT, D_NOALIGN); if (dsw) conflict('d', dopts, D_SW, D_NOALIGN); if (dswidth) conflict('d', dopts, D_SWIDTH, D_NOALIGN); nodsflag = 1; break; case D_SECTLOG: if (!value || *value == '\0') reqval('d', dopts, D_SECTLOG); if (slflag) respec('d', dopts, D_SECTLOG); if (ssflag) conflict('d', dopts, D_SECTSIZE, D_SECTLOG); sectorlog = atoi(value); if (sectorlog <= 0) illegal(value, "d sectlog"); sectorsize = 1 << sectorlog; slflag = 1; break; case D_SECTSIZE: if (!value || *value == '\0') reqval('d', dopts, D_SECTSIZE); if (ssflag) respec('d', dopts, D_SECTSIZE); if (slflag) conflict('d', dopts, D_SECTLOG, D_SECTSIZE); sectorsize = cvtnum( blocksize, sectorsize, value); if (sectorsize <= 0 || !ispow2(sectorsize)) illegal(value, "d sectsize"); sectorlog = libxfs_highbit32(sectorsize); ssflag = 1; break; case D_RTINHERIT: fsx.fsx_xflags |= \ XFS_DIFLAG_RTINHERIT; break; case D_PROJINHERIT: if (!value || *value == '\0') reqval('d', dopts, D_PROJINHERIT); fsx.fsx_projid = atoi(value); fsx.fsx_xflags |= \ XFS_DIFLAG_PROJINHERIT; break; case D_EXTSZINHERIT: if (!value || *value == '\0') reqval('d', dopts, D_EXTSZINHERIT); fsx.fsx_extsize = atoi(value); fsx.fsx_xflags |= \ XFS_DIFLAG_EXTSZINHERIT; break; default: unknown('d', value); } } break; case 'i': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)iopts, &value)) { case I_ALIGN: if (!value || *value == '\0') value = "1"; iaflag = atoi(value); if (iaflag < 0 || iaflag > 1) illegal(value, "i align"); break; case I_LOG: if (!value || *value == '\0') reqval('i', iopts, I_LOG); if (ilflag) respec('i', iopts, I_LOG); if (ipflag) conflict('i', iopts, I_PERBLOCK, I_LOG); if (isflag) conflict('i', iopts, I_SIZE, I_LOG); inodelog = atoi(value); if (inodelog <= 0) illegal(value, "i log"); isize = 1 << inodelog; ilflag = 1; break; case I_MAXPCT: if (!value || *value == '\0') reqval('i', iopts, I_MAXPCT); if (imflag) respec('i', iopts, I_MAXPCT); imaxpct = atoi(value); if (imaxpct < 0 || imaxpct > 100) illegal(value, "i maxpct"); imflag = 1; break; case I_PERBLOCK: if (!value || *value == '\0') reqval('i', iopts, I_PERBLOCK); if (ilflag) conflict('i', iopts, I_LOG, I_PERBLOCK); if (ipflag) respec('i', iopts, I_PERBLOCK); if (isflag) conflict('i', iopts, I_SIZE, I_PERBLOCK); inopblock = atoi(value); if (inopblock < XFS_MIN_INODE_PERBLOCK || !ispow2(inopblock)) illegal(value, "i perblock"); ipflag = 1; break; case I_SIZE: if (!value || *value == '\0') reqval('i', iopts, I_SIZE); if (ilflag) conflict('i', iopts, I_LOG, I_SIZE); if (ipflag) conflict('i', iopts, I_PERBLOCK, I_SIZE); if (isflag) respec('i', iopts, I_SIZE); isize = cvtnum(0, 0, value); if (isize <= 0 || !ispow2(isize)) illegal(value, "i size"); inodelog = libxfs_highbit32(isize); isflag = 1; break; case I_ATTR: if (!value || *value == '\0') reqval('i', iopts, I_ATTR); c = atoi(value); if (c < 0 || c > 2) illegal(value, "i attr"); attrversion = c; break; case I_PROJID32BIT: if (!value || *value == '\0') value = "0"; c = atoi(value); if (c < 0 || c > 1) illegal(value, "i projid32bit"); projid32bit = c; break; default: unknown('i', value); } } break; case 'l': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)lopts, &value)) { case L_AGNUM: if (!value || *value == '\0') reqval('l', lopts, L_AGNUM); if (laflag) respec('l', lopts, L_AGNUM); if (ldflag) conflict('l', lopts, L_AGNUM, L_DEV); logagno = atoi(value); laflag = 1; break; case L_FILE: if (!value || *value == '\0') value = "1"; if (loginternal) conflict('l', lopts, L_INTERNAL, L_FILE); xi.lisfile = atoi(value); if (xi.lisfile < 0 || xi.lisfile > 1) illegal(value, "l file"); if (xi.lisfile) xi.lcreat = 1; break; case L_INTERNAL: if (!value || *value == '\0') value = "1"; if (ldflag) conflict('l', lopts, L_INTERNAL, L_DEV); if (xi.lisfile) conflict('l', lopts, L_FILE, L_INTERNAL); if (liflag) respec('l', lopts, L_INTERNAL); loginternal = atoi(value); if (loginternal < 0 || loginternal > 1) illegal(value, "l internal"); liflag = 1; break; case L_SU: if (!value || *value == '\0') reqval('l', lopts, L_SU); if (lsu) respec('l', lopts, L_SU); lsu = cvtnum( blocksize, sectorsize, value); break; case L_SUNIT: if (!value || *value == '\0') reqval('l', lopts, L_SUNIT); if (lsunit) respec('l', lopts, L_SUNIT); if (!isdigits(value)) { fprintf(stderr, _("Specify log sunit in 512-byte blocks, no size suffix\n")); usage(); } lsunit = cvtnum(0, 0, value); break; case L_NAME: case L_DEV: if (laflag) conflict('l', lopts, L_AGNUM, L_DEV); if (liflag) conflict('l', lopts, L_INTERNAL, L_DEV); if (!value || *value == '\0') reqval('l', lopts, L_NAME); if (xi.logname) respec('l', lopts, L_NAME); ldflag = 1; loginternal = 0; logfile = value; xi.logname = value; break; case L_VERSION: if (!value || *value == '\0') reqval('l', lopts, L_VERSION); if (lvflag) respec('l', lopts, L_VERSION); logversion = atoi(value); if (logversion < 1 || logversion > 2) illegal(value, "l version"); lvflag = 1; break; case L_SIZE: if (!value || *value == '\0') reqval('l', lopts, L_SIZE); if (logsize) respec('l', lopts, L_SIZE); logsize = value; lsflag = 1; break; case L_SECTLOG: if (!value || *value == '\0') reqval('l', lopts, L_SECTLOG); if (lslflag) respec('l', lopts, L_SECTLOG); if (lssflag) conflict('l', lopts, L_SECTSIZE, L_SECTLOG); lsectorlog = atoi(value); if (lsectorlog <= 0) illegal(value, "l sectlog"); lsectorsize = 1 << lsectorlog; lslflag = 1; break; case L_SECTSIZE: if (!value || *value == '\0') reqval('l', lopts, L_SECTSIZE); if (lssflag) respec('l', lopts, L_SECTSIZE); if (lslflag) conflict('l', lopts, L_SECTLOG, L_SECTSIZE); lsectorsize = cvtnum( blocksize, sectorsize, value); if (lsectorsize <= 0 || !ispow2(lsectorsize)) illegal(value, "l sectsize"); lsectorlog = libxfs_highbit32(lsectorsize); lssflag = 1; break; case L_LAZYSBCNTR: if (!value || *value == '\0') reqval('l', lopts, L_LAZYSBCNTR); c = atoi(value); if (c < 0 || c > 1) illegal(value, "l lazy-count"); lazy_sb_counters = c; break; default: unknown('l', value); } } break; case 'L': if (strlen(optarg) > sizeof(sbp->sb_fname)) illegal(optarg, "L"); label = optarg; break; case 'n': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)nopts, &value)) { case N_LOG: if (!value || *value == '\0') reqval('n', nopts, N_LOG); if (nlflag) respec('n', nopts, N_LOG); if (nsflag) conflict('n', nopts, N_SIZE, N_LOG); dirblocklog = atoi(value); if (dirblocklog <= 0) illegal(value, "n log"); dirblocksize = 1 << dirblocklog; nlflag = 1; break; case N_SIZE: if (!value || *value == '\0') reqval('n', nopts, N_SIZE); if (nsflag) respec('n', nopts, N_SIZE); if (nlflag) conflict('n', nopts, N_LOG, N_SIZE); dirblocksize = cvtnum( blocksize, sectorsize, value); if (dirblocksize <= 0 || !ispow2(dirblocksize)) illegal(value, "n size"); dirblocklog = libxfs_highbit32(dirblocksize); nsflag = 1; break; case N_VERSION: if (!value || *value == '\0') reqval('n', nopts, N_VERSION); if (nvflag) respec('n', nopts, N_VERSION); if (!strcasecmp(value, "ci")) { nci = 1; /* ASCII CI mode */ } else { dirversion = atoi(value); if (dirversion != 2) illegal(value, "n version"); } nvflag = 1; break; default: unknown('n', value); } } break; case 'N': Nflag = 1; break; case 'K': discard = 0; break; case 'p': if (protofile) respec('p', NULL, 0); protofile = optarg; break; case 'q': qflag = 1; break; case 'r': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)ropts, &value)) { case R_EXTSIZE: if (!value || *value == '\0') reqval('r', ropts, R_EXTSIZE); if (rtextsize) respec('r', ropts, R_EXTSIZE); rtextsize = value; break; case R_FILE: if (!value || *value == '\0') value = "1"; xi.risfile = atoi(value); if (xi.risfile < 0 || xi.risfile > 1) illegal(value, "r file"); if (xi.risfile) xi.rcreat = 1; break; case R_NAME: case R_DEV: if (!value || *value == '\0') reqval('r', ropts, R_NAME); if (xi.rtname) respec('r', ropts, R_NAME); xi.rtname = value; break; case R_SIZE: if (!value || *value == '\0') reqval('r', ropts, R_SIZE); if (rtsize) respec('r', ropts, R_SIZE); rtsize = value; break; case R_NOALIGN: norsflag = 1; break; default: unknown('r', value); } } break; case 's': p = optarg; while (*p != '\0') { char *value; switch (getsubopt(&p, (constpp)sopts, &value)) { case S_LOG: case S_SECTLOG: if (!value || *value == '\0') reqval('s', sopts, S_SECTLOG); if (slflag || lslflag) respec('s', sopts, S_SECTLOG); if (ssflag || lssflag) conflict('s', sopts, S_SECTSIZE, S_SECTLOG); sectorlog = atoi(value); if (sectorlog <= 0) illegal(value, "s sectlog"); lsectorlog = sectorlog; sectorsize = 1 << sectorlog; lsectorsize = sectorsize; lslflag = slflag = 1; break; case S_SIZE: case S_SECTSIZE: if (!value || *value == '\0') reqval('s', sopts, S_SECTSIZE); if (ssflag || lssflag) respec('s', sopts, S_SECTSIZE); if (slflag || lslflag) conflict('s', sopts, S_SECTLOG, S_SECTSIZE); sectorsize = cvtnum( blocksize, sectorsize, value); if (sectorsize <= 0 || !ispow2(sectorsize)) illegal(value, "s sectsize"); lsectorsize = sectorsize; sectorlog = libxfs_highbit32(sectorsize); lsectorlog = sectorlog; lssflag = ssflag = 1; break; default: unknown('s', value); } } break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': unknown(optopt, ""); } } if (argc - optind > 1) { fprintf(stderr, _("extra arguments\n")); usage(); } else if (argc - optind == 1) { dfile = xi.volname = argv[optind]; if (xi.dname) { fprintf(stderr, _("cannot specify both %s and -d name=%s\n"), xi.volname, xi.dname); usage(); } } else dfile = xi.dname; /* * Blocksize and sectorsize first, other things depend on them * For RAID4/5/6 we want to align sector size and block size, * so we need to start with the device geometry extraction too. */ if (!blflag && !bsflag) { blocklog = XFS_DFL_BLOCKSIZE_LOG; blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG; } if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) { fprintf(stderr, _("illegal block size %d\n"), blocksize); usage(); } memset(&ft, 0, sizeof(ft)); get_topology(&xi, &ft, force_overwrite); if (ft.sectoralign) { /* * Older Linux software RAID versions want the sector size * to match the block size to avoid switching I/O sizes. * For the legacy libdisk case we thus set the sector size to * match the block size. For systems using libblkid we assume * that the kernel is recent enough to not require this and * ft.sectoralign will never be set. */ sectorsize = blocksize; } else if (!ssflag) { /* * Unless specified manually on the command line use the * advertised sector size of the device. We use the physical * sector size unless the requested block size is smaller * than that, then we can use logical, but warn about the * inefficiency. */ /* Older kernels may not have physical/logical distinction */ if (!ft.psectorsize) ft.psectorsize = ft.lsectorsize; sectorsize = ft.psectorsize ? ft.psectorsize : XFS_MIN_SECTORSIZE; if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) { fprintf(stderr, _("specified blocksize %d is less than device physical sector size %d\n"), blocksize, ft.psectorsize); fprintf(stderr, _("switching to logical sector size %d\n"), ft.lsectorsize); sectorsize = ft.lsectorsize ? ft.lsectorsize : XFS_MIN_SECTORSIZE; } } if (ft.sectoralign || !ssflag) { sectorlog = libxfs_highbit32(sectorsize); if (loginternal) { lsectorsize = sectorsize; lsectorlog = sectorlog; } } if (sectorsize < XFS_MIN_SECTORSIZE || sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) { if (ssflag) fprintf(stderr, _("illegal sector size %d\n"), sectorsize); else fprintf(stderr, _("block size %d cannot be smaller than logical sector size %d\n"), blocksize, ft.lsectorsize); usage(); } if (sectorsize < ft.lsectorsize) { fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"), sectorsize, ft.lsectorsize); usage(); } if (lsectorsize < XFS_MIN_SECTORSIZE || lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) { fprintf(stderr, _("illegal log sector size %d\n"), lsectorsize); usage(); } else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) { lsu = blocksize; logversion = 2; } if (nsflag || nlflag) { if (dirblocksize < blocksize || dirblocksize > XFS_MAX_BLOCKSIZE) { fprintf(stderr, _("illegal directory block size %d\n"), dirblocksize); usage(); } } else { if (blocksize < (1 << XFS_MIN_REC_DIRSIZE)) dirblocklog = XFS_MIN_REC_DIRSIZE; else dirblocklog = blocklog; dirblocksize = 1 << dirblocklog; } if (daflag && dasize) { fprintf(stderr, _("both -d agcount= and agsize= specified, use one or the other\n")); usage(); } if (xi.disfile && (!dsize || !xi.dname)) { fprintf(stderr, _("if -d file then -d name and -d size are required\n")); usage(); } if (dsize) { __uint64_t dbytes; dbytes = cvtnum(blocksize, sectorsize, dsize); if (dbytes % XFS_MIN_BLOCKSIZE) { fprintf(stderr, _("illegal data length %lld, not a multiple of %d\n"), (long long)dbytes, XFS_MIN_BLOCKSIZE); usage(); } dblocks = (xfs_drfsbno_t)(dbytes >> blocklog); if (dbytes % blocksize) fprintf(stderr, _("warning: " "data length %lld not a multiple of %d, truncated to %lld\n"), (long long)dbytes, blocksize, (long long)(dblocks << blocklog)); } if (ipflag) { inodelog = blocklog - libxfs_highbit32(inopblock); isize = 1 << inodelog; } else if (!ilflag && !isflag) { inodelog = XFS_DINODE_DFL_LOG; isize = 1 << inodelog; } if (xi.lisfile && (!logsize || !xi.logname)) { fprintf(stderr, _("if -l file then -l name and -l size are required\n")); usage(); } if (logsize) { __uint64_t logbytes; logbytes = cvtnum(blocksize, sectorsize, logsize); if (logbytes % XFS_MIN_BLOCKSIZE) { fprintf(stderr, _("illegal log length %lld, not a multiple of %d\n"), (long long)logbytes, XFS_MIN_BLOCKSIZE); usage(); } logblocks = (xfs_drfsbno_t)(logbytes >> blocklog); if (logbytes % blocksize) fprintf(stderr, _("warning: log length %lld not a multiple of %d, truncated to %lld\n"), (long long)logbytes, blocksize, (long long)(logblocks << blocklog)); } if (xi.risfile && (!rtsize || !xi.rtname)) { fprintf(stderr, _("if -r file then -r name and -r size are required\n")); usage(); } if (rtsize) { __uint64_t rtbytes; rtbytes = cvtnum(blocksize, sectorsize, rtsize); if (rtbytes % XFS_MIN_BLOCKSIZE) { fprintf(stderr, _("illegal rt length %lld, not a multiple of %d\n"), (long long)rtbytes, XFS_MIN_BLOCKSIZE); usage(); } rtblocks = (xfs_drfsbno_t)(rtbytes >> blocklog); if (rtbytes % blocksize) fprintf(stderr, _("warning: rt length %lld not a multiple of %d, truncated to %lld\n"), (long long)rtbytes, blocksize, (long long)(rtblocks << blocklog)); } /* * If specified, check rt extent size against its constraints. */ if (rtextsize) { __uint64_t rtextbytes; rtextbytes = cvtnum(blocksize, sectorsize, rtextsize); if (rtextbytes % blocksize) { fprintf(stderr, _("illegal rt extent size %lld, not a multiple of %d\n"), (long long)rtextbytes, blocksize); usage(); } if (rtextbytes > XFS_MAX_RTEXTSIZE) { fprintf(stderr, _("rt extent size %s too large, maximum %d\n"), rtextsize, XFS_MAX_RTEXTSIZE); usage(); } if (rtextbytes < XFS_MIN_RTEXTSIZE) { fprintf(stderr, _("rt extent size %s too small, minimum %d\n"), rtextsize, XFS_MIN_RTEXTSIZE); usage(); } rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog); } else { /* * If realtime extsize has not been specified by the user, * and the underlying volume is striped, then set rtextblocks * to the stripe width. */ int rswidth; __uint64_t rtextbytes; rswidth = 0; if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile)) rswidth = ft.rtswidth; else rswidth = 0; /* check that rswidth is a multiple of fs blocksize */ if (!norsflag && rswidth && !(BBTOB(rswidth) % blocksize)) { rswidth = DTOBT(rswidth); rtextbytes = rswidth << blocklog; if (XFS_MIN_RTEXTSIZE <= rtextbytes && (rtextbytes <= XFS_MAX_RTEXTSIZE)) { rtextblocks = rswidth; } } if (!rtextblocks) { rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ? XFS_MIN_RTEXTSIZE >> blocklog : 1; } } ASSERT(rtextblocks); /* * Check some argument sizes against mins, maxes. */ if (isize > blocksize / XFS_MIN_INODE_PERBLOCK || isize < XFS_DINODE_MIN_SIZE || isize > XFS_DINODE_MAX_SIZE) { int maxsz; fprintf(stderr, _("illegal inode size %d\n"), isize); maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK, XFS_DINODE_MAX_SIZE); if (XFS_DINODE_MIN_SIZE == maxsz) fprintf(stderr, _("allowable inode size with %d byte blocks is %d\n"), blocksize, XFS_DINODE_MIN_SIZE); else fprintf(stderr, _("allowable inode size with %d byte blocks is between %d and %d\n"), blocksize, XFS_DINODE_MIN_SIZE, maxsz); exit(1); } /* if lsu or lsunit was specified, automatically use v2 logs */ if ((lsu || lsunit) && logversion == 1) { fprintf(stderr, _("log stripe unit specified, using v2 logs\n")); logversion = 2; } calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize, &dsunit, &dswidth, &lsunit); xi.setblksize = sectorsize; /* * Initialize. This will open the log and rt devices as well. */ if (!libxfs_init(&xi)) usage(); if (!xi.ddev) { fprintf(stderr, _("no device name given in argument list\n")); usage(); } /* * Ok, Linux only has a 1024-byte resolution on device _size_, * and the sizes below are in basic 512-byte blocks, * so if we have (size % 2), on any partition, we can't get * to the last 512 bytes. The same issue exists for larger * sector sizes - we cannot write past the last sector. * * So, we reduce the size (in basic blocks) to a perfect * multiple of the sector size, or 1024, whichever is larger. */ sector_mask = (__uint64_t)-1 << (MAX(sectorlog, 10) - BBSHIFT); xi.dsize &= sector_mask; xi.rtsize &= sector_mask; xi.logBBsize &= (__uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT); if (!force_overwrite) { if (check_overwrite(dfile) || check_overwrite(logfile) || check_overwrite(xi.rtname)) { fprintf(stderr, _("%s: Use the -f option to force overwrite.\n"), progname); exit(1); } } if (discard) { discard_blocks(xi.ddev, xi.dsize); if (xi.rtdev) discard_blocks(xi.rtdev, xi.rtsize); if (xi.logdev && xi.logdev != xi.ddev) discard_blocks(xi.logdev, xi.logBBsize); } if (!liflag && !ldflag) loginternal = xi.logdev == 0; if (xi.logname) logfile = xi.logname; else if (loginternal) logfile = _("internal log"); else if (xi.volname && xi.logdev) logfile = _("volume log"); else if (!ldflag) { fprintf(stderr, _("no log subvolume or internal log\n")); usage(); } if (xi.rtname) rtfile = xi.rtname; else if (xi.volname && xi.rtdev) rtfile = _("volume rt"); else if (!xi.rtdev) rtfile = _("none"); if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) { fprintf(stderr, _("size %s specified for data subvolume is too large, " "maximum is %lld blocks\n"), dsize, (long long)DTOBT(xi.dsize)); usage(); } else if (!dsize && xi.dsize > 0) dblocks = DTOBT(xi.dsize); else if (!dsize) { fprintf(stderr, _("can't get size of data subvolume\n")); usage(); } if (dblocks < XFS_MIN_DATA_BLOCKS) { fprintf(stderr, _("size %lld of data subvolume is too small, minimum %d blocks\n"), (long long)dblocks, XFS_MIN_DATA_BLOCKS); usage(); } if (loginternal && xi.logdev) { fprintf(stderr, _("can't have both external and internal logs\n")); usage(); } else if (loginternal && sectorsize != lsectorsize) { fprintf(stderr, _("data and log sector sizes must be equal for internal logs\n")); usage(); } if (xi.dbsize > sectorsize) { fprintf(stderr, _( "Warning: the data subvolume sector size %u is less than the sector size \n\ reported by the device (%u).\n"), sectorsize, xi.dbsize); } if (!loginternal && xi.lbsize > lsectorsize) { fprintf(stderr, _( "Warning: the log subvolume sector size %u is less than the sector size\n\ reported by the device (%u).\n"), lsectorsize, xi.lbsize); } if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) { fprintf(stderr, _( "Warning: the realtime subvolume sector size %u is less than the sector size\n\ reported by the device (%u).\n"), sectorsize, xi.rtbsize); } max_tr_res = max_trans_res(dirversion, sectorlog, blocklog, inodelog, dirblocklog); ASSERT(max_tr_res); min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR; min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks); if (!logsize && dblocks >= (1024*1024*1024) >> blocklog) min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog); if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) { fprintf(stderr, _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), logsize, (long long)DTOBT(xi.logBBsize)); usage(); } else if (!logsize && xi.logBBsize > 0) { logblocks = DTOBT(xi.logBBsize); } else if (logsize && !xi.logdev && !loginternal) { fprintf(stderr, _("size specified for non-existent log subvolume\n")); usage(); } else if (loginternal && logsize && logblocks >= dblocks) { fprintf(stderr, _("size %lld too large for internal log\n"), (long long)logblocks); usage(); } else if (!loginternal && !xi.logdev) { logblocks = 0; } else if (loginternal && !logsize) { /* * With a 2GB max log size, default to maximum size * at 4TB. This keeps the same ratio from the older * max log size of 128M at 256GB fs size. IOWs, * the ratio of fs size to log size is 2048:1. */ logblocks = (dblocks << blocklog) / 2048; logblocks = logblocks >> blocklog; logblocks = MAX(min_logblocks, logblocks); logblocks = MAX(logblocks, MAX(XFS_DFL_LOG_SIZE, max_tr_res * XFS_DFL_LOG_FACTOR)); logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS); if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) { logblocks = XFS_MAX_LOG_BYTES >> blocklog; } } validate_log_size(logblocks, blocklog, min_logblocks); if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) { fprintf(stderr, _("size %s specified for rt subvolume is too large, " "maximum is %lld blocks\n"), rtsize, (long long)DTOBT(xi.rtsize)); usage(); } else if (!rtsize && xi.rtsize > 0) rtblocks = DTOBT(xi.rtsize); else if (rtsize && !xi.rtdev) { fprintf(stderr, _("size specified for non-existent rt subvolume\n")); usage(); } if (xi.rtdev) { rtextents = rtblocks / rtextblocks; nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize); } else { rtextents = rtblocks = 0; nbmblocks = 0; } if (dasize) { /* User-specified AG size */ /* * Check specified agsize is a multiple of blocksize. */ if (agsize % blocksize) { fprintf(stderr, _("agsize (%lld) not a multiple of fs blk size (%d)\n"), (long long)agsize, blocksize); usage(); } agsize /= blocksize; agcount = dblocks / agsize + (dblocks % agsize != 0); } else if (daflag) /* User-specified AG count */ agsize = dblocks / agcount + (dblocks % agcount != 0); else calc_default_ag_geometry(blocklog, dblocks, ft.dsunit | ft.dswidth, &agsize, &agcount); if (!nodsflag) { if (dsunit) { if (ft.dsunit && ft.dsunit != dsunit) { fprintf(stderr, _("%s: Specified data stripe unit %d " "is not the same as the volume stripe " "unit %d\n"), progname, dsunit, ft.dsunit); } if (ft.dswidth && ft.dswidth != dswidth) { fprintf(stderr, _("%s: Specified data stripe width %d " "is not the same as the volume stripe " "width %d\n"), progname, dswidth, ft.dswidth); } } else { dsunit = ft.dsunit; dswidth = ft.dswidth; nodsflag = 1; } } /* else dsunit & dswidth can't be set if nodsflag is set */ /* * If dsunit is a multiple of fs blocksize, then check that is a * multiple of the agsize too */ if (dsunit && !(BBTOB(dsunit) % blocksize) && dswidth && !(BBTOB(dswidth) % blocksize)) { /* convert from 512 byte blocks to fs blocksize */ dsunit = DTOBT(dsunit); dswidth = DTOBT(dswidth); /* * agsize is not a multiple of dsunit */ if ((agsize % dsunit) != 0) { /* * Round up to stripe unit boundary. Also make sure * that agsize is still larger than * XFS_AG_MIN_BLOCKS(blocklog) */ tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit; /* * Round down to stripe unit boundary if rounding up * created an AG size that is larger than the AG max. */ if (tmp_agsize > XFS_AG_MAX_BLOCKS(blocklog)) tmp_agsize = ((agsize) / dsunit) * dsunit; if ((tmp_agsize >= XFS_AG_MIN_BLOCKS(blocklog)) && (tmp_agsize <= XFS_AG_MAX_BLOCKS(blocklog))) { agsize = tmp_agsize; if (!daflag) agcount = dblocks/agsize + (dblocks % agsize != 0); if (dasize) fprintf(stderr, _("agsize rounded to %lld, swidth = %d\n"), (long long)agsize, dswidth); } else { if (nodsflag) { dsunit = dswidth = 0; } else { /* * agsize is out of bounds, this will * print nice details & exit. */ validate_ag_geometry(blocklog, dblocks, agsize, agcount); exit(1); } } } if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) { /* This is a non-optimal configuration because all AGs * start on the same disk in the stripe. Changing * the AG size by one sunit will guarantee that this * does not happen. */ tmp_agsize = agsize - dsunit; if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) { tmp_agsize = agsize + dsunit; if (dblocks < agsize) { /* oh well, nothing to do */ tmp_agsize = agsize; } } if (daflag || dasize) { fprintf(stderr, _( "Warning: AG size is a multiple of stripe width. This can cause performance\n\ problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\ an AG size that is one stripe unit smaller, for example %llu.\n"), (unsigned long long)tmp_agsize); } else { agsize = tmp_agsize; agcount = dblocks/agsize + (dblocks % agsize != 0); /* * If the last AG is too small, reduce the * filesystem size and drop the blocks. */ if ( dblocks % agsize != 0 && (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) { dblocks = (xfs_drfsbno_t)((agcount - 1) * agsize); agcount--; ASSERT(agcount != 0); } } } } else { if (nodsflag) dsunit = dswidth = 0; else { fprintf(stderr, _("%s: Stripe unit(%d) or stripe width(%d) is " "not a multiple of the block size(%d)\n"), progname, BBTOB(dsunit), BBTOB(dswidth), blocksize); exit(1); } } /* * If the last AG is too small, reduce the filesystem size * and drop the blocks. */ if ( dblocks % agsize != 0 && (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) { ASSERT(!daflag); dblocks = (xfs_drfsbno_t)((agcount - 1) * agsize); agcount--; ASSERT(agcount != 0); } validate_ag_geometry(blocklog, dblocks, agsize, agcount); if (!imflag) imaxpct = calc_default_imaxpct(blocklog, dblocks); /* * check that log sunit is modulo fsblksize or default it to dsunit. */ if (lsunit) { if ((BBTOB(lsunit) % blocksize != 0)) { fprintf(stderr, _("log stripe unit (%d) must be a multiple of the block size (%d)\n"), BBTOB(lsunit), blocksize); exit(1); } /* convert from 512 byte blocks to fs blocks */ lsunit = DTOBT(lsunit); } else if (logversion == 2 && loginternal && dsunit) { /* lsunit and dsunit now in fs blocks */ lsunit = dsunit; } if (logversion == 2 && (lsunit * blocksize) > 256 * 1024) { fprintf(stderr, _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"), (lsunit * blocksize)); lsunit = (32 * 1024) >> blocklog; fprintf(stderr, _("log stripe unit adjusted to 32KiB\n")); } protostring = setup_proto(protofile); bsize = 1 << (blocklog - BBSHIFT); mp = &mbuf; sbp = &mp->m_sb; memset(mp, 0, sizeof(xfs_mount_t)); sbp->sb_blocklog = (__uint8_t)blocklog; sbp->sb_sectlog = (__uint8_t)sectorlog; sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize); mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; if (loginternal) { /* * Readjust the log size to fit within an AG if it was sized * automatically. */ if (!logsize) { logblocks = MIN(logblocks, agsize - XFS_PREALLOC_BLOCKS(mp)); } if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) { fprintf(stderr, _("internal log size %lld too large, must fit in allocation group\n"), (long long)logblocks); usage(); } if (laflag) { if (logagno >= agcount) { fprintf(stderr, _("log ag number %d too large, must be less than %lld\n"), logagno, (long long)agcount); usage(); } } else logagno = (xfs_agnumber_t)(agcount / 2); logstart = XFS_AGB_TO_FSB(mp, logagno, XFS_PREALLOC_BLOCKS(mp)); /* * Align the logstart at stripe unit boundary. */ if (lsunit) { logstart = fixup_internal_log_stripe(mp, lsflag, logstart, agsize, lsunit, &logblocks, blocklog, &lalign); } else if (dsunit) { logstart = fixup_internal_log_stripe(mp, lsflag, logstart, agsize, dsunit, &logblocks, blocklog, &lalign); } } else { logstart = 0; if (lsunit) fixup_log_stripe_unit(lsflag, lsunit, &logblocks, blocklog); } validate_log_size(logblocks, blocklog, min_logblocks); if (!qflag || Nflag) { printf(_( "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), dfile, isize, (long long)agcount, (long long)agsize, "", sectorsize, attrversion, projid32bit, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, dirversion, dirblocksize, nci, logfile, 1 << blocklog, (long long)logblocks, logversion, "", lsectorsize, lsunit, lazy_sb_counters, rtfile, rtextblocks << blocklog, (long long)rtblocks, (long long)rtextents); if (Nflag) exit(0); } if (label) strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname)); sbp->sb_magicnum = XFS_SB_MAGIC; sbp->sb_blocksize = blocksize; sbp->sb_dblocks = dblocks; sbp->sb_rblocks = rtblocks; sbp->sb_rextents = rtextents; platform_uuid_generate(&uuid); platform_uuid_copy(&sbp->sb_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO; sbp->sb_rextsize = rtextblocks; sbp->sb_agblocks = (xfs_agblock_t)agsize; sbp->sb_agcount = (xfs_agnumber_t)agcount; sbp->sb_rbmblocks = nbmblocks; sbp->sb_logblocks = (xfs_extlen_t)logblocks; sbp->sb_sectsize = (__uint16_t)sectorsize; sbp->sb_inodesize = (__uint16_t)isize; sbp->sb_inopblock = (__uint16_t)(blocksize / isize); sbp->sb_sectlog = (__uint8_t)sectorlog; sbp->sb_inodelog = (__uint8_t)inodelog; sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog); sbp->sb_rextslog = (__uint8_t)(rtextents ? libxfs_highbit32((unsigned int)rtextents) : 0); sbp->sb_inprogress = 1; /* mkfs is in progress */ sbp->sb_imax_pct = imaxpct; sbp->sb_icount = 0; sbp->sb_ifree = 0; sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) - (loginternal ? logblocks : 0); sbp->sb_frextents = 0; /* will do a free later */ sbp->sb_uquotino = sbp->sb_gquotino = 0; sbp->sb_qflags = 0; sbp->sb_unit = dsunit; sbp->sb_width = dswidth; sbp->sb_dirblklog = dirblocklog - blocklog; if (logversion == 2) { /* This is stored in bytes */ lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit); sbp->sb_logsunit = lsunit; } else sbp->sb_logsunit = 0; if (iaflag) { sbp->sb_inoalignmt = XFS_INODE_BIG_CLUSTER_SIZE >> blocklog; iaflag = sbp->sb_inoalignmt != 0; } else sbp->sb_inoalignmt = 0; if (lsectorsize != BBSIZE || sectorsize != BBSIZE) { sbp->sb_logsectlog = (__uint8_t)lsectorlog; sbp->sb_logsectsize = (__uint16_t)lsectorsize; } else { sbp->sb_logsectlog = 0; sbp->sb_logsectsize = 0; } sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters, attrversion == 2, projid32bit == 1, 0); sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0, logversion == 2, attrversion == 1, (sectorsize != BBSIZE || lsectorsize != BBSIZE), nci, sbp->sb_features2 != 0); /* * Due to a structure alignment issue, sb_features2 ended up in one * of two locations, the second "incorrect" location represented by * the sb_bad_features2 field. To avoid older kernels mounting * filesystems they shouldn't, set both field to the same value. */ sbp->sb_bad_features2 = sbp->sb_features2; if (force_overwrite) zero_old_xfs_structures(&xi, sbp); /* * Zero out the beginning of the device, to obliterate any old * filesystem signatures out there. This should take care of * swap (somewhere around the page size), jfs (32k), * ext[2,3] and reiserfs (64k) - and hopefully all else. */ buf = libxfs_getbuf(xi.ddev, 0, BTOBB(WHACK_SIZE)); memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); libxfs_purgebuf(buf); /* OK, now write the superblock */ buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1)); memset(XFS_BUF_PTR(buf), 0, sectorsize); libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * If the data area is a file, then grow it out to its final size * so that the reads for the end of the device in the mount code * will succeed. */ if (xi.disfile && ftruncate64(xi.dfd, dblocks * blocksize) < 0) { fprintf(stderr, _("%s: Growing the data section failed\n"), progname); exit(1); } /* * Zero out the end of the device, to obliterate any * old MD RAID (or other) metadata at the end of the device. * (MD sb is ~64k from the end, take out a wider swath to be sure) */ if (!xi.disfile) { buf = libxfs_getbuf(xi.ddev, (xi.dsize - BTOBB(WHACK_SIZE)), BTOBB(WHACK_SIZE)); memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); libxfs_purgebuf(buf); } /* * Zero the log if there is one. */ if (loginternal) xi.logdev = xi.ddev; if (xi.logdev) libxfs_log_clear(xi.logdev, XFS_FSB_TO_DADDR(mp, logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), &sbp->sb_uuid, logversion, lsunit, XLOG_FMT); mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 1); if (mp == NULL) { fprintf(stderr, _("%s: filesystem failed to initialize\n"), progname); exit(1); } for (agno = 0; agno < agcount; agno++) { /* * Superblock. */ buf = libxfs_getbuf(xi.ddev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1)); memset(XFS_BUF_PTR(buf), 0, sectorsize); libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp, XFS_SB_ALL_BITS); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * AG header block: freespace */ buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1)); agf = XFS_BUF_TO_AGF(buf); memset(agf, 0, sectorsize); if (agno == agcount - 1) agsize = dblocks - (xfs_drfsbno_t)(agno * agsize); agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); agf->agf_seqno = cpu_to_be32(agno); agf->agf_length = cpu_to_be32(agsize); agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp)); agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp)); agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1); agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1); agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp)); agf->agf_freeblks = cpu_to_be32(nbmblocks); agf->agf_longest = cpu_to_be32(nbmblocks); if (loginternal && agno == logagno) { be32_add_cpu(&agf->agf_freeblks, -logblocks); agf->agf_longest = cpu_to_be32(agsize - XFS_FSB_TO_AGBNO(mp, logstart) - logblocks); } if (XFS_MIN_FREELIST(agf, mp) > worst_freelist) worst_freelist = XFS_MIN_FREELIST(agf, mp); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * AG header block: inodes */ buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1)); agi = XFS_BUF_TO_AGI(buf); memset(agi, 0, sectorsize); agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); agi->agi_seqno = cpu_to_be32(agno); agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize); agi->agi_count = 0; agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp)); agi->agi_level = cpu_to_be32(1); agi->agi_freecount = 0; agi->agi_newino = cpu_to_be32(NULLAGINO); agi->agi_dirino = cpu_to_be32(NULLAGINO); for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++) agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * BNO btree root block */ buf = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), bsize); block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); block->bb_level = 0; block->bb_numrecs = cpu_to_be16(1); block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); arec = XFS_ALLOC_REC_ADDR(mp, block, 1); arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { if (lalign) { /* * Have to insert two records * Insert pad record for stripe align of log */ arec->ar_blockcount = cpu_to_be32( XFS_FSB_TO_AGBNO(mp, logstart) - be32_to_cpu(arec->ar_startblock)); nrec = arec + 1; /* * Insert record at start of internal log */ nrec->ar_startblock = cpu_to_be32( be32_to_cpu(arec->ar_startblock) + be32_to_cpu(arec->ar_blockcount)); arec = nrec; be16_add_cpu(&block->bb_numrecs, 1); } /* * Change record start to after the internal log */ be32_add_cpu(&arec->ar_startblock, logblocks); } arec->ar_blockcount = cpu_to_be32(agsize - be32_to_cpu(arec->ar_startblock)); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * CNT btree root block */ buf = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), bsize); block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); block->bb_level = 0; block->bb_numrecs = cpu_to_be16(1); block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); arec = XFS_ALLOC_REC_ADDR(mp, block, 1); arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); if (loginternal && agno == logagno) { if (lalign) { arec->ar_blockcount = cpu_to_be32( XFS_FSB_TO_AGBNO(mp, logstart) - be32_to_cpu(arec->ar_startblock)); nrec = arec + 1; nrec->ar_startblock = cpu_to_be32( be32_to_cpu(arec->ar_startblock) + be32_to_cpu(arec->ar_blockcount)); arec = nrec; be16_add_cpu(&block->bb_numrecs, 1); } be32_add_cpu(&arec->ar_startblock, logblocks); } arec->ar_blockcount = cpu_to_be32(agsize - be32_to_cpu(arec->ar_startblock)); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * INO btree root block */ buf = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), bsize); block = XFS_BUF_TO_BLOCK(buf); memset(block, 0, blocksize); block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); block->bb_level = 0; block->bb_numrecs = 0; block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } /* * Touch last block, make fs the right size if it's a file. */ buf = libxfs_getbuf(mp->m_dev, (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize); memset(XFS_BUF_PTR(buf), 0, blocksize); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * Make sure we can write the last block in the realtime area. */ if (mp->m_rtdev && rtblocks > 0) { buf = libxfs_getbuf(mp->m_rtdev, XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize); memset(XFS_BUF_PTR(buf), 0, blocksize); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } /* * BNO, CNT free block list */ for (agno = 0; agno < agcount; agno++) { xfs_alloc_arg_t args; xfs_trans_t *tp; memset(&args, 0, sizeof(args)); args.tp = tp = libxfs_trans_alloc(mp, 0); args.mp = mp; args.agno = agno; args.alignment = 1; args.pag = xfs_perag_get(mp,agno); if ((c = libxfs_trans_reserve(tp, worst_freelist, 0, 0, 0, 0))) res_failed(c); libxfs_alloc_fix_freelist(&args, 0); xfs_perag_put(args.pag); libxfs_trans_commit(tp, 0); } /* * Allocate the root inode and anything else in the proto file. */ mp->m_rootip = NULL; parse_proto(mp, &fsx, &protostring); /* * Protect ourselves against possible stupidity */ if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) { fprintf(stderr, _("%s: root inode created in AG %u, not AG 0\n"), progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino)); exit(1); } /* * Write out multiple secondary superblocks with rootinode field set */ if (mp->m_sb.sb_agcount > 1) { /* * the last superblock */ buf = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), LIBXFS_EXIT_ON_FAILURE); XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* * and one in the middle for luck */ if (mp->m_sb.sb_agcount > 2) { buf = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), LIBXFS_EXIT_ON_FAILURE); XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( mp->m_sb.sb_rootino); libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } } /* * Dump all inodes and buffers before marking us all done. * Need to drop references to inodes we still hold, first. */ libxfs_rtmount_destroy(mp); libxfs_icache_purge(); libxfs_bcache_purge(); /* * Mark the filesystem ok. */ buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE); (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0; libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); libxfs_umount(mp); if (xi.rtdev) libxfs_device_close(xi.rtdev); if (xi.logdev && xi.logdev != xi.ddev) libxfs_device_close(xi.logdev); libxfs_device_close(xi.ddev); return 0; } static void conflict( char opt, char *tab[], int oldidx, int newidx) { fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"), opt, tab[oldidx], opt, tab[newidx]); usage(); } static void illegal( char *value, char *opt) { fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt); usage(); } static int ispow2( unsigned int i) { return (i & (i - 1)) == 0; } static void __attribute__((noreturn)) reqval( char opt, char *tab[], int idx) { fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]); usage(); } static void respec( char opt, char *tab[], int idx) { fprintf(stderr, "-%c ", opt); if (tab) fprintf(stderr, "%s ", tab[idx]); fprintf(stderr, _("option respecified\n")); usage(); } static void unknown( char opt, char *s) { fprintf(stderr, _("unknown option -%c %s\n"), opt, s); usage(); } /* * isdigits -- returns 1 if string contains nothing but [0-9], 0 otherwise */ int isdigits( char *str) { int i; int n = strlen(str); for (i = 0; i < n; i++) { if (!isdigit((int)str[i])) return 0; } return 1; } long long cvtnum( unsigned int blocksize, unsigned int sectorsize, char *s) { long long i; char *sp; i = strtoll(s, &sp, 0); if (i == 0 && sp == s) return -1LL; if (*sp == '\0') return i; if (*sp == 'b' && sp[1] == '\0') { if (blocksize) return i * blocksize; fprintf(stderr, _("blocksize not available yet.\n")); usage(); } if (*sp == 's' && sp[1] == '\0') { if (sectorsize) return i * sectorsize; return i * BBSIZE; } if (*sp == 'k' && sp[1] == '\0') return 1024LL * i; if (*sp == 'm' && sp[1] == '\0') return 1024LL * 1024LL * i; if (*sp == 'g' && sp[1] == '\0') return 1024LL * 1024LL * 1024LL * i; if (*sp == 't' && sp[1] == '\0') return 1024LL * 1024LL * 1024LL * 1024LL * i; if (*sp == 'p' && sp[1] == '\0') return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i; if (*sp == 'e' && sp[1] == '\0') return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i; return -1LL; } static void __attribute__((noreturn)) usage( void ) { fprintf(stderr, _("Usage: %s\n\ /* blocksize */ [-b log=n|size=num]\n\ /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\ (sunit=value,swidth=value|su=num,sw=num),\n\ sectlog=n|sectsize=num\n\ /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\ projid32bit=0|1]\n\ /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\ sunit=value|su=num,sectlog=n|sectsize=num,\n\ lazy-count=0|1]\n\ /* label */ [-L label (maximum 12 characters)]\n\ /* naming */ [-n log=n|size=num,version=2|ci]\n\ /* prototype file */ [-p fname]\n\ /* quiet */ [-q]\n\ /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\ /* sectorsize */ [-s log=n|size=num]\n\ /* version */ [-V]\n\ devicename\n\ is required unless -d name=xxx is given.\n\ is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\ xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\ is xxx (512 byte blocks).\n"), progname); exit(1); } xfsprogs-3.1.9ubuntu2/mkfs/xfs_mkfs.h0000664000000000000000000000646111466226660014565 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_MKFS_H__ #define __XFS_MKFS_H__ #define XFS_DFL_SB_VERSION_BITS \ (XFS_SB_VERSION_NLINKBIT | \ XFS_SB_VERSION_EXTFLGBIT | \ XFS_SB_VERSION_DIRV2BIT) #define XFS_SB_VERSION_MKFS(ia,dia,log2,attr1,sflag,ci,more) (\ ((ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \ ( XFS_SB_VERSION_4 | \ ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \ ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \ ((log2) ? XFS_SB_VERSION_LOGV2BIT : 0) | \ ((attr1) ? XFS_SB_VERSION_ATTRBIT : 0) | \ ((sflag) ? XFS_SB_VERSION_SECTORBIT : 0) | \ ((ci) ? XFS_SB_VERSION_BORGBIT : 0) | \ ((more) ? XFS_SB_VERSION_MOREBITSBIT : 0) | \ XFS_DFL_SB_VERSION_BITS | \ 0 ) : XFS_SB_VERSION_1 ) #define XFS_SB_VERSION2_MKFS(lazycount, attr2, projid32bit, parent) (\ ((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) | \ ((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) | \ ((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) | \ ((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) | \ 0 ) #define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */ #define XFS_DINODE_DFL_LOG 8 /* 256 byte inodes */ #define XFS_MIN_DATA_BLOCKS 100 #define XFS_MIN_INODE_PERBLOCK 2 /* min inodes per block */ #define XFS_DFL_IMAXIMUM_PCT 25 /* max % of space for inodes */ #define XFS_IFLAG_ALIGN 1 /* -i align defaults on */ #define XFS_MIN_REC_DIRSIZE 12 /* 4096 byte dirblocks (V2) */ #define XFS_DFL_DIR_VERSION 2 /* default directory version */ #define XFS_DFL_LOG_SIZE 1000 /* default log size, blocks */ #define XFS_MIN_LOG_FACTOR 3 /* min log size factor */ #define XFS_DFL_LOG_FACTOR 16 /* default log size, factor */ /* with max trans reservation */ #define XFS_MAX_INODE_SIG_BITS 32 /* most significant bits in an * inode number that we'll * accept w/o warnings */ #define XFS_AG_BYTES(bblog) ((long long)BBSIZE << (bblog)) #define XFS_AG_MIN_BYTES ((XFS_AG_BYTES(15))) /* 16 MB */ #define XFS_AG_MIN_BLOCKS(blog) ((XFS_AG_BYTES(15)) >> (blog)) #define XFS_AG_MAX_BLOCKS(blog) ((XFS_AG_BYTES(31) - 1) >> (blog)) #define XFS_MAX_AGNUMBER ((xfs_agnumber_t)(NULLAGNUMBER - 1)) /* xfs_mkfs.c */ extern int isdigits (char *str); extern long long cvtnum (unsigned int blocksize, unsigned int sectorsize, char *s); /* proto.c */ extern char *setup_proto (char *fname); extern void parse_proto (xfs_mount_t *mp, struct fsxattr *fsx, char **pp); extern void res_failed (int err); /* maxtrres.c */ extern int max_trans_res (int dirversion, int sectorlog, int blocklog, int inodelog, int dirblocklog); #endif /* __XFS_MKFS_H__ */ xfsprogs-3.1.9ubuntu2/mkfs/maxtrres.c0000664000000000000000000000563211140033220014555 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * maxtrres.c * * Compute the maximum transaction reservation for a legal combination * of sector size, block size, inode size, directory version, and * directory block size. */ #include #include "xfs_mkfs.h" static void max_attrset_trans_res_adjust( xfs_mount_t *mp) { int local; int size; int nblks; int res; /* * Determine space the maximal sized attribute will use, * to calculate the largest reservation size needed. */ size = libxfs_attr_leaf_newentsize(MAXNAMELEN, 64 * 1024, mp->m_sb.sb_blocksize, &local); ASSERT(!local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks += XFS_B_TO_FSB(mp, size); nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); res = XFS_ATTRSET_LOG_RES(mp, nblks); #if 0 printf("size = %d nblks = %d res = %d\n", size, nblks, res); #endif mp->m_reservations.tr_attrset = res; } static int max_trans_res_by_mount( xfs_mount_t *mp) { uint *p; int rval; xfs_trans_reservations_t *tr = &mp->m_reservations; for (rval = 0, p = (uint *)tr; p < (uint *)(tr + 1); p++) { if ((int)*p > rval) rval = (int)*p; } return rval; } int max_trans_res( int dirversion, int sectorlog, int blocklog, int inodelog, int dirblocklog) { xfs_sb_t *sbp; xfs_mount_t mount; int maxres, maxfsb; memset(&mount, 0, sizeof(mount)); sbp = &mount.m_sb; sbp->sb_magicnum = XFS_SB_MAGIC; sbp->sb_sectlog = sectorlog; sbp->sb_sectsize = 1 << sbp->sb_sectlog; sbp->sb_blocklog = blocklog; sbp->sb_blocksize = 1 << blocklog; sbp->sb_agblocks = XFS_AG_MIN_BYTES / (1 << blocklog); sbp->sb_inodelog = inodelog; sbp->sb_inopblog = blocklog - inodelog; sbp->sb_inodesize = 1 << inodelog; sbp->sb_inopblock = 1 << (blocklog - inodelog); sbp->sb_dirblklog = dirblocklog - blocklog; sbp->sb_versionnum = XFS_SB_VERSION_4 | (dirversion == 2 ? XFS_SB_VERSION_DIRV2BIT : 0); libxfs_mount(&mount, sbp, 0,0,0,0); max_attrset_trans_res_adjust(&mount); maxres = max_trans_res_by_mount(&mount); maxfsb = XFS_B_TO_FSB(&mount, maxres); libxfs_umount(&mount); #if 0 printf("#define\tMAXTRRES_S%d_B%d_I%d_D%d_V%d\t%lld\n", sectorlog, blocklog, inodelog, dirblocklog, dirversion, maxfsb); #endif return maxfsb; } xfsprogs-3.1.9ubuntu2/mkfs/fstyp.c0000664000000000000000000000347011140033220014053 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include /* * fstyp allows the user to determine the filesystem identifier of * mounted or unmounted filesystems using heuristics. * * The filesystem type is required by mount(2) and sometimes by mount(8) * to mount filesystems of different types. fstyp uses exactly the same * heuristics that mount does to determine whether the supplied device * special file is of a known filesystem type. If it is, fstyp prints * on standard output the usual filesystem identifier for that type and * exits with a zero return code. If no filesystem is identified, fstyp * prints "Unknown" to indicate failure and exits with a non-zero status. * * WARNING: The use of heuristics implies that the result of fstyp is not * guaranteed to be accurate. */ int main(int argc, char *argv[]) { char *type; if (argc != 2) { fprintf(stderr, "Usage: %s \n", basename(argv[0])); exit(1); } if (access(argv[1], R_OK) < 0) { perror(argv[1]); exit(1); } if ((type = fstype(argv[1])) == NULL) { printf("Unknown\n"); exit(1); } printf("%s\n", type); exit(0); } xfsprogs-3.1.9ubuntu2/logprint/0000775000000000000000000000000013265631475013466 5ustar xfsprogs-3.1.9ubuntu2/logprint/log_misc.c0000664000000000000000000012432613265631475015436 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" #define CLEARED_BLKS (-5) #define ZEROED_LOG (-4) #define FULL_READ (-3) #define PARTIAL_READ (-2) #define BAD_HEADER (-1) #define NO_ERROR (0) #define XLOG_SET(f,b) (((f) & (b)) == (b)) static int logBBsize; char *trans_type[] = { "", "SETATTR", "SETATTR_SIZE", "INACTIVE", "CREATE", "CREATE_TRUNC", "TRUNCATE_FILE", "REMOVE", "LINK", "RENAME", "MKDIR", "RMDIR", "SYMLINK", "SET_DMATTRS", "GROWFS", "STRAT_WRITE", "DIOSTRAT", "WRITE_SYNC", "WRITEID", "ADDAFORK", "ATTRINVAL", "ATRUNCATE", "ATTR_SET", "ATTR_RM", "ATTR_FLAG", "CLEAR_AGI_BUCKET", "QM_SBCHANGE", "DUMMY1", "DUMMY2", "QM_QUOTAOFF", "QM_DQALLOC", "QM_SETQLIM", "QM_DQCLUSTER", "QM_QINOCREATE", "QM_QUOTAOFF_END", "SB_UNIT", "FSYNC_TS", "GROWFSRT_ALLOC", "GROWFSRT_ZERO", "GROWFSRT_FREE", "SWAPEXT", "SB_COUNT", "CHECKPOINT", }; typedef struct xlog_split_item { struct xlog_split_item *si_next; struct xlog_split_item *si_prev; xlog_tid_t si_tid; int si_skip; } xlog_split_item_t; xlog_split_item_t *split_list = NULL; void print_xlog_op_line(void) { printf("--------------------------------------" "--------------------------------------\n"); } /* print_xlog_op_line */ void print_xlog_xhdr_line(void) { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); } /* print_xlog_xhdr_line */ void print_xlog_record_line(void) { printf("======================================" "======================================\n"); } /* print_xlog_record_line */ void print_stars(void) { printf("***********************************" "***********************************\n"); } /* print_stars */ /* * Given a pointer to a data segment, print out the data as if it were * a log operation header. */ void xlog_print_op_header(xlog_op_header_t *op_head, int i, xfs_caddr_t *ptr) { xlog_op_header_t hbuf; /* * memmove because on 64/n32, partial reads can cause the op_head * pointer to come in pointing to an odd-numbered byte */ memmove(&hbuf, op_head, sizeof(xlog_op_header_t)); op_head = &hbuf; *ptr += sizeof(xlog_op_header_t); printf(_("Oper (%d): tid: %x len: %d clientid: %s "), i, be32_to_cpu(op_head->oh_tid), be32_to_cpu(op_head->oh_len), (op_head->oh_clientid == XFS_TRANSACTION ? "TRANS" : (op_head->oh_clientid == XFS_LOG ? "LOG" : "ERROR"))); printf(_("flags: ")); if (op_head->oh_flags) { if (op_head->oh_flags & XLOG_START_TRANS) printf("START "); if (op_head->oh_flags & XLOG_COMMIT_TRANS) printf("COMMIT "); if (op_head->oh_flags & XLOG_WAS_CONT_TRANS) printf("WAS_CONT "); if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) printf("UNMOUNT "); if (op_head->oh_flags & XLOG_CONTINUE_TRANS) printf("CONTINUE "); if (op_head->oh_flags & XLOG_END_TRANS) printf("END "); } else { printf(_("none")); } printf("\n"); } /* xlog_print_op_header */ void xlog_print_add_to_trans(xlog_tid_t tid, int skip) { xlog_split_item_t *item; item = (xlog_split_item_t *)calloc(sizeof(xlog_split_item_t), 1); item->si_tid = tid; item->si_skip = skip; item->si_next = split_list; item->si_prev = NULL; if (split_list) split_list->si_prev = item; split_list = item; } /* xlog_print_add_to_trans */ int xlog_print_find_tid(xlog_tid_t tid, uint was_cont) { xlog_split_item_t *listp = split_list; if (!split_list) { if (was_cont != 0) /* Not first time we have used this tid */ return 1; else return 0; } while (listp) { if (listp->si_tid == tid) break; listp = listp->si_next; } if (!listp) { return 0; } if (--listp->si_skip == 0) { if (listp == split_list) { /* delete at head */ split_list = listp->si_next; if (split_list) split_list->si_prev = NULL; } else { if (listp->si_next) listp->si_next->si_prev = listp->si_prev; listp->si_prev->si_next = listp->si_next; } free(listp); } return 1; } /* xlog_print_find_tid */ int xlog_print_trans_header(xfs_caddr_t *ptr, int len) { xfs_trans_header_t *h; xfs_caddr_t cptr = *ptr; __uint32_t magic; char *magic_c = (char *)&magic; *ptr += len; magic=*(__uint32_t*)cptr; /* XXX be32_to_cpu soon */ if (len >= 4) { #if __BYTE_ORDER == __LITTLE_ENDIAN printf("%c%c%c%c:", magic_c[3], magic_c[2], magic_c[1], magic_c[0]); #else printf("%c%c%c%c:", magic_c[0], magic_c[1], magic_c[2], magic_c[3]); #endif } if (len != sizeof(xfs_trans_header_t)) { printf(_(" Not enough data to decode further\n")); return 1; } h = (xfs_trans_header_t *)cptr; printf(_(" type: %s tid: %x num_items: %d\n"), trans_type[h->th_type], h->th_tid, h->th_num_items); return 0; } /* xlog_print_trans_header */ int xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops) { xfs_buf_log_format_t *f; xfs_agi_t *agi; xfs_agf_t *agf; xfs_disk_dquot_t *dq; xlog_op_header_t *head = NULL; int num, skip; int super_block = 0; int bucket, col, buckets; __int64_t blkno; xfs_buf_log_format_t lbuf; int size, blen, map_size, struct_size; __be64 x, y; ushort flags; /* * memmove to ensure 8-byte alignment for the long longs in * buf_log_format_t structure */ memmove(&lbuf, *ptr, MIN(sizeof(xfs_buf_log_format_t), len)); f = &lbuf; *ptr += len; ASSERT(f->blf_type == XFS_LI_BUF); printf("BUF: "); blkno = f->blf_blkno; size = f->blf_size; blen = f->blf_len; map_size = f->blf_map_size; flags = f->blf_flags; struct_size = sizeof(xfs_buf_log_format_t); if (len >= struct_size) { ASSERT((len - sizeof(struct_size)) % sizeof(int) == 0); printf(_("#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n"), size, (long long)blkno, (unsigned long long)blkno, blen, map_size, flags); if (blkno == 0) super_block = 1; } else { ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */ printf(_("#regs: %d Not printing rest of data\n"), f->blf_size); return size; } num = size-1; /* Check if all regions in this log item were in the given LR ptr */ if (*i+num > num_ops-1) { skip = num - (num_ops-1-*i); num = num_ops-1-*i; } else { skip = 0; } while (num-- > 0) { (*i)++; head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); if (super_block) { printf(_("SUPER BLOCK Buffer: ")); if (be32_to_cpu(head->oh_len) < 4*8) { printf(_("Out of space\n")); } else { printf("\n"); /* * memmove because *ptr may not be 8-byte aligned */ memmove(&x, *ptr, sizeof(__be64)); memmove(&y, *ptr+8, sizeof(__be64)); printf(_("icount: %llu ifree: %llu "), (unsigned long long) be64_to_cpu(x), (unsigned long long) be64_to_cpu(y)); memmove(&x, *ptr+16, sizeof(__be64)); memmove(&y, *ptr+24, sizeof(__be64)); printf(_("fdblks: %llu frext: %llu\n"), (unsigned long long) be64_to_cpu(x), (unsigned long long) be64_to_cpu(y)); } super_block = 0; } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { agi = (xfs_agi_t *)(*ptr); printf(_("AGI Buffer: XAGI ")); if (be32_to_cpu(head->oh_len) < sizeof(xfs_agi_t) - XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) { printf(_("out of space\n")); } else { printf("\n"); printf(_("ver: %d "), be32_to_cpu(agi->agi_versionnum)); printf(_("seq#: %d len: %d cnt: %d root: %d\n"), be32_to_cpu(agi->agi_seqno), be32_to_cpu(agi->agi_length), be32_to_cpu(agi->agi_count), be32_to_cpu(agi->agi_root)); printf(_("level: %d free#: 0x%x newino: 0x%x\n"), be32_to_cpu(agi->agi_level), be32_to_cpu(agi->agi_freecount), be32_to_cpu(agi->agi_newino)); if (be32_to_cpu(head->oh_len) == 128) { buckets = 17; } else if (be32_to_cpu(head->oh_len) == 256) { buckets = 32 + 17; } else { if (head->oh_flags & XLOG_CONTINUE_TRANS) { printf(_("AGI unlinked data skipped ")); printf(_("(CONTINUE set, no space)\n")); continue; } buckets = XFS_AGI_UNLINKED_BUCKETS; } for (bucket = 0; bucket < buckets;) { printf(_("bucket[%d - %d]: "), bucket, bucket+3); for (col = 0; col < 4; col++, bucket++) { if (bucket < buckets) { printf("0x%x ", be32_to_cpu(agi->agi_unlinked[bucket])); } } printf("\n"); } } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) { agf = (xfs_agf_t *)(*ptr); printf(_("AGF Buffer: XAGF ")); if (be32_to_cpu(head->oh_len) < sizeof(xfs_agf_t)) { printf(_("Out of space\n")); } else { printf("\n"); printf(_("ver: %d seq#: %d len: %d \n"), be32_to_cpu(agf->agf_versionnum), be32_to_cpu(agf->agf_seqno), be32_to_cpu(agf->agf_length)); printf(_("root BNO: %d CNT: %d\n"), be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]), be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); printf(_("level BNO: %d CNT: %d\n"), be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]), be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); printf(_("1st: %d last: %d cnt: %d " "freeblks: %d longest: %d\n"), be32_to_cpu(agf->agf_flfirst), be32_to_cpu(agf->agf_fllast), be32_to_cpu(agf->agf_flcount), be32_to_cpu(agf->agf_freeblks), be32_to_cpu(agf->agf_longest)); } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) { dq = (xfs_disk_dquot_t *)(*ptr); printf(_("DQUOT Buffer: DQ ")); if (be32_to_cpu(head->oh_len) < sizeof(xfs_disk_dquot_t)) { printf(_("Out of space\n")); } else { printf("\n"); printf(_("ver: %d flags: 0x%x id: %d \n"), dq->d_version, dq->d_flags, be32_to_cpu(dq->d_id)); printf(_("blk limits hard: %llu soft: %llu\n"), (unsigned long long) be64_to_cpu(dq->d_blk_hardlimit), (unsigned long long) be64_to_cpu(dq->d_blk_softlimit)); printf(_("blk count: %llu warns: %d timer: %d\n"), (unsigned long long) be64_to_cpu(dq->d_bcount), (int) be16_to_cpu(dq->d_bwarns), be32_to_cpu(dq->d_btimer)); printf(_("ino limits hard: %llu soft: %llu\n"), (unsigned long long) be64_to_cpu(dq->d_ino_hardlimit), (unsigned long long) be64_to_cpu(dq->d_ino_softlimit)); printf(_("ino count: %llu warns: %d timer: %d\n"), (unsigned long long) be64_to_cpu(dq->d_icount), (int) be16_to_cpu(dq->d_iwarns), be32_to_cpu(dq->d_itimer)); } } else { printf(_("BUF DATA\n")); if (print_data) { uint *dp = (uint *)*ptr; int nums = be32_to_cpu(head->oh_len) >> 2; int i = 0; while (i < nums) { if ((i % 8) == 0) printf("%2x ", i); printf("%8x ", *dp); dp++; i++; if ((i % 8) == 0) printf("\n"); } printf("\n"); } } *ptr += be32_to_cpu(head->oh_len); } if (head && head->oh_flags & XLOG_CONTINUE_TRANS) skip++; return skip; } /* xlog_print_trans_buffer */ int xlog_print_trans_efd(xfs_caddr_t *ptr, uint len) { xfs_efd_log_format_t *f; xfs_efd_log_format_t lbuf; /* size without extents at end */ uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t); /* * memmove to ensure 8-byte alignment for the long longs in * xfs_efd_log_format_t structure */ memmove(&lbuf, *ptr, MIN(core_size, len)); f = &lbuf; *ptr += len; if (len >= core_size) { printf(_("EFD: #regs: %d num_extents: %d id: 0x%llx\n"), f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id); /* don't print extents as they are not used */ return 0; } else { printf(_("EFD: Not enough data to decode further\n")); return 1; } } /* xlog_print_trans_efd */ int xlog_print_trans_efi(xfs_caddr_t *ptr, uint src_len) { xfs_efi_log_format_t *src_f, *f; uint dst_len; xfs_extent_t *ex; int i; int error = 0; /* * memmove to ensure 8-byte alignment for the long longs in * xfs_efi_log_format_t structure */ if ((src_f = (xfs_efi_log_format_t *)malloc(src_len)) == NULL) { fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname); exit(1); } memmove((char*)src_f, *ptr, src_len); *ptr += src_len; /* convert to native format */ dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t); if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) { fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname); exit(1); } if (xfs_efi_copy_format((char*)src_f, src_len, f)) { error = 1; goto error; } printf(_("EFI: #regs: %d num_extents: %d id: 0x%llx\n"), f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id); ex = f->efi_extents; for (i=0; i < f->efi_nextents; i++) { printf("(s: 0x%llx, l: %d) ", (unsigned long long)ex->ext_start, ex->ext_len); if (i % 4 == 3) printf("\n"); ex++; } if (i % 4 != 0) printf("\n"); error: free(src_f); free(f); return error; } /* xlog_print_trans_efi */ int xlog_print_trans_qoff(xfs_caddr_t *ptr, uint len) { xfs_qoff_logformat_t *f; xfs_qoff_logformat_t lbuf; memmove(&lbuf, *ptr, MIN(sizeof(xfs_qoff_logformat_t), len)); f = &lbuf; *ptr += len; if (len >= sizeof(xfs_qoff_logformat_t)) { printf(_("QOFF: #regs: %d flags: 0x%x\n"), f->qf_size, f->qf_flags); return 0; } else { printf(_("QOFF: Not enough data to decode further\n")); return 1; } } /* xlog_print_trans_qoff */ void xlog_print_trans_inode_core(xfs_icdinode_t *ip) { printf(_("INODE CORE\n")); printf(_("magic 0x%hx mode 0%ho version %d format %d\n"), ip->di_magic, ip->di_mode, (int)ip->di_version, (int)ip->di_format); printf(_("nlink %hd uid %d gid %d\n"), ip->di_nlink, ip->di_uid, ip->di_gid); printf(_("atime 0x%x mtime 0x%x ctime 0x%x\n"), ip->di_atime.t_sec, ip->di_mtime.t_sec, ip->di_ctime.t_sec); printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"), (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks, ip->di_extsize, ip->di_nextents); printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"), ip->di_anextents, (int)ip->di_forkoff, ip->di_dmevmask, ip->di_dmstate); printf(_("flags 0x%x gen 0x%x\n"), ip->di_flags, ip->di_gen); } void xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size) { xfs_ino_t ino; int count; int i; char namebuf[257]; xfs_dir_sf_entry_t *sfep; /* XXX need to determine whether this is v1 or v2, then print appropriate structure */ printf(_("SHORTFORM DIRECTORY size %d\n"), size); /* bail out for now */ return; printf(_("SHORTFORM DIRECTORY size %d count %d\n"), size, sfp->hdr.count); memmove(&ino, &(sfp->hdr.parent), sizeof(ino)); printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(ino)); count = (uint)(sfp->hdr.count); sfep = &(sfp->list[0]); for (i = 0; i < count; i++) { memmove(&ino, &(sfep->inumber), sizeof(ino)); memmove(namebuf, (sfep->name), sfep->namelen); namebuf[sfep->namelen] = '\0'; printf(_("%s ino 0x%llx namelen %d\n"), namebuf, (unsigned long long)ino, sfep->namelen); sfep = xfs_dir_sf_nextentry(sfep); } } int xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops) { xfs_icdinode_t dino; xlog_op_header_t *op_head; xfs_inode_log_format_t dst_lbuf; xfs_inode_log_format_64_t src_lbuf; /* buffer of biggest one */ xfs_inode_log_format_t *f; int mode; int size; /* * print inode type header region * * memmove to ensure 8-byte alignment for the long longs in * xfs_inode_log_format_t structure * * len can be smaller than xfs_inode_log_format_32|64_t * if format data is split over operations */ memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len)); (*i)++; /* bump index */ *ptr += len; if (len == sizeof(xfs_inode_log_format_32_t) || len == sizeof(xfs_inode_log_format_64_t)) { f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf); printf(_("INODE: ")); printf(_("#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n"), f->ilf_size, (unsigned long long)f->ilf_ino, f->ilf_fields, f->ilf_dsize); printf(_(" blkno: %lld len: %d boff: %d\n"), (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset); } else { ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */ f = (xfs_inode_log_format_t *)&src_lbuf; printf(_("INODE: #regs: %d Not printing rest of data\n"), f->ilf_size); return f->ilf_size; } if (*i >= num_ops) /* end of LR */ return f->ilf_size-1; /* core inode comes 2nd */ op_head = (xlog_op_header_t *)*ptr; xlog_print_op_header(op_head, *i, ptr); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) { return f->ilf_size-1; } memmove(&dino, *ptr, sizeof(dino)); mode = dino.di_mode & S_IFMT; size = (int)dino.di_size; xlog_print_trans_inode_core(&dino); *ptr += sizeof(xfs_icdinode_t); if (*i == num_ops-1 && f->ilf_size == 3) { return 1; } /* does anything come next */ op_head = (xlog_op_header_t *)*ptr; switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { case XFS_ILOG_DEV: printf(_("DEV inode: no extra region\n")); break; case XFS_ILOG_UUID: printf(_("UUID inode: no extra region\n")); break; } /* Only the inode core is logged */ if (f->ilf_size == 2) return 0; ASSERT(f->ilf_size <= 4); ASSERT((f->ilf_size == 3) || (f->ilf_fields & XFS_ILOG_AFORK)); if (f->ilf_fields & XFS_ILOG_DFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); switch (f->ilf_fields & XFS_ILOG_DFORK) { case XFS_ILOG_DEXT: printf(_("EXTENTS inode data\n")); break; case XFS_ILOG_DBROOT: printf(_("BTREE inode data\n")); break; case XFS_ILOG_DDATA: printf(_("LOCAL inode data\n")); if (mode == S_IFDIR) xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); break; default: ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0); break; } *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) return 1; op_head = (xlog_op_header_t *)*ptr; } if (f->ilf_fields & XFS_ILOG_AFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); switch (f->ilf_fields & XFS_ILOG_AFORK) { case XFS_ILOG_AEXT: printf(_("EXTENTS attr data\n")); break; case XFS_ILOG_ABROOT: printf(_("BTREE attr data\n")); break; case XFS_ILOG_ADATA: printf(_("LOCAL attr data\n")); if (mode == S_IFDIR) xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size); break; default: ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0); break; } *ptr += be32_to_cpu(op_head->oh_len); if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) return 1; op_head = (xlog_op_header_t *)*ptr; } return 0; } /* xlog_print_trans_inode */ int xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops) { xfs_dq_logformat_t *f; xfs_dq_logformat_t lbuf = {0}; xfs_disk_dquot_t ddq; xlog_op_header_t *head = NULL; int num, skip; /* * print dquot header region * * memmove to ensure 8-byte alignment for the long longs in * xfs_dq_logformat_t structure */ memmove(&lbuf, *ptr, MIN(sizeof(xfs_dq_logformat_t), len)); f = &lbuf; (*i)++; /* bump index */ *ptr += len; if (len == sizeof(xfs_dq_logformat_t)) { printf(_("#regs: %d id: 0x%x"), f->qlf_size, f->qlf_id); printf(_(" blkno: %lld len: %d boff: %d\n"), (long long)f->qlf_blkno, f->qlf_len, f->qlf_boffset); } else { ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */ printf(_("DQUOT: #regs: %d Not printing rest of data\n"), f->qlf_size); return f->qlf_size; } num = f->qlf_size-1; /* Check if all regions in this log item were in the given LR ptr */ if (*i+num > num_ops-1) { skip = num - (num_ops-1-*i); num = num_ops-1-*i; } else { skip = 0; } while (num-- > 0) { head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); ASSERT(be32_to_cpu(head->oh_len) == sizeof(xfs_disk_dquot_t)); memmove(&ddq, *ptr, sizeof(xfs_disk_dquot_t)); printf(_("DQUOT: magic 0x%hx flags 0%ho\n"), be16_to_cpu(ddq.d_magic), ddq.d_flags); *ptr += be32_to_cpu(head->oh_len); } if (head && head->oh_flags & XLOG_CONTINUE_TRANS) skip++; return skip; } /* xlog_print_trans_dquot */ /****************************************************************************** * * Log print routines * ****************************************************************************** */ void xlog_print_lseek(xlog_t *log, int fd, xfs_daddr_t blkno, int whence) { #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT) xfs_off_t offset; if (whence == SEEK_SET) offset = BBTOOFF64(blkno+log->l_logBBstart); else offset = BBTOOFF64(blkno); if (lseek64(fd, offset, whence) < 0) { fprintf(stderr, _("%s: lseek64 to %lld failed: %s\n"), progname, (long long)offset, strerror(errno)); exit(1); } } /* xlog_print_lseek */ void print_lsn(xfs_caddr_t string, __be64 *lsn) { printf("%s: %u,%u", string, CYCLE_LSN(be64_to_cpu(*lsn)), BLOCK_LSN(be64_to_cpu(*lsn))); } int xlog_print_record(int fd, int num_ops, int len, int *read_type, xfs_caddr_t *partial_buf, xlog_rec_header_t *rhead, xlog_rec_ext_header_t *xhdrs) { xfs_caddr_t buf, ptr; int read_len, skip; int ret, n, i, j, k; if (print_no_print) return NO_ERROR; if (!len) { printf("\n"); return NO_ERROR; } /* read_len must read up to some block boundary */ read_len = (int) BBTOB(BTOBB(len)); /* read_type => don't malloc() new buffer, use old one */ if (*read_type == FULL_READ) { if ((ptr = buf = (xfs_caddr_t)malloc(read_len)) == NULL) { fprintf(stderr, _("%s: xlog_print_record: malloc failed\n"), progname); exit(1); } } else { read_len -= *read_type; buf = (xfs_caddr_t)((__psint_t)(*partial_buf) + (__psint_t)(*read_type)); ptr = *partial_buf; } if ((ret = (int) read(fd, buf, read_len)) == -1) { fprintf(stderr, _("%s: xlog_print_record: read error\n"), progname); exit(1); } /* Did we overflow the end? */ if (*read_type == FULL_READ && BLOCK_LSN(be64_to_cpu(rhead->h_lsn)) + BTOBB(read_len) >= logBBsize) { *read_type = BBTOB(logBBsize - BLOCK_LSN(be64_to_cpu(rhead->h_lsn))-1); *partial_buf = buf; return PARTIAL_READ; } /* Did we read everything? */ if ((ret == 0 && read_len != 0) || ret != read_len) { *read_type = ret; *partial_buf = buf; return PARTIAL_READ; } if (*read_type != FULL_READ) read_len += *read_type; /* Everything read in. Start from beginning of buffer * Unpack the data, by putting the saved cycle-data back * into the first word of each BB. * Do some checks. */ buf = ptr; for (i = 0; ptr < buf + read_len; ptr += BBSIZE, i++) { xlog_rec_header_t *rechead = (xlog_rec_header_t *)ptr; /* sanity checks */ if (be32_to_cpu(rechead->h_magicno) == XLOG_HEADER_MAGIC_NUM) { /* data should not have magicno as first word * as it should by cycle# */ free(buf); return -1; } else { /* verify cycle# * FIXME: cycle+1 should be a macro pv#900369 */ if (be32_to_cpu(rhead->h_cycle) != be32_to_cpu(*(__be32 *)ptr)) { if (*read_type == FULL_READ) return -1; else if (be32_to_cpu(rhead->h_cycle) + 1 != be32_to_cpu(*(__be32 *)ptr)) return -1; } } /* copy back the data from the header */ if (i < XLOG_HEADER_CYCLE_SIZE / BBSIZE) { /* from 1st header */ *(__be32 *)ptr = rhead->h_cycle_data[i]; } else { ASSERT(xhdrs != NULL); /* from extra headers */ j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); *(__be32 *)ptr = xhdrs[j-1].xh_cycle_data[k]; } } ptr = buf; for (i=0; ioh_flags, XLOG_WAS_CONT_TRANS) || XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) && be32_to_cpu(op_head->oh_len) == 0)) { for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) { printf("%c", *ptr); ptr++; } printf("\n"); continue; } if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid), op_head->oh_flags & XLOG_WAS_CONT_TRANS)) { printf(_("Left over region from split log item\n")); ptr += be32_to_cpu(op_head->oh_len); continue; } if (be32_to_cpu(op_head->oh_len) != 0) { if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) { skip = xlog_print_trans_header(&ptr, be32_to_cpu(op_head->oh_len)); } else { switch (*(unsigned short *)ptr) { case XFS_LI_BUF: { skip = xlog_print_trans_buffer(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_INODE: { skip = xlog_print_trans_inode(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_DQUOT: { skip = xlog_print_trans_dquot(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_EFI: { skip = xlog_print_trans_efi(&ptr, be32_to_cpu(op_head->oh_len)); break; } case XFS_LI_EFD: { skip = xlog_print_trans_efd(&ptr, be32_to_cpu(op_head->oh_len)); break; } case XFS_LI_QUOTAOFF: { skip = xlog_print_trans_qoff(&ptr, be32_to_cpu(op_head->oh_len)); break; } case XLOG_UNMOUNT_TYPE: { printf(_("Unmount filesystem\n")); skip = 0; break; } default: { fprintf(stderr, _("%s: unknown log operation type (%x)\n"), progname, *(unsigned short *)ptr); if (print_exit) { free(buf); return BAD_HEADER; } skip = 0; ptr += be32_to_cpu(op_head->oh_len); } } /* switch */ } /* else */ if (skip != 0) xlog_print_add_to_trans(be32_to_cpu(op_head->oh_tid), skip); } } printf("\n"); free(buf); return NO_ERROR; } /* xlog_print_record */ int xlog_print_rec_head(xlog_rec_header_t *head, int *len) { int i; char uub[64]; int datalen,bbs; if (print_no_print) return be32_to_cpu(head->h_num_logops); if (!head->h_magicno) return ZEROED_LOG; if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { printf(_("Header 0x%x wanted 0x%x\n"), be32_to_cpu(head->h_magicno), XLOG_HEADER_MAGIC_NUM); return BAD_HEADER; } /* check for cleared blocks written by xlog_clear_stale_blocks() */ if (!head->h_len && !head->h_chksum && !head->h_prev_block && !head->h_num_logops && !head->h_size) return CLEARED_BLKS; datalen=be32_to_cpu(head->h_len); bbs=BTOBB(datalen); printf(_("cycle: %d version: %d "), be32_to_cpu(head->h_cycle), be32_to_cpu(head->h_version)); print_lsn(" lsn", &head->h_lsn); print_lsn(" tail_lsn", &head->h_tail_lsn); printf("\n"); printf(_("length of Log Record: %d prev offset: %d num ops: %d\n"), datalen, be32_to_cpu(head->h_prev_block), be32_to_cpu(head->h_num_logops)); if (print_overwrite) { printf(_("cycle num overwrites: ")); for (i=0; i< MIN(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) printf("%d - 0x%x ", i, be32_to_cpu(head->h_cycle_data[i])); printf("\n"); } platform_uuid_unparse(&head->h_fs_uuid, uub); printf(_("uuid: %s format: "), uub); switch (be32_to_cpu(head->h_fmt)) { case XLOG_FMT_UNKNOWN: printf(_("unknown\n")); break; case XLOG_FMT_LINUX_LE: printf(_("little endian linux\n")); break; case XLOG_FMT_LINUX_BE: printf(_("big endian linux\n")); break; case XLOG_FMT_IRIX_BE: printf(_("big endian irix\n")); break; default: printf("? (%d)\n", be32_to_cpu(head->h_fmt)); break; } printf(_("h_size: %d\n"), be32_to_cpu(head->h_size)); *len = be32_to_cpu(head->h_len); return(be32_to_cpu(head->h_num_logops)); } /* xlog_print_rec_head */ void xlog_print_rec_xhead(xlog_rec_ext_header_t *head, int coverage) { int i; print_xlog_xhdr_line(); printf(_("extended-header: cycle: %d\n"), be32_to_cpu(head->xh_cycle)); if (print_overwrite) { printf(_("cycle num overwrites: ")); for (i = 0; i < coverage; i++) printf("%d - 0x%x ", i, be32_to_cpu(head->xh_cycle_data[i])); printf("\n"); } } /* xlog_print_rec_xhead */ static void print_xlog_bad_zeroed(xfs_daddr_t blkno) { print_stars(); printf(_("* ERROR: found data after zeroed blocks block=%-21lld *\n"), (long long)blkno); print_stars(); if (print_exit) xlog_exit("Bad log - data after zeroed blocks"); } /* print_xlog_bad_zeroed */ static void print_xlog_bad_header(xfs_daddr_t blkno, xfs_caddr_t buf) { print_stars(); printf(_("* ERROR: header cycle=%-11d block=%-21lld *\n"), xlog_get_cycle(buf), (long long)blkno); print_stars(); if (print_exit) xlog_exit("Bad log record header"); } /* print_xlog_bad_header */ void print_xlog_bad_data(xfs_daddr_t blkno) { print_stars(); printf(_("* ERROR: data block=%-21lld *\n"), (long long)blkno); print_stars(); if (print_exit) xlog_exit("Bad data in log"); } /* print_xlog_bad_data */ static void print_xlog_bad_reqd_hdrs(xfs_daddr_t blkno, int num_reqd, int num_hdrs) { print_stars(); printf(_("* ERROR: for header block=%lld\n" "* not enough hdrs for data length, " "required num = %d, hdr num = %d\n"), (long long)blkno, num_reqd, num_hdrs); print_stars(); if (print_exit) xlog_exit(_("Not enough headers for data length.")); } /* print_xlog_bad_reqd_hdrs */ static void xlog_reallocate_xhdrs(int num_hdrs, xlog_rec_ext_header_t **ret_xhdrs) { int len = (num_hdrs-1) * sizeof(xlog_rec_ext_header_t); *ret_xhdrs = (xlog_rec_ext_header_t *)realloc(*ret_xhdrs, len); if (*ret_xhdrs == NULL) { fprintf(stderr, _("%s: xlog_print: malloc failed for ext hdrs\n"), progname); exit(1); } } /* for V2 logs read each extra hdr and print it out */ static int xlog_print_extended_headers( int fd, int len, xfs_daddr_t *blkno, xlog_rec_header_t *hdr, int *ret_num_hdrs, xlog_rec_ext_header_t **ret_xhdrs) { int i, j; int coverage_bb; int num_hdrs; int num_required; char xhbuf[XLOG_HEADER_SIZE]; xlog_rec_ext_header_t *x; num_required = howmany(len, XLOG_HEADER_CYCLE_SIZE); num_hdrs = be32_to_cpu(hdr->h_size) / XLOG_HEADER_CYCLE_SIZE; if (num_required > num_hdrs) { print_xlog_bad_reqd_hdrs((*blkno)-1, num_required, num_hdrs); } if (num_hdrs == 1) { free(*ret_xhdrs); *ret_xhdrs = NULL; *ret_num_hdrs = 1; return 0; } if (*ret_xhdrs == NULL || num_hdrs > *ret_num_hdrs) { xlog_reallocate_xhdrs(num_hdrs, ret_xhdrs); } *ret_num_hdrs = num_hdrs; /* don't include 1st header */ for (i = 1, x = *ret_xhdrs; i < num_hdrs; i++, (*blkno)++, x++) { /* read one extra header blk */ if (read(fd, xhbuf, 512) == 0) { printf(_("%s: physical end of log\n"), progname); print_xlog_record_line(); /* reached the end so return 1 */ return 1; } if (print_only_data) { printf(_("BLKNO: %lld\n"), (long long)*blkno); xlog_recover_print_data(xhbuf, 512); } else { if (i == num_hdrs - 1) { /* last header */ coverage_bb = BTOBB(len) % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); } else { /* earliear header */ coverage_bb = XLOG_HEADER_CYCLE_SIZE / BBSIZE; } xlog_print_rec_xhead((xlog_rec_ext_header_t*)xhbuf, coverage_bb); } /* Copy from buffer into xhdrs array for later. * Could endian convert here but then code later on * will look asymmetric with the 1 hdr normal case * which does endian coversion on access. */ x->xh_cycle = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle; for (j = 0; j < XLOG_HEADER_CYCLE_SIZE / BBSIZE; j++) { x->xh_cycle_data[j] = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle_data[j]; } } return 0; } /* * This code is gross and needs to be rewritten. */ void xfs_log_print(xlog_t *log, int fd, int print_block_start) { char hbuf[XLOG_HEADER_SIZE]; xlog_rec_header_t *hdr = (xlog_rec_header_t *)&hbuf[0]; xlog_rec_ext_header_t *xhdrs = NULL; int num_ops, len, num_hdrs = 1; xfs_daddr_t block_end = 0, block_start, blkno, error; xfs_daddr_t zeroed_blkno = 0, cleared_blkno = 0; int read_type = FULL_READ; xfs_caddr_t partial_buf; int zeroed = 0; int cleared = 0; logBBsize = log->l_logBBsize; /* * Normally, block_start and block_end are the same value since we * are printing the entire log. However, if the start block is given, * we still end at the end of the logical log. */ if ((error = xlog_print_find_oldest(log, &block_end))) { fprintf(stderr, _("%s: problem finding oldest LR\n"), progname); return; } if (print_block_start == -1) block_start = block_end; else block_start = print_block_start; xlog_print_lseek(log, fd, block_start, SEEK_SET); blkno = block_start; for (;;) { if (read(fd, hbuf, 512) == 0) { printf(_("%s: physical end of log\n"), progname); print_xlog_record_line(); break; } if (print_only_data) { printf(_("BLKNO: %lld\n"), (long long)blkno); xlog_recover_print_data(hbuf, 512); blkno++; goto loop; } num_ops = xlog_print_rec_head(hdr, &len); blkno++; if (zeroed && num_ops != ZEROED_LOG) { printf(_("%s: after %d zeroed blocks\n"), progname, zeroed); /* once we find zeroed blocks - that's all we expect */ print_xlog_bad_zeroed(blkno-1); /* reset count since we're assuming previous zeroed blocks * were bad */ zeroed = 0; } if (num_ops == ZEROED_LOG || num_ops == CLEARED_BLKS || num_ops == BAD_HEADER) { if (num_ops == ZEROED_LOG) { if (zeroed == 0) zeroed_blkno = blkno-1; zeroed++; } else if (num_ops == CLEARED_BLKS) { if (cleared == 0) cleared_blkno = blkno-1; cleared++; } else { print_xlog_bad_header(blkno-1, hbuf); } goto loop; } if (be32_to_cpu(hdr->h_version) == 2) { if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0) break; } error = xlog_print_record(fd, num_ops, len, &read_type, &partial_buf, hdr, xhdrs); switch (error) { case 0: { blkno += BTOBB(len); if (print_block_start != -1 && blkno >= block_end) /* If start specified, we */ goto end; /* end early */ break; } case -1: { print_xlog_bad_data(blkno-1); if (print_block_start != -1 && blkno >= block_end) /* If start specified, */ goto end; /* we end early */ xlog_print_lseek(log, fd, blkno, SEEK_SET); goto loop; } case PARTIAL_READ: { print_xlog_record_line(); printf(_("%s: physical end of log\n"), progname); print_xlog_record_line(); blkno = 0; xlog_print_lseek(log, fd, 0, SEEK_SET); /* * We may have hit the end of the log when we started at 0. * In this case, just end. */ if (block_start == 0) goto end; goto partial_log_read; } default: xlog_panic(_("illegal value")); } print_xlog_record_line(); loop: if (blkno >= logBBsize) { if (cleared) { printf(_("%s: skipped %d cleared blocks in range: %lld - %lld\n"), progname, cleared, (long long)(cleared_blkno), (long long)(cleared + cleared_blkno - 1)); if (cleared == logBBsize) printf(_("%s: totally cleared log\n"), progname); cleared=0; } if (zeroed) { printf(_("%s: skipped %d zeroed blocks in range: %lld - %lld\n"), progname, zeroed, (long long)(zeroed_blkno), (long long)(zeroed + zeroed_blkno - 1)); if (zeroed == logBBsize) printf(_("%s: totally zeroed log\n"), progname); zeroed=0; } printf(_("%s: physical end of log\n"), progname); print_xlog_record_line(); break; } } /* Do we need to print the first part of physical log? */ if (block_start != 0) { blkno = 0; xlog_print_lseek(log, fd, 0, SEEK_SET); for (;;) { if (read(fd, hbuf, 512) == 0) { xlog_panic(_("xlog_find_head: bad read")); } if (print_only_data) { printf(_("BLKNO: %lld\n"), (long long)blkno); xlog_recover_print_data(hbuf, 512); blkno++; goto loop2; } num_ops = xlog_print_rec_head(hdr, &len); blkno++; if (num_ops == ZEROED_LOG || num_ops == CLEARED_BLKS || num_ops == BAD_HEADER) { /* we only expect zeroed log entries or cleared log * entries at the end of the _physical_ log, * so treat them the same as bad blocks here */ print_xlog_bad_header(blkno-1, hbuf); if (blkno >= block_end) break; continue; } if (be32_to_cpu(hdr->h_version) == 2) { if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0) break; } partial_log_read: error= xlog_print_record(fd, num_ops, len, &read_type, &partial_buf, (xlog_rec_header_t *)hbuf, xhdrs); if (read_type != FULL_READ) len -= read_type; read_type = FULL_READ; if (!error) blkno += BTOBB(len); else { print_xlog_bad_data(blkno-1); xlog_print_lseek(log, fd, blkno, SEEK_SET); goto loop2; } print_xlog_record_line(); loop2: if (blkno >= block_end) break; } } end: printf(_("%s: logical end of log\n"), progname); print_xlog_record_line(); } /* * if necessary, convert an xfs_inode_log_format struct from 32bit or 64 bit versions * (which can have different field alignments) to the native version */ xfs_inode_log_format_t * xfs_inode_item_format_convert(char *src_buf, uint len, xfs_inode_log_format_t *in_f) { /* if we have native format then just return buf without copying data */ if (len == sizeof(xfs_inode_log_format_t)) { return (xfs_inode_log_format_t *)src_buf; } if (len == sizeof(xfs_inode_log_format_32_t)) { xfs_inode_log_format_32_t *in_f32; in_f32 = (xfs_inode_log_format_32_t *)src_buf; in_f->ilf_type = in_f32->ilf_type; in_f->ilf_size = in_f32->ilf_size; in_f->ilf_fields = in_f32->ilf_fields; in_f->ilf_asize = in_f32->ilf_asize; in_f->ilf_dsize = in_f32->ilf_dsize; in_f->ilf_ino = in_f32->ilf_ino; /* copy biggest */ memcpy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid, sizeof(uuid_t)); in_f->ilf_blkno = in_f32->ilf_blkno; in_f->ilf_len = in_f32->ilf_len; in_f->ilf_boffset = in_f32->ilf_boffset; } else { xfs_inode_log_format_64_t *in_f64; ASSERT(len == sizeof(xfs_inode_log_format_64_t)); in_f64 = (xfs_inode_log_format_64_t *)src_buf; in_f->ilf_type = in_f64->ilf_type; in_f->ilf_size = in_f64->ilf_size; in_f->ilf_fields = in_f64->ilf_fields; in_f->ilf_asize = in_f64->ilf_asize; in_f->ilf_dsize = in_f64->ilf_dsize; in_f->ilf_ino = in_f64->ilf_ino; /* copy biggest */ memcpy(&in_f->ilf_u.ilfu_uuid, &in_f64->ilf_u.ilfu_uuid, sizeof(uuid_t)); in_f->ilf_blkno = in_f64->ilf_blkno; in_f->ilf_len = in_f64->ilf_len; in_f->ilf_boffset = in_f64->ilf_boffset; } return in_f; } int xfs_efi_copy_format(char *buf, uint len, xfs_efi_log_format_t *dst_efi_fmt) { uint i; uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents; uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents - 1) * sizeof(xfs_extent_t); uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t); uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t); if (len == dst_len) { memcpy((char *)dst_efi_fmt, buf, len); return 0; } else if (len == len32) { xfs_efi_log_format_32_t *src_efi_fmt_32 = (xfs_efi_log_format_32_t *)buf; dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type; dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size; dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents; dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id; for (i = 0; i < dst_efi_fmt->efi_nextents; i++) { dst_efi_fmt->efi_extents[i].ext_start = src_efi_fmt_32->efi_extents[i].ext_start; dst_efi_fmt->efi_extents[i].ext_len = src_efi_fmt_32->efi_extents[i].ext_len; } return 0; } else if (len == len64) { xfs_efi_log_format_64_t *src_efi_fmt_64 = (xfs_efi_log_format_64_t *)buf; dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type; dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size; dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents; dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id; for (i = 0; i < dst_efi_fmt->efi_nextents; i++) { dst_efi_fmt->efi_extents[i].ext_start = src_efi_fmt_64->efi_extents[i].ext_start; dst_efi_fmt->efi_extents[i].ext_len = src_efi_fmt_64->efi_extents[i].ext_len; } return 0; } fprintf(stderr, _("%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n"), progname, len, len32, len64, nextents); return 1; } xfsprogs-3.1.9ubuntu2/logprint/Makefile0000664000000000000000000000110511330256617015113 0ustar # # Copyright (c) 2000-2001,2004 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_logprint HFILES = logprint.h CFILES = logprint.c \ log_copy.c log_dump.c log_misc.c \ log_print_all.c log_print_trans.c LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS = -static default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/logprint/log_dump.c0000664000000000000000000000401511146407622015427 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" /* * Dump log blocks, not data */ void xfs_log_dump( xlog_t *log, int fd, int print_block_start) { int r; uint last_cycle = -1; xfs_daddr_t blkno, dupblkno; xlog_rec_header_t *hdr; char buf[XLOG_HEADER_SIZE]; dupblkno = 0; hdr = (xlog_rec_header_t *)buf; xlog_print_lseek(log, fd, 0, SEEK_SET); for (blkno = 0; blkno < log->l_logBBsize; blkno++) { r = read(fd, buf, sizeof(buf)); if (r < 0) { fprintf(stderr, _("%s: read error (%lld): %s\n"), __FUNCTION__, (long long)blkno, strerror(errno)); continue; } else if (r == 0) { printf(_("%s: physical end of log at %lld\n"), __FUNCTION__, (long long)blkno); break; } if (CYCLE_LSN(be64_to_cpu(*(__be64 *)buf)) == XLOG_HEADER_MAGIC_NUM && !print_no_data) { printf(_( "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n"), (long long)blkno, be32_to_cpu(hdr->h_cycle), CYCLE_LSN(be64_to_cpu(hdr->h_tail_lsn)), BLOCK_LSN(be64_to_cpu(hdr->h_tail_lsn)), be32_to_cpu(hdr->h_len), be32_to_cpu(hdr->h_num_logops)); } if (xlog_get_cycle(buf) != last_cycle) { printf(_( "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n"), (long long)dupblkno, (long long)blkno, last_cycle, xlog_get_cycle(buf)); last_cycle = xlog_get_cycle(buf); dupblkno = blkno; } } } xfsprogs-3.1.9ubuntu2/logprint/logprint.c0000664000000000000000000001347611146407622015472 0ustar /* * Copyright (c) 2000-2004 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" #include #include #define OP_PRINT 0 #define OP_PRINT_TRANS 1 #define OP_DUMP 2 #define OP_COPY 3 int print_data; int print_only_data; int print_inode; int print_quota; int print_buffer; int print_overwrite; int print_no_data; int print_no_print; int print_exit = 1; /* -e is now default. specify -c to override */ int print_operation = OP_PRINT; void usage(void) { fprintf(stderr, _("Usage: %s [options...] \n\n\ Options:\n\ -c try to continue if error found in log\n\ -C copy the log from the filesystem to filename\n\ -d dump the log in log-record format\n\ -f specified device is actually a file\n\ -l filename of external log\n\ -n don't try and interpret log data\n\ -o print buffer data in hex\n\ -s block # to start printing\n\ -v print \"overwrite\" data\n\ -t print out transactional view\n\ -b in transactional view, extract buffer info\n\ -i in transactional view, extract inode info\n\ -q in transactional view, extract quota info\n\ -D print only data; no decoding\n\ -V print version information\n"), progname); exit(1); } int logstat(xfs_mount_t *mp) { int fd; char buf[BBSIZE]; xfs_sb_t *sb; /* On Linux we always read the superblock of the * filesystem. We need this to get the length of the * log. Otherwise we end up seeking forever. -- mkp */ if ((fd = open(x.dname, O_RDONLY)) == -1) { fprintf(stderr, _(" Can't open device %s: %s\n"), x.dname, strerror(errno)); exit(1); } lseek64(fd, 0, SEEK_SET); if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { fprintf(stderr, _(" read of XFS superblock failed\n")); exit(1); } close (fd); if (!x.disfile) { /* * Conjure up a mount structure */ sb = &mp->m_sb; libxfs_sb_from_disk(sb, (xfs_dsb_t *)buf); mp->m_blkbb_log = sb->sb_blocklog - BBSHIFT; x.logBBsize = XFS_FSB_TO_BB(mp, sb->sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, sb->sb_logstart); if (!x.logname && sb->sb_logstart == 0) { fprintf(stderr, _(" external log device not specified\n\n")); usage(); /*NOTREACHED*/ } } else { struct stat s; stat(x.dname, &s); x.logBBsize = s.st_size >> 9; x.logBBstart = 0; } if (x.logname && *x.logname) { /* External log */ if ((fd = open(x.logname, O_RDONLY)) == -1) { fprintf(stderr, _("Can't open file %s: %s\n"), x.logname, strerror(errno)); exit(1); } close(fd); } else { /* Internal log */ x.logdev = x.ddev; } return 0; } int main(int argc, char **argv) { int print_start = -1; int c; int logfd; char *copy_file = NULL; xlog_t log = {0}; xfs_mount_t mount; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); progname = basename(argv[0]); while ((c = getopt(argc, argv, "bC:cdefl:iqnors:tDVv")) != EOF) { switch (c) { case 'D': print_only_data++; print_data++; break; case 'b': print_buffer++; break; case 'c': /* default is to stop on error. * -c turns this off. */ print_exit = 0; break; case 'e': /* -e is now default */ print_exit++; break; case 'C': print_operation = OP_COPY; copy_file = optarg; break; case 'd': print_operation = OP_DUMP; break; case 'f': print_skip_uuid++; x.disfile = 1; break; case 'l': x.logname = optarg; x.lisfile = 1; break; case 'i': print_inode++; break; case 'q': print_quota++; break; case 'n': print_no_data++; break; case 'o': print_data++; break; case 's': print_start = atoi(optarg); break; case 't': print_operation = OP_PRINT_TRANS; break; case 'v': print_overwrite++; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': usage(); } } if (argc - optind != 1) usage(); x.dname = argv[optind]; if (x.dname == NULL) usage(); x.isreadonly = LIBXFS_ISINACTIVE; printf(_("xfs_logprint:\n")); if (!libxfs_init(&x)) exit(1); logstat(&mount); logfd = (x.logfd < 0) ? x.dfd : x.logfd; printf(_(" data device: 0x%llx\n"), (unsigned long long)x.ddev); if (x.logname) { printf(_(" log file: \"%s\" "), x.logname); } else { printf(_(" log device: 0x%llx "), (unsigned long long)x.logdev); } printf(_("daddr: %lld length: %lld\n\n"), (long long)x.logBBstart, (long long)x.logBBsize); ASSERT(x.logBBsize <= INT_MAX); log.l_dev = x.logdev; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBstart = x.logBBstart; log.l_logBBsize = x.logBBsize; log.l_mp = &mount; switch (print_operation) { case OP_PRINT: xfs_log_print(&log, logfd, print_start); break; case OP_PRINT_TRANS: xfs_log_print_trans(&log, print_start); break; case OP_DUMP: xfs_log_dump(&log, logfd, print_start); break; case OP_COPY: xfs_log_copy(&log, logfd, copy_file); break; } exit(0); } xfsprogs-3.1.9ubuntu2/logprint/logprint.h0000664000000000000000000000320311140033220015441 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LOGPRINT_H #define LOGPRINT_H #include /* command line flags */ extern int print_data; extern int print_only_data; extern int print_inode; extern int print_quota; extern int print_buffer; extern int print_transactions; extern int print_overwrite; extern int print_no_data; extern int print_no_print; /* exports */ extern char *trans_type[]; extern void xlog_print_lseek(xlog_t *, int, xfs_daddr_t, int); extern void xfs_log_copy(xlog_t *, int, char *); extern void xfs_log_dump(xlog_t *, int, int); extern void xfs_log_print(xlog_t *, int, int); extern void xfs_log_print_trans(xlog_t *, int); extern void print_xlog_record_line(void); extern void print_xlog_op_line(void); extern void print_stars(void); extern xfs_inode_log_format_t * xfs_inode_item_format_convert(char *, uint, xfs_inode_log_format_t *); extern int xfs_efi_copy_format(char *, uint, xfs_efi_log_format_t *); #endif /* LOGPRINT_H */ xfsprogs-3.1.9ubuntu2/logprint/log_print_trans.c0000664000000000000000000000374011650373061017030 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" void xlog_recover_print_trans_head( xlog_recover_t *tr) { printf(_("TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n"), tr->r_log_tid, trans_type[tr->r_theader.th_type], tr->r_theader.th_num_items, tr->r_theader.th_tid, (long)&tr->r_itemq); } int xlog_recover_do_trans( xlog_t *log, xlog_recover_t *trans, int pass) { xlog_recover_print_trans(trans, &trans->r_itemq, 3); return 0; } void xfs_log_print_trans( xlog_t *log, int print_block_start) { xfs_daddr_t head_blk, tail_blk; int error; error = xlog_find_tail(log, &head_blk, &tail_blk); if (error) { fprintf(stderr, _("%s: failed to find head and tail, error: %d\n"), progname, error); exit(1); } printf(_(" log tail: %lld head: %lld state: %s\n"), (long long)tail_blk, (long long)head_blk, (tail_blk == head_blk)?"":""); if (print_block_start != -1) { printf(_(" override tail: %d\n"), print_block_start); tail_blk = print_block_start; } printf("\n"); print_record_header = 1; if (head_blk == tail_blk) return; if ((error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1))) { fprintf(stderr, _("%s: failed in xfs_do_recovery_pass, error: %d\n"), progname, error); exit(1); } } xfsprogs-3.1.9ubuntu2/logprint/log_copy.c0000664000000000000000000000354311146407622015441 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" /* * Extract a log and write it out to a file */ void xfs_log_copy( xlog_t *log, int fd, char *filename) { int ofd, r; xfs_daddr_t blkno; char buf[XLOG_HEADER_SIZE]; if ((ofd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, 0666)) == -1) { perror("open"); exit(1); } xlog_print_lseek(log, fd, 0, SEEK_SET); for (blkno = 0; blkno < log->l_logBBsize; blkno++) { r = read(fd, buf, sizeof(buf)); if (r < 0) { fprintf(stderr, _("%s: read error (%lld): %s\n"), __FUNCTION__, (long long)blkno, strerror(errno)); continue; } else if (r == 0) { printf(_("%s: physical end of log at %lld\n"), __FUNCTION__, (long long)blkno); break; } else if (r != sizeof(buf)) { fprintf(stderr, _("%s: short read? (%lld)\n"), __FUNCTION__, (long long)blkno); continue; } r = write(ofd, buf, sizeof(buf)); if (r < 0) { fprintf(stderr, _("%s: write error (%lld): %s\n"), __FUNCTION__, (long long)blkno, strerror(errno)); break; } else if (r != sizeof(buf)) { fprintf(stderr, _("%s: short write? (%lld)\n"), __FUNCTION__, (long long)blkno); continue; } } close(ofd); } xfsprogs-3.1.9ubuntu2/logprint/log_print_all.c0000664000000000000000000003370711650373061016457 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "logprint.h" /* * Start is defined to be the block pointing to the oldest valid log record. */ int xlog_print_find_oldest( struct log *log, xfs_daddr_t *last_blk) { xfs_buf_t *bp; xfs_daddr_t first_blk; uint first_half_cycle, last_half_cycle; int error; if (xlog_find_zeroed(log, &first_blk)) return 0; first_blk = 0; /* read first block */ bp = xlog_get_bp(log, 1); xlog_bread_noalign(log, 0, 1, bp); first_half_cycle = xlog_get_cycle(XFS_BUF_PTR(bp)); *last_blk = log->l_logBBsize-1; /* read last block */ xlog_bread_noalign(log, *last_blk, 1, bp); last_half_cycle = xlog_get_cycle(XFS_BUF_PTR(bp)); ASSERT(last_half_cycle != 0); if (first_half_cycle == last_half_cycle) { /* all cycle nos are same */ *last_blk = 0; } else { /* have 1st and last; look for middle cycle */ error = xlog_find_cycle_start(log, bp, first_blk, last_blk, last_half_cycle); if (error) return error; } xlog_put_bp(bp); return 0; } void xlog_recover_print_data( xfs_caddr_t p, int len) { if (print_data) { uint *dp = (uint *)p; int nums = len >> 2; int j = 0; while (j < nums) { if ((j % 8) == 0) printf("%2x ", j); printf("%8x ", *dp); dp++; j++; if ((j % 8) == 0) printf("\n"); } printf("\n"); } } STATIC void xlog_recover_print_buffer( xlog_recover_item_t *item) { xfs_agi_t *agi; xfs_agf_t *agf; xfs_buf_log_format_t *f; xfs_caddr_t p; int len, num, i; xfs_daddr_t blkno; xfs_disk_dquot_t *ddq; f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; len = item->ri_buf[0].i_len; printf(" "); ASSERT(f->blf_type == XFS_LI_BUF); printf(_("BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n"), f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size, f->blf_flags); blkno = (xfs_daddr_t)f->blf_blkno; num = f->blf_size-1; i = 1; while (num-- > 0) { p = item->ri_buf[i].i_addr; len = item->ri_buf[i].i_len; i++; if (blkno == 0) { /* super block */ printf(_(" SUPER Block Buffer:\n")); if (!print_buffer) continue; printf(_(" icount:%llu ifree:%llu "), (unsigned long long) be64_to_cpu(*(__be64 *)(p)), (unsigned long long) be64_to_cpu(*(__be64 *)(p+8))); printf(_("fdblks:%llu frext:%llu\n"), (unsigned long long) be64_to_cpu(*(__be64 *)(p+16)), (unsigned long long) be64_to_cpu(*(__be64 *)(p+24))); printf(_(" sunit:%u swidth:%u\n"), be32_to_cpu(*(__be32 *)(p+56)), be32_to_cpu(*(__be32 *)(p+60))); } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGI_MAGIC) { agi = (xfs_agi_t *)p; printf(_(" AGI Buffer: (XAGI)\n")); if (!print_buffer) continue; printf(_(" ver:%d "), be32_to_cpu(agi->agi_versionnum)); printf(_("seq#:%d len:%d cnt:%d root:%d\n"), be32_to_cpu(agi->agi_seqno), be32_to_cpu(agi->agi_length), be32_to_cpu(agi->agi_count), be32_to_cpu(agi->agi_root)); printf(_(" level:%d free#:0x%x newino:0x%x\n"), be32_to_cpu(agi->agi_level), be32_to_cpu(agi->agi_freecount), be32_to_cpu(agi->agi_newino)); } else if (be32_to_cpu(*(__be32 *)p) == XFS_AGF_MAGIC) { agf = (xfs_agf_t *)p; printf(_(" AGF Buffer: (XAGF)\n")); if (!print_buffer) continue; printf(_(" ver:%d seq#:%d len:%d \n"), be32_to_cpu(agf->agf_versionnum), be32_to_cpu(agf->agf_seqno), be32_to_cpu(agf->agf_length)); printf(_(" root BNO:%d CNT:%d\n"), be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]), be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); printf(_(" level BNO:%d CNT:%d\n"), be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]), be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); printf(_(" 1st:%d last:%d cnt:%d " "freeblks:%d longest:%d\n"), be32_to_cpu(agf->agf_flfirst), be32_to_cpu(agf->agf_fllast), be32_to_cpu(agf->agf_flcount), be32_to_cpu(agf->agf_freeblks), be32_to_cpu(agf->agf_longest)); } else if (*(uint *)p == XFS_DQUOT_MAGIC) { ddq = (xfs_disk_dquot_t *)p; printf(_(" DQUOT Buffer:\n")); if (!print_buffer) continue; printf(_(" UIDs 0x%lx-0x%lx\n"), (unsigned long)be32_to_cpu(ddq->d_id), (unsigned long)be32_to_cpu(ddq->d_id) + (BBTOB(f->blf_len) / sizeof(xfs_dqblk_t)) - 1); } else { printf(_(" BUF DATA\n")); if (!print_buffer) continue; xlog_recover_print_data(p, len); } } } STATIC void xlog_recover_print_quotaoff( xlog_recover_item_t *item) { xfs_qoff_logformat_t *qoff_f; char str[32] = { 0 }; qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr; ASSERT(qoff_f); if (qoff_f->qf_flags & XFS_UQUOTA_ACCT) strcat(str, "USER QUOTA"); if (qoff_f->qf_flags & XFS_GQUOTA_ACCT) strcat(str, "GROUP QUOTA"); if (qoff_f->qf_flags & XFS_PQUOTA_ACCT) strcat(str, "PROJECT QUOTA"); printf(_("\tQUOTAOFF: #regs:%d type:%s\n"), qoff_f->qf_size, str); } STATIC void xlog_recover_print_dquot( xlog_recover_item_t *item) { xfs_dq_logformat_t *f; xfs_disk_dquot_t *d; f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr; ASSERT(f); ASSERT(f->qlf_len == 1); d = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr; printf(_("\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n"), f->qlf_size, (long long)f->qlf_blkno, f->qlf_boffset, f->qlf_id); if (!print_quota) return; printf(_("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n"), be16_to_cpu(d->d_magic), d->d_version, be32_to_cpu(d->d_id), be32_to_cpu(d->d_id)); printf(_("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x" "\tino_soft 0x%x\n"), (int)be64_to_cpu(d->d_blk_hardlimit), (int)be64_to_cpu(d->d_blk_softlimit), (int)be64_to_cpu(d->d_ino_hardlimit), (int)be64_to_cpu(d->d_ino_softlimit)); printf(_("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n"), (int)be64_to_cpu(d->d_bcount), (int)be64_to_cpu(d->d_bcount), (int)be64_to_cpu(d->d_icount), (int)be64_to_cpu(d->d_icount)); printf(_("\t\tbtimer 0x%x itimer 0x%x \n"), (int)be32_to_cpu(d->d_btimer), (int)be32_to_cpu(d->d_itimer)); } STATIC void xlog_recover_print_inode_core( xfs_icdinode_t *di) { printf(_(" CORE inode:\n")); if (!print_inode) return; printf(_(" magic:%c%c mode:0x%x ver:%d format:%d " "onlink:%d\n"), (di->di_magic>>8) & 0xff, di->di_magic & 0xff, di->di_mode, di->di_version, di->di_format, di->di_onlink); printf(_(" uid:%d gid:%d nlink:%d projid:%u\n"), di->di_uid, di->di_gid, di->di_nlink, xfs_get_projid(*di)); printf(_(" atime:%d mtime:%d ctime:%d\n"), di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec); printf(_(" flushiter:%d\n"), di->di_flushiter); printf(_(" size:0x%llx nblks:0x%llx exsize:%d " "nextents:%d anextents:%d\n"), (unsigned long long) di->di_size, (unsigned long long)di->di_nblocks, di->di_extsize, di->di_nextents, (int)di->di_anextents); printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x " "gen:%d\n"), (int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate, (int)di->di_flags, di->di_gen); } STATIC void xlog_recover_print_inode( xlog_recover_item_t *item) { xfs_inode_log_format_t f_buf; xfs_inode_log_format_t *f; int attr_index; int hasdata; int hasattr; ASSERT(item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_32_t) || item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_64_t)); f = xfs_inode_item_format_convert(item->ri_buf[0].i_addr, item->ri_buf[0].i_len, &f_buf); printf(_(" INODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n"), f->ilf_size, (unsigned long long)f->ilf_ino, f->ilf_fields, f->ilf_dsize); /* core inode comes 2nd */ ASSERT(item->ri_buf[1].i_len == sizeof(xfs_icdinode_t)); xlog_recover_print_inode_core((xfs_icdinode_t *) item->ri_buf[1].i_addr); hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0; hasattr = (f->ilf_fields & XFS_ILOG_AFORK) != 0; /* does anything come next */ switch (f->ilf_fields & (XFS_ILOG_DFORK|XFS_ILOG_DEV|XFS_ILOG_UUID)) { case XFS_ILOG_DEXT: ASSERT(f->ilf_size == 3 + hasattr); printf(_(" DATA FORK EXTENTS inode data:\n")); if (print_inode && print_data) xlog_recover_print_data(item->ri_buf[2].i_addr, item->ri_buf[2].i_len); break; case XFS_ILOG_DBROOT: ASSERT(f->ilf_size == 3 + hasattr); printf(_(" DATA FORK BTREE inode data:\n")); if (print_inode && print_data) xlog_recover_print_data(item->ri_buf[2].i_addr, item->ri_buf[2].i_len); break; case XFS_ILOG_DDATA: ASSERT(f->ilf_size == 3 + hasattr); printf(_(" DATA FORK LOCAL inode data:\n")); if (print_inode && print_data) xlog_recover_print_data(item->ri_buf[2].i_addr, item->ri_buf[2].i_len); break; case XFS_ILOG_DEV: ASSERT(f->ilf_size == 2 + hasattr); printf(_(" DEV inode: no extra region\n")); break; case XFS_ILOG_UUID: ASSERT(f->ilf_size == 2 + hasattr); printf(_(" UUID inode: no extra region\n")); break; case 0: ASSERT(f->ilf_size == 2 + hasattr); break; default: xlog_panic("xlog_print_trans_inode: illegal inode type"); } if (hasattr) { attr_index = 2 + hasdata; switch (f->ilf_fields & XFS_ILOG_AFORK) { case XFS_ILOG_AEXT: ASSERT(f->ilf_size == 3 + hasdata); printf(_(" ATTR FORK EXTENTS inode data:\n")); if (print_inode && print_data) xlog_recover_print_data( item->ri_buf[attr_index].i_addr, item->ri_buf[attr_index].i_len); break; case XFS_ILOG_ABROOT: ASSERT(f->ilf_size == 3 + hasdata); printf(_(" ATTR FORK BTREE inode data:\n")); if (print_inode && print_data) xlog_recover_print_data( item->ri_buf[attr_index].i_addr, item->ri_buf[attr_index].i_len); break; case XFS_ILOG_ADATA: ASSERT(f->ilf_size == 3 + hasdata); printf(_(" ATTR FORK LOCAL inode data:\n")); if (print_inode && print_data) xlog_recover_print_data( item->ri_buf[attr_index].i_addr, item->ri_buf[attr_index].i_len); break; default: xlog_panic("%s: illegal inode log flag", __FUNCTION__); } } } STATIC void xlog_recover_print_efd( xlog_recover_item_t *item) { xfs_efd_log_format_t *f; f = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; /* * An xfs_efd_log_format structure contains a variable length array * as the last field. * Each element is of size xfs_extent_32_t or xfs_extent_64_t. * However, the extents are never used and won't be printed. */ printf(_(" EFD: #regs: %d num_extents: %d id: 0x%llx\n"), f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id); } STATIC void xlog_recover_print_efi( xlog_recover_item_t *item) { xfs_efi_log_format_t *f, *src_f; xfs_extent_t *ex; int i; uint src_len, dst_len; src_f = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; src_len = item->ri_buf[0].i_len; /* * An xfs_efi_log_format structure contains a variable length array * as the last field. * Each element is of size xfs_extent_32_t or xfs_extent_64_t. * Need to convert to native format. */ dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t); if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) { fprintf(stderr, _("%s: xlog_recover_print_efi: malloc failed\n"), progname); exit(1); } if (xfs_efi_copy_format((char*)src_f, src_len, f)) { free(f); return; } printf(_(" EFI: #regs:%d num_extents:%d id:0x%llx\n"), f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id); ex = f->efi_extents; printf(" "); for (i=0; i< f->efi_nextents; i++) { printf("(s: 0x%llx, l: %d) ", (unsigned long long)ex->ext_start, ex->ext_len); if (i % 4 == 3) printf("\n"); ex++; } if (i % 4 != 0) printf("\n"); free(f); } void xlog_recover_print_logitem( xlog_recover_item_t *item) { switch (ITEM_TYPE(item)) { case XFS_LI_BUF: xlog_recover_print_buffer(item); break; case XFS_LI_INODE: xlog_recover_print_inode(item); break; case XFS_LI_EFD: xlog_recover_print_efd(item); break; case XFS_LI_EFI: xlog_recover_print_efi(item); break; case XFS_LI_DQUOT: xlog_recover_print_dquot(item); break; case XFS_LI_QUOTAOFF: xlog_recover_print_quotaoff(item); break; default: printf(_("xlog_recover_print_logitem: illegal type\n")); break; } } void xlog_recover_print_item( xlog_recover_item_t *item) { int i; switch (ITEM_TYPE(item)) { case XFS_LI_BUF: printf("BUF"); break; case XFS_LI_INODE: printf("INO"); break; case XFS_LI_EFD: printf("EFD"); break; case XFS_LI_EFI: printf("EFI"); break; case XFS_LI_DQUOT: printf("DQ "); break; case XFS_LI_QUOTAOFF: printf("QOFF"); break; default: cmn_err(CE_PANIC, _("%s: illegal type"), __FUNCTION__); break; } /* type isn't filled in yet printf(_("ITEM: type: %d cnt: %d total: %d "), item->ri_type, item->ri_cnt, item->ri_total); */ printf(_(": cnt:%d total:%d "), item->ri_cnt, item->ri_total); for (i=0; iri_cnt; i++) { printf(_("a:0x%lx len:%d "), (long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len); } printf("\n"); xlog_recover_print_logitem(item); } void xlog_recover_print_trans( xlog_recover_t *trans, struct list_head *itemq, int print) { xlog_recover_item_t *item; if (print < 3) return; print_xlog_record_line(); xlog_recover_print_trans_head(trans); list_for_each_entry(item, itemq, ri_list) xlog_recover_print_item(item); } xfsprogs-3.1.9ubuntu2/repair/0000775000000000000000000000000012062211564013075 5ustar xfsprogs-3.1.9ubuntu2/repair/phase6.c0000664000000000000000000027674612062210562014452 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "dir.h" #include "dir2.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "prefetch.h" #include "progress.h" #include "threads.h" #include "versions.h" static struct cred zerocr; static struct fsxattr zerofsx; static xfs_ino_t orphanage_ino; static struct xfs_name xfs_name_dot = {(unsigned char *)".", 1}; /* * Data structures used to keep track of directories where the ".." * entries are updated. These must be rebuilt after the initial pass */ typedef struct dotdot_update { struct dotdot_update *next; ino_tree_node_t *irec; xfs_agnumber_t agno; int ino_offset; } dotdot_update_t; static dotdot_update_t *dotdot_update_list; static int dotdot_update; static void add_dotdot_update( xfs_agnumber_t agno, ino_tree_node_t *irec, int ino_offset) { dotdot_update_t *dir = malloc(sizeof(dotdot_update_t)); if (!dir) do_error(_("malloc failed add_dotdot_update (%zu bytes)\n"), sizeof(dotdot_update_t)); dir->next = dotdot_update_list; dir->irec = irec; dir->agno = agno; dir->ino_offset = ino_offset; dotdot_update_list = dir; } /* * Data structures and routines to keep track of directory entries * and whether their leaf entry has been seen. Also used for name * duplicate checking and rebuilding step if required. */ typedef struct dir_hash_ent { struct dir_hash_ent *nextbyaddr; /* next in addr bucket */ struct dir_hash_ent *nextbyhash; /* next in name bucket */ struct dir_hash_ent *nextbyorder; /* next in order added */ xfs_dahash_t hashval; /* hash value of name */ __uint32_t address; /* offset of data entry */ xfs_ino_t inum; /* inode num of entry */ short junkit; /* name starts with / */ short seen; /* have seen leaf entry */ struct xfs_name name; } dir_hash_ent_t; typedef struct dir_hash_tab { int size; /* size of hash tables */ int names_duped; /* 1 = ent names malloced */ dir_hash_ent_t *first; /* ptr to first added entry */ dir_hash_ent_t *last; /* ptr to last added entry */ dir_hash_ent_t **byhash; /* ptr to name hash buckets */ dir_hash_ent_t **byaddr; /* ptr to addr hash buckets */ } dir_hash_tab_t; #define DIR_HASH_TAB_SIZE(n) \ (sizeof(dir_hash_tab_t) + (sizeof(dir_hash_ent_t *) * (n) * 2)) #define DIR_HASH_FUNC(t,a) ((a) % (t)->size) /* * Track the contents of the freespace table in a directory. */ typedef struct freetab { int naents; /* expected number of data blocks */ int nents; /* number of data blocks processed */ struct freetab_ent { xfs_dir2_data_off_t v; short s; } ents[1]; } freetab_t; #define FREETAB_SIZE(n) \ (offsetof(freetab_t, ents) + (sizeof(struct freetab_ent) * (n))) #define DIR_HASH_CK_OK 0 #define DIR_HASH_CK_DUPLEAF 1 #define DIR_HASH_CK_BADHASH 2 #define DIR_HASH_CK_NODATA 3 #define DIR_HASH_CK_NOLEAF 4 #define DIR_HASH_CK_BADSTALE 5 #define DIR_HASH_CK_TOTAL 6 /* * Returns 0 if the name already exists (ie. a duplicate) */ static int dir_hash_add( xfs_mount_t *mp, dir_hash_tab_t *hashtab, __uint32_t addr, xfs_ino_t inum, int namelen, unsigned char *name) { xfs_dahash_t hash = 0; int byaddr; int byhash = 0; dir_hash_ent_t *p; int dup; short junk; struct xfs_name xname; ASSERT(!hashtab->names_duped); xname.name = name; xname.len = namelen; junk = name[0] == '/'; byaddr = DIR_HASH_FUNC(hashtab, addr); dup = 0; if (!junk) { hash = mp->m_dirnameops->hashname(&xname); byhash = DIR_HASH_FUNC(hashtab, hash); /* * search hash bucket for existing name. */ for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) { if (p->hashval == hash && p->name.len == namelen) { if (memcmp(p->name.name, name, namelen) == 0) { dup = 1; junk = 1; break; } } } } if ((p = malloc(sizeof(*p))) == NULL) do_error(_("malloc failed in dir_hash_add (%zu bytes)\n"), sizeof(*p)); p->nextbyaddr = hashtab->byaddr[byaddr]; hashtab->byaddr[byaddr] = p; if (hashtab->last) hashtab->last->nextbyorder = p; else hashtab->first = p; p->nextbyorder = NULL; hashtab->last = p; if (!(p->junkit = junk)) { p->hashval = hash; p->nextbyhash = hashtab->byhash[byhash]; hashtab->byhash[byhash] = p; } p->address = addr; p->inum = inum; p->seen = 0; p->name = xname; return !dup; } /* * checks to see if any data entries are not in the leaf blocks */ static int dir_hash_unseen( dir_hash_tab_t *hashtab) { int i; dir_hash_ent_t *p; for (i = 0; i < hashtab->size; i++) { for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) { if (p->seen == 0) return 1; } } return 0; } static int dir_hash_check( dir_hash_tab_t *hashtab, xfs_inode_t *ip, int seeval) { static char *seevalstr[DIR_HASH_CK_TOTAL]; static int done; if (!done) { seevalstr[DIR_HASH_CK_OK] = _("ok"); seevalstr[DIR_HASH_CK_DUPLEAF] = _("duplicate leaf"); seevalstr[DIR_HASH_CK_BADHASH] = _("hash value mismatch"); seevalstr[DIR_HASH_CK_NODATA] = _("no data entry"); seevalstr[DIR_HASH_CK_NOLEAF] = _("no leaf entry"); seevalstr[DIR_HASH_CK_BADSTALE] = _("bad stale count"); done = 1; } if (seeval == DIR_HASH_CK_OK && dir_hash_unseen(hashtab)) seeval = DIR_HASH_CK_NOLEAF; if (seeval == DIR_HASH_CK_OK) return 0; do_warn(_("bad hash table for directory inode %" PRIu64 " (%s): "), ip->i_ino, seevalstr[seeval]); if (!no_modify) do_warn(_("rebuilding\n")); else do_warn(_("would rebuild\n")); return 1; } static void dir_hash_done( dir_hash_tab_t *hashtab) { int i; dir_hash_ent_t *n; dir_hash_ent_t *p; for (i = 0; i < hashtab->size; i++) { for (p = hashtab->byaddr[i]; p; p = n) { n = p->nextbyaddr; if (hashtab->names_duped) free((void *)p->name.name); free(p); } } free(hashtab); } static dir_hash_tab_t * dir_hash_init( xfs_fsize_t size) { dir_hash_tab_t *hashtab; int hsize; hsize = size / (16 * 4); if (hsize > 65536) hsize = 63336; else if (hsize < 16) hsize = 16; if ((hashtab = calloc(DIR_HASH_TAB_SIZE(hsize), 1)) == NULL) do_error(_("calloc failed in dir_hash_init\n")); hashtab->size = hsize; hashtab->byhash = (dir_hash_ent_t**)((char *)hashtab + sizeof(dir_hash_tab_t)); hashtab->byaddr = (dir_hash_ent_t**)((char *)hashtab + sizeof(dir_hash_tab_t) + sizeof(dir_hash_ent_t*) * hsize); return hashtab; } static int dir_hash_see( dir_hash_tab_t *hashtab, xfs_dahash_t hash, xfs_dir2_dataptr_t addr) { int i; dir_hash_ent_t *p; i = DIR_HASH_FUNC(hashtab, addr); for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) { if (p->address != addr) continue; if (p->seen) return DIR_HASH_CK_DUPLEAF; if (p->junkit == 0 && p->hashval != hash) return DIR_HASH_CK_BADHASH; p->seen = 1; return DIR_HASH_CK_OK; } return DIR_HASH_CK_NODATA; } /* * checks to make sure leafs match a data entry, and that the stale * count is valid. */ static int dir_hash_see_all( dir_hash_tab_t *hashtab, xfs_dir2_leaf_entry_t *ents, int count, int stale) { int i; int j; int rval; for (i = j = 0; i < count; i++) { if (be32_to_cpu(ents[i].address) == XFS_DIR2_NULL_DATAPTR) { j++; continue; } rval = dir_hash_see(hashtab, be32_to_cpu(ents[i].hashval), be32_to_cpu(ents[i].address)); if (rval != DIR_HASH_CK_OK) return rval; } return j == stale ? DIR_HASH_CK_OK : DIR_HASH_CK_BADSTALE; } /* * Convert name pointers into locally allocated memory. * This must only be done after all the entries have been added. */ static void dir_hash_dup_names(dir_hash_tab_t *hashtab) { unsigned char *name; dir_hash_ent_t *p; if (hashtab->names_duped) return; for (p = hashtab->first; p; p = p->nextbyorder) { name = malloc(p->name.len); memcpy(name, p->name.name, p->name.len); p->name.name = name; } hashtab->names_duped = 1; } /* * Given a block number in a fork, return the next valid block number * (not a hole). * If this is the last block number then NULLFILEOFF is returned. * * This was originally in the kernel, but only used in xfs_repair. */ static int bmap_next_offset( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ xfs_fileoff_t *bnop, /* current block */ int whichfork) /* data or attr fork */ { xfs_fileoff_t bno; /* current block */ int eof; /* hit end of file */ int error; /* error return value */ xfs_bmbt_irec_t got; /* current extent value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last extent used */ xfs_bmbt_irec_t prev; /* previous extent value */ if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return EIO; if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { *bnop = NULLFILEOFF; return 0; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) return error; bno = *bnop + 1; xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (eof) *bnop = NULLFILEOFF; else *bnop = got.br_startoff < bno ? bno : got.br_startoff; return 0; } static void res_failed( int err) { if (err == ENOSPC) { do_error(_("ran out of disk space!\n")); } else do_error(_("xfs_trans_reserve returned %d\n"), err); } void mk_rbmino(xfs_mount_t *mp) { xfs_trans_t *tp; xfs_inode_t *ip; xfs_bmbt_irec_t *ep; xfs_fsblock_t first; int i; int nmap; int committed; int error; xfs_bmap_free_t flist; xfs_dfiloff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; /* * first set up inode */ tp = libxfs_trans_alloc(mp, 0); if ((i = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip); if (error) { do_error( _("couldn't iget realtime bitmap inode -- error - %d\n"), error); } memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = S_IFREG; ip->i_d.di_version = 1; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for sb ptr */ /* * now the ifork */ ip->i_df.if_flags = XFS_IFEXTENTS; ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; ip->i_df.if_u1.if_extents = NULL; ip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; /* * commit changes */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* * then allocate blocks for file and fill with zeroes (stolen * from mkfs) */ tp = libxfs_trans_alloc(mp, 0); if ((error = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0))) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); bno = 0; xfs_bmap_init(&flist, &first); while (bno < mp->m_sb.sb_rbmblocks) { nmap = XFS_BMAP_MAX_NMAP; error = libxfs_bmapi(tp, ip, bno, (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno), XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks, map, &nmap, &flist); if (error) { do_error( _("couldn't allocate realtime bitmap, error = %d\n"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { libxfs_device_zero(mp->m_dev, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; } } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error( _("allocation of the realtime bitmap failed, error = %d\n"), error); } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } static int fill_rbmino(xfs_mount_t *mp) { xfs_buf_t *bp; xfs_trans_t *tp; xfs_inode_t *ip; xfs_rtword_t *bmp; xfs_fsblock_t first; int nmap; int error; xfs_dfiloff_t bno; xfs_bmbt_irec_t map; bmp = btmcompute; bno = 0; tp = libxfs_trans_alloc(mp, 0); if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) res_failed(error); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip); if (error) { do_error( _("couldn't iget realtime bitmap inode -- error - %d\n"), error); } while (bno < mp->m_sb.sb_rbmblocks) { /* * fill the file one block at a time */ nmap = 1; error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, &first, 1, &map, &nmap, NULL); if (error || nmap != 1) { do_error( _("couldn't map realtime bitmap block %" PRIu64 ", error = %d\n"), bno, error); } ASSERT(map.br_startblock != HOLESTARTBLOCK); error = libxfs_trans_read_buf( mp, tp, mp->m_dev, XFS_FSB_TO_DADDR(mp, map.br_startblock), XFS_FSB_TO_BB(mp, 1), 1, &bp); if (error) { do_warn( _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %" PRIu64 "\n"), bno, map.br_startblock, mp->m_sb.sb_rbmino); return(1); } memmove(XFS_BUF_PTR(bp), bmp, mp->m_sb.sb_blocksize); libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); bmp = (xfs_rtword_t *)((__psint_t) bmp + mp->m_sb.sb_blocksize); bno++; } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); return(0); } static int fill_rsumino(xfs_mount_t *mp) { xfs_buf_t *bp; xfs_trans_t *tp; xfs_inode_t *ip; xfs_suminfo_t *smp; xfs_fsblock_t first; int nmap; int error; xfs_dfiloff_t bno; xfs_dfiloff_t end_bno; xfs_bmbt_irec_t map; smp = sumcompute; bno = 0; end_bno = mp->m_rsumsize >> mp->m_sb.sb_blocklog; tp = libxfs_trans_alloc(mp, 0); if ((error = libxfs_trans_reserve(tp, 10, 0, 0, 0, 0))) res_failed(error); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip); if (error) { do_error( _("couldn't iget realtime summary inode -- error - %d\n"), error); } while (bno < end_bno) { /* * fill the file one block at a time */ nmap = 1; error = libxfs_bmapi(tp, ip, bno, 1, XFS_BMAPI_WRITE, &first, 1, &map, &nmap, NULL); if (error || nmap != 1) { do_error( _("couldn't map realtime summary inode block %" PRIu64 ", error = %d\n"), bno, error); } ASSERT(map.br_startblock != HOLESTARTBLOCK); error = libxfs_trans_read_buf( mp, tp, mp->m_dev, XFS_FSB_TO_DADDR(mp, map.br_startblock), XFS_FSB_TO_BB(mp, 1), 1, &bp); if (error) { do_warn( _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode %" PRIu64 "\n"), bno, map.br_startblock, mp->m_sb.sb_rsumino); return(1); } memmove(XFS_BUF_PTR(bp), smp, mp->m_sb.sb_blocksize); libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); smp = (xfs_suminfo_t *)((__psint_t)smp + mp->m_sb.sb_blocksize); bno++; } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); return(0); } static void mk_rsumino(xfs_mount_t *mp) { xfs_trans_t *tp; xfs_inode_t *ip; xfs_bmbt_irec_t *ep; xfs_fsblock_t first; int i; int nmap; int committed; int error; int nsumblocks; xfs_bmap_free_t flist; xfs_dfiloff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; /* * first set up inode */ tp = libxfs_trans_alloc(mp, 0); if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip); if (error) { do_error( _("couldn't iget realtime summary inode -- error - %d\n"), error); } memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = S_IFREG; ip->i_d.di_version = 1; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for sb ptr */ /* * now the ifork */ ip->i_df.if_flags = XFS_IFEXTENTS; ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; ip->i_df.if_u1.if_extents = NULL; ip->i_d.di_size = mp->m_rsumsize; /* * commit changes */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); libxfs_trans_ihold(tp, ip); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* * then allocate blocks for file and fill with zeroes (stolen * from mkfs) */ tp = libxfs_trans_alloc(mp, 0); xfs_bmap_init(&flist, &first); nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog; if ((error = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), BBTOB(128), 0, XFS_TRANS_PERM_LOG_RES, XFS_DEFAULT_PERM_LOG_COUNT))) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); bno = 0; xfs_bmap_init(&flist, &first); while (bno < nsumblocks) { nmap = XFS_BMAP_MAX_NMAP; error = libxfs_bmapi(tp, ip, bno, (xfs_extlen_t)(nsumblocks - bno), XFS_BMAPI_WRITE, &first, nsumblocks, map, &nmap, &flist); if (error) { do_error( _("couldn't allocate realtime summary inode, error = %d\n"), error); } for (i = 0, ep = map; i < nmap; i++, ep++) { libxfs_device_zero(mp->m_dev, XFS_FSB_TO_DADDR(mp, ep->br_startblock), XFS_FSB_TO_BB(mp, ep->br_blockcount)); bno += ep->br_blockcount; } } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error( _("allocation of the realtime summary ino failed, error = %d\n"), error); } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } /* * makes a new root directory. */ static void mk_root_dir(xfs_mount_t *mp) { xfs_trans_t *tp; xfs_inode_t *ip; int i; int error; const mode_t mode = 0755; ino_tree_node_t *irec; ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); tp = libxfs_trans_alloc(mp, 0); ip = NULL; if ((i = libxfs_trans_reserve(tp, 10, XFS_ICHANGE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) res_failed(i); error = libxfs_trans_iget(mp, tp, mp->m_sb.sb_rootino, 0, 0, &ip); if (error) { do_error(_("could not iget root inode -- error - %d\n"), error); } /* * take care of the core -- initialization from xfs_ialloc() */ memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_mode = (__uint16_t) mode|S_IFDIR; ip->i_d.di_version = 1; ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_nlink = 1; /* account for . */ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); /* * now the ifork */ ip->i_df.if_flags = XFS_IFEXTENTS; ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; ip->i_df.if_u1.if_extents = NULL; mp->m_rootip = ip; /* * initialize the directory */ libxfs_dir_init(tp, ip, ip); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); set_inode_isadir(irec, XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino) - irec->ino_startnum); } /* * orphanage name == lost+found */ static xfs_ino_t mk_orphanage(xfs_mount_t *mp) { xfs_ino_t ino; xfs_trans_t *tp; xfs_inode_t *ip; xfs_inode_t *pip; xfs_fsblock_t first; ino_tree_node_t *irec; int ino_offset = 0; int i; int committed; int error; xfs_bmap_free_t flist; const int mode = 0755; int nres; struct xfs_name xname; ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); /* * check for an existing lost+found first, if it exists, return * its inode. Otherwise, we can create it. Bad lost+found inodes * would have been cleared in phase3 and phase4. */ if ((i = libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip, 0))) do_error(_("%d - couldn't iget root inode to obtain %s\n"), i, ORPHANAGE); xname.name = (unsigned char *)ORPHANAGE; xname.len = strlen(ORPHANAGE); if (libxfs_dir_lookup(NULL, pip, &xname, &ino, NULL) == 0) return ino; /* * could not be found, create it */ tp = libxfs_trans_alloc(mp, 0); xfs_bmap_init(&flist, &first); nres = XFS_MKDIR_SPACE_RES(mp, xname.len); if ((i = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT))) res_failed(i); /* * use iget/ijoin instead of trans_iget because the ialloc * wrapper can commit the transaction and start a new one */ /* if ((i = libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip, 0))) do_error(_("%d - couldn't iget root inode to make %s\n"), i, ORPHANAGE);*/ error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0, &zerocr, &zerofsx, &ip); if (error) { do_error(_("%s inode allocation failed %d\n"), ORPHANAGE, error); } ip->i_d.di_nlink++; /* account for . */ ino = ip->i_ino; irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGINO(mp, ino)); ino_offset = get_inode_offset(mp, ino, irec); /* * Mark the inode allocated to lost+found as used in the AVL tree * so it is not skipped in phase 7 */ set_inode_used(irec, ino_offset); add_inode_ref(irec, ino_offset); /* * now that we know the transaction will stay around, * add the root inode to it */ libxfs_trans_ijoin(tp, pip, 0); /* * create the actual entry */ error = libxfs_dir_createname(tp, pip, &xname, ip->i_ino, &first, &flist, nres); if (error) do_error( _("can't make %s, createname error %d\n"), ORPHANAGE, error); /* * bump up the link count in the root directory to account * for .. in the new directory */ pip->i_d.di_nlink++; add_inode_ref(find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)), 0); libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); libxfs_dir_init(tp, ip, pip); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_error(_("%s directory creation failed -- bmapf error %d\n"), ORPHANAGE, error); } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); add_inode_reached(irec,ino_offset); return(ino); } /* * move a file to the orphange. */ static void mv_orphanage( xfs_mount_t *mp, xfs_ino_t ino, /* inode # to be moved */ int isa_dir) /* 1 if inode is a directory */ { xfs_inode_t *orphanage_ip; xfs_ino_t entry_ino_num; xfs_inode_t *ino_p; xfs_trans_t *tp; xfs_fsblock_t first; xfs_bmap_free_t flist; int err; int committed; unsigned char fname[MAXPATHLEN + 1]; int nres; int incr; ino_tree_node_t *irec; int ino_offset = 0; struct xfs_name xname; ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); xname.name = fname; xname.len = snprintf((char *)fname, sizeof(fname), "%llu", (unsigned long long)ino); err = libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip, 0); if (err) do_error(_("%d - couldn't iget orphanage inode\n"), err); /* * Make sure the filename is unique in the lost+found */ incr = 0; while (libxfs_dir_lookup(NULL, orphanage_ip, &xname, &entry_ino_num, NULL) == 0) xname.len = snprintf((char *)fname, sizeof(fname), "%llu.%d", (unsigned long long)ino, ++incr); tp = libxfs_trans_alloc(mp, 0); if ((err = libxfs_iget(mp, NULL, ino, 0, &ino_p, 0))) do_error(_("%d - couldn't iget disconnected inode\n"), err); if (isa_dir) { irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, orphanage_ino), XFS_INO_TO_AGINO(mp, orphanage_ino)); if (irec) ino_offset = XFS_INO_TO_AGINO(mp, orphanage_ino) - irec->ino_startnum; nres = XFS_DIRENTER_SPACE_RES(mp, fnamelen) + XFS_DIRENTER_SPACE_RES(mp, 2); err = libxfs_dir_lookup(tp, ino_p, &xfs_name_dotdot, &entry_ino_num, NULL); if (err) { ASSERT(err == ENOENT); if ((err = libxfs_trans_reserve(tp, nres, XFS_RENAME_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT))) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); libxfs_trans_ijoin(tp, orphanage_ip, 0); libxfs_trans_ijoin(tp, ino_p, 0); xfs_bmap_init(&flist, &first); err = libxfs_dir_createname(tp, orphanage_ip, &xname, ino, &first, &flist, nres); if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); if (irec) add_inode_ref(irec, ino_offset); else orphanage_ip->i_d.di_nlink++; libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); err = libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot, orphanage_ino, &first, &flist, nres); if (err) do_error( _("creation of .. entry failed (%d), filesystem may be out of space\n"), err); ino_p->i_d.di_nlink++; libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE); err = libxfs_bmap_finish(&tp, &flist, &committed); if (err) do_error( _("bmap finish failed (err - %d), filesystem may be out of space\n"), err); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } else { if ((err = libxfs_trans_reserve(tp, nres, XFS_RENAME_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT))) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); libxfs_trans_ijoin(tp, orphanage_ip, 0); libxfs_trans_ijoin(tp, ino_p, 0); xfs_bmap_init(&flist, &first); err = libxfs_dir_createname(tp, orphanage_ip, &xname, ino, &first, &flist, nres); if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); if (irec) add_inode_ref(irec, ino_offset); else orphanage_ip->i_d.di_nlink++; libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); /* * don't replace .. value if it already points * to us. that'll pop a libxfs/kernel ASSERT. */ if (entry_ino_num != orphanage_ino) { err = libxfs_dir_replace(tp, ino_p, &xfs_name_dotdot, orphanage_ino, &first, &flist, nres); if (err) do_error( _("name replace op failed (%d), filesystem may be out of space\n"), err); } err = libxfs_bmap_finish(&tp, &flist, &committed); if (err) do_error( _("bmap finish failed (%d), filesystem may be out of space\n"), err); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } else { /* * use the remove log reservation as that's * more accurate. we're only creating the * links, we're not doing the inode allocation * also accounted for in the create */ nres = XFS_DIRENTER_SPACE_RES(mp, xname.len); err = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); if (err) do_error( _("space reservation failed (%d), filesystem may be out of space\n"), err); libxfs_trans_ijoin(tp, orphanage_ip, 0); libxfs_trans_ijoin(tp, ino_p, 0); xfs_bmap_init(&flist, &first); err = libxfs_dir_createname(tp, orphanage_ip, &xname, ino, &first, &flist, nres); if (err) do_error( _("name create failed in %s (%d), filesystem may be out of space\n"), ORPHANAGE, err); ASSERT(err == 0); ino_p->i_d.di_nlink = 1; libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE); err = libxfs_bmap_finish(&tp, &flist, &committed); if (err) do_error( _("bmap finish failed (%d), filesystem may be out of space\n"), err); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } /* * Returns the fsbno of the first (leftmost) block in the directory leaf. * sets *bno to the directory block # corresponding to the returned fsbno. */ static xfs_dfsbno_t map_first_dblock_fsbno(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, xfs_dablk_t *bno) { xfs_fsblock_t fblock; xfs_da_intnode_t *node; xfs_buf_t *bp; xfs_dablk_t da_bno; xfs_dfsbno_t fsbno; xfs_bmbt_irec_t map; int nmap; int i; int error; char *ftype; /* * traverse down left-side of tree until we hit the * left-most leaf block setting up the btree cursor along * the way. */ da_bno = 0; *bno = 0; i = -1; node = NULL; fblock = NULLFSBLOCK; ftype = _("dir"); nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, XFS_BMAPI_METADATA, &fblock, 0, &map, &nmap, NULL); if (error || nmap != 1) { if (!no_modify) do_error( _("can't map block %d in %s inode %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ftype, ino, error, nmap); else { do_warn( _("can't map block %d in %s inode %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ftype, ino, error, nmap); return(NULLDFSBNO); } } if ((fsbno = map.br_startblock) == HOLESTARTBLOCK) { if (!no_modify) do_error( _("block %d in %s ino %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); else { do_warn( _("block %d in %s ino %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); return(NULLDFSBNO); } } if (ip->i_d.di_size <= XFS_LBSIZE(mp)) return(fsbno); if (xfs_sb_version_hasdirv2(&mp->m_sb)) return(fsbno); do { /* * walk down left side of btree, release buffers as you * go. if the root block is a leaf (single-level btree), * just return it. * */ bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), da_bno, fsbno, ino); return(NULLDFSBNO); } node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { libxfs_putbuf(bp); do_warn( _("bad dir/attr magic number in inode %" PRIu64 ", file bno = %u, fsbno = %" PRIu64 "\n"), ino, da_bno, fsbno); return(NULLDFSBNO); } if (i == -1) i = be16_to_cpu(node->hdr.level); da_bno = be32_to_cpu(node->btree[0].before); libxfs_putbuf(bp); bp = NULL; nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t) da_bno, 1, XFS_BMAPI_METADATA, &fblock, 0, &map, &nmap, NULL); if (error || nmap != 1) { if (!no_modify) do_error( _("can't map block %d in %s ino %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ftype, ino, error, nmap); else { do_warn( _("can't map block %d in %s ino %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ftype, ino, error, nmap); return(NULLDFSBNO); } } if ((fsbno = map.br_startblock) == HOLESTARTBLOCK) { if (!no_modify) do_error( _("block %d in %s inode %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); else { do_warn( _("block %d in %s inode %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); return(NULLDFSBNO); } } i--; } while(i > 0); *bno = da_bno; return(fsbno); } static int entry_junked( const char *msg, const char *iname, xfs_ino_t ino1, xfs_ino_t ino2) { do_warn(msg, iname, ino1, ino2); if (!no_modify) { if (verbose) do_warn(_(", marking entry to be junked\n")); else do_warn("\n"); } else do_warn(_(", would junk entry\n")); return !no_modify; } /* * process a leaf block, also checks for .. entry * and corrects it to match what we think .. should be */ static void lf_block_dir_entry_check(xfs_mount_t *mp, xfs_ino_t ino, xfs_dir_leafblock_t *leaf, int *dirty, int *num_illegal, int *need_dot, ino_tree_node_t *current_irec, int current_ino_offset, dir_hash_tab_t *hashtab, xfs_dablk_t da_bno) { xfs_dir_leaf_entry_t *entry; ino_tree_node_t *irec; xfs_ino_t lino; xfs_ino_t parent; xfs_dir_leaf_name_t *namest; int i; int junkit; int ino_offset; int nbad; char fname[MAXNAMELEN + 1]; entry = &leaf->entries[0]; *dirty = 0; nbad = 0; /* * look at each entry. reference inode pointed to by each * entry in the incore inode tree. * if not a directory, set reached flag, increment link count * if a directory and reached, mark entry as to be deleted. * if a directory, check to see if recorded parent * matches current inode #, * if so, then set reached flag, increment link count * of current and child dir inodes, push the child * directory inode onto the directory stack. * if current inode != parent, then mark entry to be deleted. * * return */ for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { /* * snag inode #, update link counts, and make sure * this isn't a loop if the child is a directory */ namest = xfs_dir_leaf_namestruct(leaf, be16_to_cpu(entry->nameidx)); /* * skip bogus entries (leading '/'). they'll be deleted * later */ if (namest->name[0] == '/') { nbad++; continue; } junkit = 0; xfs_dir_sf_get_dirino(&namest->inumber, &lino); memmove(fname, namest->name, entry->namelen); fname[entry->namelen] = '\0'; ASSERT(lino != NULLFSINO); /* * skip the '..' entry since it's checked when the * directory is reached by something else. if it never * gets reached, it'll be moved to the orphanage and we'll * take care of it then. */ if (entry->namelen == 2 && namest->name[0] == '.' && namest->name[1] == '.') continue; ASSERT(no_modify || !verify_inum(mp, lino)); /* * special case the . entry. we know there's only one * '.' and only '.' points to itself because bogus entries * got trashed in phase 3 if there were > 1. * bump up link count for '.' but don't set reached * until we're actually reached by another directory * '..' is already accounted for or will be taken care * of when directory is moved to orphanage. */ if (ino == lino) { ASSERT(namest->name[0] == '.' && entry->namelen == 1); add_inode_ref(current_irec, current_ino_offset); *need_dot = 0; continue; } /* * skip entries with bogus inumbers if we're in no modify mode */ if (no_modify && verify_inum(mp, lino)) continue; /* * ok, now handle the rest of the cases besides '.' and '..' */ irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino)); if (irec == NULL) { nbad++; if (entry_junked( _("entry \"%s\" in dir inode %" PRIu64 " points to non-existent inode %" PRIu64), fname, ino, lino)) { namest->name[0] = '/'; *dirty = 1; } continue; } ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; /* * if it's a free inode, blow out the entry. * by now, any inode that we think is free * really is free. */ if (is_inode_free(irec, ino_offset)) { nbad++; if (entry_junked( _("entry \"%s\" in dir inode %" PRIu64 " points to free inode %" PRIu64), fname, ino, lino)) { namest->name[0] = '/'; *dirty = 1; } continue; } /* * check if this inode is lost+found dir in the root */ if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { /* root inode, "lost+found", if it's not a directory, * trash it, otherwise, assign it */ if (!inode_isadir(irec, ino_offset)) { nbad++; if (entry_junked( _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), ORPHANAGE, lino, ino)) { namest->name[0] = '/'; *dirty = 1; } continue; } /* * if this is a dup, it will be picked up below, * otherwise, mark it as the orphanage for later. */ if (!orphanage_ino) orphanage_ino = lino; } /* * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, (da_bno << mp->m_sb.sb_blocklog) + be16_to_cpu(entry->nameidx), lino, entry->namelen, namest->name)) { nbad++; if (entry_junked( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), fname, lino, ino)) { namest->name[0] = '/'; *dirty = 1; } if (lino == orphanage_ino) orphanage_ino = 0; continue; } /* * check easy case first, regular inode, just bump * the link count and continue */ if (!inode_isadir(irec, ino_offset)) { add_inode_reached(irec, ino_offset); continue; } parent = get_inode_parent(irec, ino_offset); ASSERT(parent != 0); /* * bump up the link counts in parent and child * directory but if the link doesn't agree with * the .. in the child, blow out the entry. * if the directory has already been reached, * blow away the entry also. */ if (is_inode_reached(irec, ino_offset)) { junkit = 1; do_warn( _("entry \"%s\" in dir ino %" PRIu64 " points to an already connected dir inode %" PRIu64 ",\n"), fname, ino, lino); } else if (parent == ino) { add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else if (parent == NULLFSINO) { /* ".." was missing, but this entry refers to it, so, set it as the parent and mark for rebuild */ do_warn( _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), fname, ino, lino); set_inode_parent(irec, ino_offset, ino); add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else { junkit = 1; do_warn( _("entry \"%s\" in dir ino %" PRIu64 " not consistent with .. value (%" PRIu64 ") in ino %" PRIu64 ",\n"), fname, ino, parent, lino); } if (junkit) { if (lino == orphanage_ino) orphanage_ino = 0; junkit = 0; nbad++; if (!no_modify) { namest->name[0] = '/'; *dirty = 1; if (verbose) do_warn( _("\twill clear entry \"%s\"\n"), fname); } else { do_warn(_("\twould clear entry \"%s\"\n"), fname); } } } *num_illegal += nbad; } /* * succeeds or dies, inode never gets dirtied since all changes * happen in file blocks. the inode size and other core info * is already correct, it's just the leaf entries that get altered. */ static void longform_dir_entry_check(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, int *num_illegal, int *need_dot, ino_tree_node_t *irec, int ino_offset, dir_hash_tab_t *hashtab) { xfs_dir_leafblock_t *leaf; xfs_buf_t *bp; xfs_dfsbno_t fsbno; xfs_fsblock_t fblock; xfs_dablk_t da_bno; int dirty; int nmap; int error; int skipit; xfs_bmbt_irec_t map; char *ftype; da_bno = 0; fblock = NULLFSBLOCK; *need_dot = 1; ftype = _("dir"); fsbno = map_first_dblock_fsbno(mp, ino, ip, &da_bno); if (fsbno == NULLDFSBNO && no_modify) { do_warn( _("cannot map block 0 of directory inode %" PRIu64 "\n"), ino); return; } do { ASSERT(fsbno != NULLDFSBNO); skipit = 0; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_error( _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), da_bno, fsbno, ino); /* NOTREACHED */ } leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { if (!no_modify) { do_error( _("bad magic # (0x%x) for dir ino %" PRIu64 " leaf block (bno %u fsbno %" PRIu64 ")\n"), be16_to_cpu(leaf->hdr.info.magic), ino, da_bno, fsbno); /* NOTREACHED */ } else { /* * this block's bad but maybe the * forward pointer is good... */ skipit = 1; dirty = 0; } } if (!skipit) lf_block_dir_entry_check(mp, ino, leaf, &dirty, num_illegal, need_dot, irec, ino_offset, hashtab, da_bno); da_bno = be32_to_cpu(leaf->hdr.info.forw); ASSERT(dirty == 0 || (dirty && !no_modify)); if (dirty && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); bp = NULL; if (da_bno != 0) { nmap = 1; error = libxfs_bmapi(NULL, ip, (xfs_fileoff_t)da_bno, 1, XFS_BMAPI_METADATA, &fblock, 0, &map, &nmap, NULL); if (error || nmap != 1) { if (!no_modify) do_error( _("can't map leaf block %d in dir %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ino, error, nmap); else { do_warn( _("can't map leaf block %d in dir %" PRIu64 ", xfs_bmapi returns %d, nmap = %d\n"), da_bno, ino, error, nmap); return; } } fsbno = map.br_startblock; if (fsbno == HOLESTARTBLOCK) { if (!no_modify) do_error( _("block %d in %s ino %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); else { do_warn( _("block %d in %s ino %" PRIu64 " doesn't exist\n"), da_bno, ftype, ino); return; } } } } while (da_bno != 0); } /* * Unexpected failure during the rebuild will leave the entries in * lost+found on the next run */ static void longform_dir2_rebuild( xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, ino_tree_node_t *irec, int ino_offset, dir_hash_tab_t *hashtab) { int error; int nres; xfs_trans_t *tp; xfs_fileoff_t lastblock; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; xfs_inode_t pip; dir_hash_ent_t *p; int committed; int done; /* * trash directory completely and rebuild from scratch using the * name/inode pairs in the hash table */ do_warn(_("rebuilding directory inode %" PRIu64 "\n"), ino); /* * first attempt to locate the parent inode, if it can't be * found, set it to the root inode and it'll be moved to the * orphanage later (the inode number here needs to be valid * for the libxfs_dir_init() call). */ pip.i_ino = get_inode_parent(irec, ino_offset); if (pip.i_ino == NULLFSINO) pip.i_ino = mp->m_sb.sb_rootino; xfs_bmap_init(&flist, &firstblock); tp = libxfs_trans_alloc(mp, 0); nres = XFS_REMOVE_SPACE_RES(mp); error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); if ((error = libxfs_bmap_last_offset(tp, ip, &lastblock, XFS_DATA_FORK))) do_error(_("xfs_bmap_last_offset failed -- error - %d\n"), error); /* free all data, leaf, node and freespace blocks */ error = libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0, &firstblock, &flist, &done); if (error) { do_warn(_("xfs_bunmapi failed -- error - %d\n"), error); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); return; } ASSERT(done); libxfs_dir_init(tp, ip, &pip); error = libxfs_bmap_finish(&tp, &flist, &committed); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); /* go through the hash list and re-add the inodes */ for (p = hashtab->first; p; p = p->nextbyorder) { if (p->name.name[0] == '/' || (p->name.name[0] == '.' && (p->name.len == 1 || (p->name.len == 2 && p->name.name[1] == '.')))) continue; tp = libxfs_trans_alloc(mp, 0); nres = XFS_CREATE_SPACE_RES(mp, p->name.len); error = libxfs_trans_reserve(tp, nres, XFS_CREATE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); if (error) { do_warn( _("space reservation failed (%d), filesystem may be out of space\n"), error); break; } libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); xfs_bmap_init(&flist, &firstblock); error = libxfs_dir_createname(tp, ip, &p->name, p->inum, &firstblock, &flist, nres); if (error) { do_warn( _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"), ino, error); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); break; } error = libxfs_bmap_finish(&tp, &flist, &committed); if (error) { do_warn( _("bmap finish failed (%d), filesystem may be out of space\n"), error); libxfs_bmap_cancel(&flist); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); break; } libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC); } } /* * Kill a block in a version 2 inode. * Makes its own transaction. */ static void dir2_kill_block( xfs_mount_t *mp, xfs_inode_t *ip, xfs_dablk_t da_bno, xfs_dabuf_t *bp) { xfs_da_args_t args; int committed; int error; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; int nres; xfs_trans_t *tp; tp = libxfs_trans_alloc(mp, 0); nres = XFS_REMOVE_SPACE_RES(mp); error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); libxfs_da_bjoin(tp, bp); memset(&args, 0, sizeof(args)); xfs_bmap_init(&flist, &firstblock); args.dp = ip; args.trans = tp; args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_DATA_FORK; if (da_bno >= mp->m_dirleafblk && da_bno < mp->m_dirfreeblk) error = libxfs_da_shrink_inode(&args, da_bno, bp); else error = libxfs_dir2_shrink_inode(&args, xfs_dir2_da_to_db(mp, da_bno), bp); if (error) do_error(_("shrink_inode failed inode %" PRIu64 " block %u\n"), ip->i_ino, da_bno); libxfs_bmap_finish(&tp, &flist, &committed); libxfs_trans_commit(tp, 0); } /* * process a data block, also checks for .. entry * and corrects it to match what we think .. should be */ static void longform_dir2_entry_check_data( xfs_mount_t *mp, xfs_inode_t *ip, int *num_illegal, int *need_dot, ino_tree_node_t *current_irec, int current_ino_offset, xfs_dabuf_t **bpp, dir_hash_tab_t *hashtab, freetab_t **freetabp, xfs_dablk_t da_bno, int isblock) { xfs_dir2_dataptr_t addr; xfs_dir2_leaf_entry_t *blp; xfs_dabuf_t *bp; xfs_dir2_block_tail_t *btp; int committed; xfs_dir2_data_t *d; xfs_dir2_db_t db; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *endptr; int error; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; char fname[MAXNAMELEN + 1]; freetab_t *freetab; int i; int ino_offset; xfs_ino_t inum; ino_tree_node_t *irec; int junkit; int lastfree; int len; int nbad; int needlog; int needscan; xfs_ino_t parent; char *ptr; xfs_trans_t *tp; int wantmagic; bp = *bpp; d = bp->data; ptr = (char *)d->u; nbad = 0; needscan = needlog = 0; junkit = 0; freetab = *freetabp; if (isblock) { btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); blp = xfs_dir2_block_leaf_p(btp); endptr = (char *)blp; if (endptr > (char *)btp) endptr = (char *)btp; wantmagic = XFS_DIR2_BLOCK_MAGIC; } else { endptr = (char *)d + mp->m_dirblksize; wantmagic = XFS_DIR2_DATA_MAGIC; } db = xfs_dir2_da_to_db(mp, da_bno); /* check for data block beyond expected end */ if (freetab->naents <= db) { struct freetab_ent e; *freetabp = freetab = realloc(freetab, FREETAB_SIZE(db + 1)); if (!freetab) { do_error( _("realloc failed in longform_dir2_entry_check_data (%zu bytes)\n"), FREETAB_SIZE(db + 1)); } e.v = NULLDATAOFF; e.s = 0; for (i = freetab->naents; i < db; i++) freetab->ents[i] = e; freetab->naents = db + 1; } /* check the data block */ while (ptr < endptr) { /* check for freespace */ dup = (xfs_dir2_data_unused_t *)ptr; if (XFS_DIR2_DATA_FREE_TAG == be16_to_cpu(dup->freetag)) { /* check for invalid freespace length */ if (ptr + be16_to_cpu(dup->length) > endptr || be16_to_cpu(dup->length) == 0 || (be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1))) break; /* check for invalid tag */ if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != (char *)dup - (char *)d) break; /* check for block with no data entries */ if ((ptr == (char *)d->u) && (ptr + be16_to_cpu(dup->length) >= endptr)) { junkit = 1; *num_illegal += 1; break; } /* continue at the end of the freespace */ ptr += be16_to_cpu(dup->length); if (ptr >= endptr) break; } /* validate data entry size */ dep = (xfs_dir2_data_entry_t *)ptr; if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) break; if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != (char *)dep - (char *)d) break; ptr += xfs_dir2_data_entsize(dep->namelen); } /* did we find an empty or corrupt block? */ if (ptr != endptr) { if (junkit) { do_warn( _("empty data block %u in directory inode %" PRIu64 ": "), da_bno, ip->i_ino); } else { do_warn(_ ("corrupt block %u in directory inode %" PRIu64 ": "), da_bno, ip->i_ino); } if (!no_modify) { do_warn(_("junking block\n")); dir2_kill_block(mp, ip, da_bno, bp); } else { do_warn(_("would junk block\n")); libxfs_da_brelse(NULL, bp); } freetab->ents[db].v = NULLDATAOFF; *bpp = NULL; return; } /* update number of data blocks processed */ if (freetab->nents < db + 1) freetab->nents = db + 1; tp = libxfs_trans_alloc(mp, 0); error = libxfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); libxfs_da_bjoin(tp, bp); libxfs_da_bhold(tp, bp); xfs_bmap_init(&flist, &firstblock); if (be32_to_cpu(d->hdr.magic) != wantmagic) { do_warn( _("bad directory block magic # %#x for directory inode %" PRIu64 " block %d: "), be32_to_cpu(d->hdr.magic), ip->i_ino, da_bno); if (!no_modify) { do_warn(_("fixing magic # to %#x\n"), wantmagic); d->hdr.magic = cpu_to_be32(wantmagic); needlog = 1; } else do_warn(_("would fix magic # to %#x\n"), wantmagic); } lastfree = 0; ptr = (char *)d->u; /* * look at each entry. reference inode pointed to by each * entry in the incore inode tree. * if not a directory, set reached flag, increment link count * if a directory and reached, mark entry as to be deleted. * if a directory, check to see if recorded parent * matches current inode #, * if so, then set reached flag, increment link count * of current and child dir inodes, push the child * directory inode onto the directory stack. * if current inode != parent, then mark entry to be deleted. */ while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (lastfree) { do_warn( _("directory inode %" PRIu64 " block %u has consecutive free entries: "), ip->i_ino, da_bno); if (!no_modify) { do_warn(_("joining together\n")); len = be16_to_cpu(dup->length); libxfs_dir2_data_use_free(tp, bp, dup, ptr - (char *)d, len, &needlog, &needscan); libxfs_dir2_data_make_free(tp, bp, ptr - (char *)d, len, &needlog, &needscan); } else do_warn(_("would join together\n")); } ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } addr = xfs_dir2_db_off_to_dataptr(mp, db, ptr - (char *)d); dep = (xfs_dir2_data_entry_t *)ptr; ptr += xfs_dir2_data_entsize(dep->namelen); inum = be64_to_cpu(dep->inumber); lastfree = 0; /* * skip bogus entries (leading '/'). they'll be deleted * later. must still log it, else we leak references to * buffers. */ if (dep->name[0] == '/') { nbad++; if (!no_modify) libxfs_dir2_data_log_entry(tp, bp, dep); continue; } memmove(fname, dep->name, dep->namelen); fname[dep->namelen] = '\0'; ASSERT(inum != NULLFSINO); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, inum), XFS_INO_TO_AGINO(mp, inum)); if (irec == NULL) { nbad++; if (entry_junked( _("entry \"%s\" in directory inode %" PRIu64 " points to non-existent inode %" PRIu64 ""), fname, ip->i_ino, inum)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } continue; } ino_offset = XFS_INO_TO_AGINO(mp, inum) - irec->ino_startnum; /* * if it's a free inode, blow out the entry. * by now, any inode that we think is free * really is free. */ if (is_inode_free(irec, ino_offset)) { nbad++; if (entry_junked( _("entry \"%s\" in directory inode %" PRIu64 " points to free inode %" PRIu64), fname, ip->i_ino, inum)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } continue; } /* * check if this inode is lost+found dir in the root */ if (inum == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { /* * if it's not a directory, trash it */ if (!inode_isadir(irec, ino_offset)) { nbad++; if (entry_junked( _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), ORPHANAGE, inum, ip->i_ino)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } continue; } /* * if this is a dup, it will be picked up below, * otherwise, mark it as the orphanage for later. */ if (!orphanage_ino) orphanage_ino = inum; } /* * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, addr, inum, dep->namelen, dep->name)) { nbad++; if (entry_junked( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), fname, inum, ip->i_ino)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } if (inum == orphanage_ino) orphanage_ino = 0; continue; } /* * if just scanning to rebuild a directory due to a ".." * update, just continue */ if (dotdot_update) continue; /* * skip the '..' entry since it's checked when the * directory is reached by something else. if it never * gets reached, it'll be moved to the orphanage and we'll * take care of it then. If it doesn't exist at all, the * directory needs to be rebuilt first before being added * to the orphanage. */ if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') { if (da_bno != 0) { /* ".." should be in the first block */ nbad++; if (entry_junked( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is not in the the first block"), fname, inum, ip->i_ino)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } } continue; } ASSERT(no_modify || !verify_inum(mp, inum)); /* * special case the . entry. we know there's only one * '.' and only '.' points to itself because bogus entries * got trashed in phase 3 if there were > 1. * bump up link count for '.' but don't set reached * until we're actually reached by another directory * '..' is already accounted for or will be taken care * of when directory is moved to orphanage. */ if (ip->i_ino == inum) { ASSERT(dep->name[0] == '.' && dep->namelen == 1); add_inode_ref(current_irec, current_ino_offset); if (da_bno != 0 || dep != (xfs_dir2_data_entry_t *)d->u) { /* "." should be the first entry */ nbad++; if (entry_junked( _("entry \"%s\" in dir %" PRIu64 " is not the first entry"), fname, inum, ip->i_ino)) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); } } *need_dot = 0; continue; } /* * skip entries with bogus inumbers if we're in no modify mode */ if (no_modify && verify_inum(mp, inum)) continue; /* * check easy case first, regular inode, just bump * the link count and continue */ if (!inode_isadir(irec, ino_offset)) { add_inode_reached(irec, ino_offset); continue; } parent = get_inode_parent(irec, ino_offset); ASSERT(parent != 0); junkit = 0; /* * bump up the link counts in parent and child * directory but if the link doesn't agree with * the .. in the child, blow out the entry. * if the directory has already been reached, * blow away the entry also. */ if (is_inode_reached(irec, ino_offset)) { junkit = 1; do_warn( _("entry \"%s\" in dir %" PRIu64" points to an already connected directory inode %" PRIu64 "\n"), fname, ip->i_ino, inum); } else if (parent == ip->i_ino) { add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else if (parent == NULLFSINO) { /* ".." was missing, but this entry refers to it, so, set it as the parent and mark for rebuild */ do_warn( _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), fname, ip->i_ino, inum); set_inode_parent(irec, ino_offset, ip->i_ino); add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); add_dotdot_update(XFS_INO_TO_AGNO(mp, inum), irec, ino_offset); } else { junkit = 1; do_warn( _("entry \"%s\" in dir inode %" PRIu64 " inconsistent with .. value (%" PRIu64 ") in ino %" PRIu64 "\n"), fname, ip->i_ino, parent, inum); } if (junkit) { if (inum == orphanage_ino) orphanage_ino = 0; junkit = 0; nbad++; if (!no_modify) { dep->name[0] = '/'; libxfs_dir2_data_log_entry(tp, bp, dep); if (verbose) do_warn( _("\twill clear entry \"%s\"\n"), fname); } else { do_warn(_("\twould clear entry \"%s\"\n"), fname); } } } *num_illegal += nbad; if (needscan) libxfs_dir2_data_freescan(mp, d, &needlog); if (needlog) libxfs_dir2_data_log_header(tp, bp); libxfs_bmap_finish(&tp, &flist, &committed); libxfs_trans_commit(tp, 0); freetab->ents[db].v = be16_to_cpu(d->hdr.bestfree[0].length); freetab->ents[db].s = 0; } /* * Check contents of leaf-form block. */ static int longform_dir2_check_leaf( xfs_mount_t *mp, xfs_inode_t *ip, dir_hash_tab_t *hashtab, freetab_t *freetab) { int badtail; __be16 *bestsp; xfs_dabuf_t *bp; xfs_dablk_t da_bno; int i; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; int seeval; da_bno = mp->m_dirleafblk; if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { do_error( _("can't read block %u for directory inode %" PRIu64 "\n"), da_bno, ip->i_ino); /* NOTREACHED */ } leaf = bp->data; ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC || be32_to_cpu(leaf->hdr.info.forw) || be32_to_cpu(leaf->hdr.info.back) || be16_to_cpu(leaf->hdr.count) < be16_to_cpu(leaf->hdr.stale) || be16_to_cpu(leaf->hdr.count) > xfs_dir2_max_leaf_ents(mp) || (char *)&leaf->ents[be16_to_cpu( leaf->hdr.count)] > (char *)bestsp) { do_warn( _("leaf block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } seeval = dir_hash_see_all(hashtab, leaf->ents, be16_to_cpu(leaf->hdr.count), be16_to_cpu(leaf->hdr.stale)); if (dir_hash_check(hashtab, ip, seeval)) { libxfs_da_brelse(NULL, bp); return 1; } badtail = freetab->nents != be32_to_cpu(ltp->bestcount); for (i = 0; !badtail && i < be32_to_cpu(ltp->bestcount); i++) { freetab->ents[i].s = 1; badtail = freetab->ents[i].v != be16_to_cpu(bestsp[i]); } if (badtail) { do_warn( _("leaf block %u for directory inode %" PRIu64 " bad tail\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } libxfs_da_brelse(NULL, bp); return 0; } /* * Check contents of the node blocks (leaves) * Looks for matching hash values for the data entries. */ static int longform_dir2_check_node( xfs_mount_t *mp, xfs_inode_t *ip, dir_hash_tab_t *hashtab, freetab_t *freetab) { xfs_dabuf_t *bp; xfs_dablk_t da_bno; xfs_dir2_db_t fdb; xfs_dir2_free_t *free; int i; xfs_dir2_leaf_t *leaf; xfs_fileoff_t next_da_bno; int seeval = 0; int used; for (da_bno = mp->m_dirleafblk, next_da_bno = 0; next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { do_warn( _("can't read leaf block %u for directory inode %" PRIu64 "\n"), da_bno, ip->i_ino); return 1; } leaf = bp->data; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { if (be16_to_cpu(leaf->hdr.info.magic) == XFS_DA_NODE_MAGIC) { libxfs_da_brelse(NULL, bp); continue; } do_warn( _("unknown magic number %#x for block %u in directory inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.info.magic), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } if (be16_to_cpu(leaf->hdr.count) > xfs_dir2_max_leaf_ents(mp) || be16_to_cpu(leaf->hdr.count) < be16_to_cpu(leaf->hdr.stale)) { do_warn( _("leaf block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } seeval = dir_hash_see_all(hashtab, leaf->ents, be16_to_cpu(leaf->hdr.count), be16_to_cpu(leaf->hdr.stale)); libxfs_da_brelse(NULL, bp); if (seeval != DIR_HASH_CK_OK) return 1; } if (dir_hash_check(hashtab, ip, seeval)) return 1; for (da_bno = mp->m_dirfreeblk, next_da_bno = 0; next_da_bno != NULLFILEOFF; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK)) { do_warn( _("can't read freespace block %u for directory inode %" PRIu64 "\n"), da_bno, ip->i_ino); return 1; } free = bp->data; fdb = xfs_dir2_da_to_db(mp, da_bno); if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC || be32_to_cpu(free->hdr.firstdb) != (fdb - XFS_DIR2_FREE_FIRSTDB(mp)) * XFS_DIR2_MAX_FREE_BESTS(mp) || be32_to_cpu(free->hdr.nvalid) < be32_to_cpu(free->hdr.nused)) { do_warn( _("free block %u for directory inode %" PRIu64 " bad header\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } for (i = used = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { if (i + be32_to_cpu(free->hdr.firstdb) >= freetab->nents || freetab->ents[i + be32_to_cpu( free->hdr.firstdb)].v != be16_to_cpu(free->bests[i])) { do_warn( _("free block %u entry %i for directory ino %" PRIu64 " bad\n"), da_bno, i, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } used += be16_to_cpu(free->bests[i]) != NULLDATAOFF; freetab->ents[i + be32_to_cpu(free->hdr.firstdb)].s = 1; } if (used != be32_to_cpu(free->hdr.nused)) { do_warn( _("free block %u for directory inode %" PRIu64 " bad nused\n"), da_bno, ip->i_ino); libxfs_da_brelse(NULL, bp); return 1; } libxfs_da_brelse(NULL, bp); } for (i = 0; i < freetab->nents; i++) { if ((freetab->ents[i].s == 0) && (freetab->ents[i].v != NULLDATAOFF)) { do_warn( _("missing freetab entry %u for directory inode %" PRIu64 "\n"), i, ip->i_ino); return 1; } } return 0; } /* * If a directory is corrupt, we need to read in as many entries as possible, * destroy the entry and create a new one with recovered name/inode pairs. * (ie. get libxfs to do all the grunt work) */ static void longform_dir2_entry_check(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, int *num_illegal, int *need_dot, ino_tree_node_t *irec, int ino_offset, dir_hash_tab_t *hashtab) { xfs_dir2_block_t *block; xfs_dabuf_t **bplist; xfs_dablk_t da_bno; freetab_t *freetab; int num_bps; int i; int isblock; int isleaf; xfs_fileoff_t next_da_bno; int seeval; int fixit; xfs_dir2_db_t db; *need_dot = 1; freetab = malloc(FREETAB_SIZE(ip->i_d.di_size / mp->m_dirblksize)); if (!freetab) { do_error( _("malloc failed in longform_dir2_entry_check (%" PRId64 " bytes)\n"), FREETAB_SIZE(ip->i_d.di_size / mp->m_dirblksize)); exit(1); } freetab->naents = ip->i_d.di_size / mp->m_dirblksize; freetab->nents = 0; for (i = 0; i < freetab->naents; i++) { freetab->ents[i].v = NULLDATAOFF; freetab->ents[i].s = 0; } num_bps = freetab->naents; bplist = calloc(num_bps, sizeof(xfs_dabuf_t*)); /* is this a block, leaf, or node directory? */ libxfs_dir2_isblock(NULL, ip, &isblock); libxfs_dir2_isleaf(NULL, ip, &isleaf); /* check directory "data" blocks (ie. name/inode pairs) */ for (da_bno = 0, next_da_bno = 0; next_da_bno != NULLFILEOFF && da_bno < mp->m_dirleafblk; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; db = xfs_dir2_da_to_db(mp, da_bno); if (db >= num_bps) { /* more data blocks than expected */ num_bps = db + 1; bplist = realloc(bplist, num_bps * sizeof(xfs_dabuf_t*)); if (!bplist) do_error( _("realloc failed in longform_dir2_entry_check (%zu bytes)\n"), num_bps * sizeof(xfs_dabuf_t*)); } if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bplist[db], XFS_DATA_FORK)) { do_warn( _("can't read data block %u for directory inode %" PRIu64 "\n"), da_bno, ino); *num_illegal += 1; continue; /* try and read all "data" blocks */ } longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot, irec, ino_offset, &bplist[db], hashtab, &freetab, da_bno, isblock); } fixit = (*num_illegal != 0) || dir2_is_badino(ino) || *need_dot; if (!dotdot_update) { /* check btree and freespace */ if (isblock) { xfs_dir2_block_tail_t *btp; xfs_dir2_leaf_entry_t *blp; block = bplist[0]->data; btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); seeval = dir_hash_see_all(hashtab, blp, be32_to_cpu(btp->count), be32_to_cpu(btp->stale)); if (dir_hash_check(hashtab, ip, seeval)) fixit |= 1; } else if (isleaf) { fixit |= longform_dir2_check_leaf(mp, ip, hashtab, freetab); } else { fixit |= longform_dir2_check_node(mp, ip, hashtab, freetab); } } if (!no_modify && (fixit || dotdot_update)) { dir_hash_dup_names(hashtab); for (i = 0; i < freetab->naents; i++) if (bplist[i]) libxfs_da_brelse(NULL, bplist[i]); longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); *num_illegal = 0; *need_dot = 0; } else { for (i = 0; i < freetab->naents; i++) if (bplist[i]) libxfs_da_brelse(NULL, bplist[i]); } free(bplist); free(freetab); } /* * shortform directory processing routines -- entry verification and * bad entry deletion (pruning). */ static void shortform_dir_entry_check(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, int *ino_dirty, ino_tree_node_t *current_irec, int current_ino_offset, dir_hash_tab_t *hashtab) { xfs_ino_t lino; xfs_ino_t parent; xfs_dir_shortform_t *sf; xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe; xfs_ifork_t *ifp; ino_tree_node_t *irec; int max_size; int ino_offset; int i; int junkit; int tmp_len; int tmp_elen; int bad_sfnamelen; int namelen; int bytes_deleted; char fname[MAXNAMELEN + 1]; ifp = &ip->i_df; sf = (xfs_dir_shortform_t *) ifp->if_u1.if_data; *ino_dirty = 0; bytes_deleted = 0; max_size = ifp->if_bytes; ASSERT(ip->i_d.di_size <= ifp->if_bytes); /* * no '.' entry in shortform dirs, just bump up ref count by 1 * '..' was already (or will be) accounted for and checked when * the directory is reached or will be taken care of when the * directory is moved to orphanage. */ add_inode_ref(current_irec, current_ino_offset); /* * now run through entries, stop at first bad entry, don't need * to skip over '..' since that's encoded in its own field and * no need to worry about '.' since it doesn't exist. */ sf_entry = next_sfe = &sf->list[0]; if (sf == NULL) { junkit = 1; do_warn( _("shortform dir inode %" PRIu64 " has null data entries \n"), ino); } else { for (i = 0; i < sf->hdr.count && max_size > (__psint_t)next_sfe - (__psint_t)sf; sf_entry = next_sfe, i++) { junkit = 0; bad_sfnamelen = 0; tmp_sfe = NULL; xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); namelen = sf_entry->namelen; ASSERT(no_modify || namelen > 0); if (no_modify && namelen == 0) { /* * if we're really lucky, this is * the last entry in which case we * can use the dir size to set the * namelen value. otherwise, forget * it because we're not going to be * able to find the next entry. */ bad_sfnamelen = 1; if (i == sf->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); } else { /* * don't process the rest of the directory, * break out of processing looop */ break; } } else if (no_modify && (__psint_t) sf_entry - (__psint_t) sf + + xfs_dir_sf_entsize_byentry(sf_entry) > ip->i_d.di_size) { bad_sfnamelen = 1; if (i == sf->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); } else { /* * don't process the rest of the directory, * break out of processing looop */ break; } } memmove(fname, sf_entry->name, sf_entry->namelen); fname[sf_entry->namelen] = '\0'; ASSERT(no_modify || lino != NULLFSINO); ASSERT(no_modify || !verify_inum(mp, lino)); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino)); if (irec == NULL) { do_warn( _("entry \"%s\" in shortform dir %" PRIu64 " references non-existent ino %" PRIu64 "\n"), fname, ino, lino); goto do_junkit; } ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; /* * if it's a free inode, blow out the entry. * by now, any inode that we think is free * really is free. */ if (!is_inode_free(irec, ino_offset)) { do_warn( _("entry \"%s\" in shortform dir inode %" PRIu64 " points to free inode %" PRIu64"\n"), fname, ino, lino); goto do_junkit; } /* * check if this inode is lost+found dir in the root */ if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { /* * if it's not a directory, trash it */ if (!inode_isadir(irec, ino_offset)) { do_warn( _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), ORPHANAGE, lino, ino); goto do_junkit; } /* * if this is a dup, it will be picked up below, * otherwise, mark it as the orphanage for later. */ if (!orphanage_ino) orphanage_ino = lino; } /* * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) (sf_entry - &sf->list[0]), lino, sf_entry->namelen, sf_entry->name)) { do_warn( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), fname, lino, ino); goto do_junkit; } if (!inode_isadir(irec, ino_offset)) { /* * check easy case first, regular inode, just bump * the link count and continue */ add_inode_reached(irec, ino_offset); next_sfe = (xfs_dir_sf_entry_t *)((__psint_t)sf_entry + xfs_dir_sf_entsize_byentry(sf_entry)); continue; } else { parent = get_inode_parent(irec, ino_offset); /* * bump up the link counts in parent and child. * directory but if the link doesn't agree with * the .. in the child, blow out the entry */ if (is_inode_reached(irec, ino_offset)) { junkit = 1; do_warn( _("entry \"%s\" in dir %" PRIu64 " references already connected dir ino %" PRIu64 ".\n"), fname, ino, lino); } else if (parent == ino) { add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else if (parent == NULLFSINO) { /* ".." was missing, but this entry refers to it, so, set it as the parent and mark for rebuild */ do_warn( _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), fname, ino, lino); set_inode_parent(irec, ino_offset, ino); add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else { junkit = 1; do_warn( _("entry \"%s\" in dir %" PRIu64 " not consistent with .. value (%" PRIu64 ") in dir ino %" PRIu64".\n"), fname, ino, parent, lino); } } if (junkit) { do_junkit: if (lino == orphanage_ino) orphanage_ino = 0; if (!no_modify) { tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); tmp_sfe = (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfe - (__psint_t) sf); max_size -= tmp_elen; bytes_deleted += tmp_elen; memmove(sf_entry, tmp_sfe, tmp_len); sf->hdr.count -= 1; memset((void *)((__psint_t)sf_entry + tmp_len), 0, tmp_elen); /* * set the tmp value to the current * pointer so we'll process the entry * we just moved up */ tmp_sfe = sf_entry; /* * WARNING: drop the index i by one * so it matches the decremented count for * accurate comparisons in the loop test */ i--; *ino_dirty = 1; if (verbose) do_warn(_("junking entry\n")); else do_warn("\n"); } else { do_warn(_("would junk entry\n")); } } /* * go onto next entry unless we've just junked an * entry in which the current entry pointer points * to an unprocessed entry. have to take into entries * with bad namelen into account in no modify mode since we * calculate size based on next_sfe. */ ASSERT(no_modify || bad_sfnamelen == 0); next_sfe = (tmp_sfe == NULL) ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + ((!bad_sfnamelen) ? xfs_dir_sf_entsize_byentry(sf_entry) : sizeof(xfs_dir_sf_entry_t) - 1 + namelen)) : tmp_sfe; } } /* * sync up sizes if required */ if (*ino_dirty) { ASSERT(bytes_deleted > 0); ASSERT(!no_modify); libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK); ip->i_d.di_size -= bytes_deleted; } if (ip->i_d.di_size != ip->i_df.if_bytes) { ASSERT(ip->i_df.if_bytes == (xfs_fsize_t) ((__psint_t) next_sfe - (__psint_t) sf)); ip->i_d.di_size = (xfs_fsize_t) ((__psint_t) next_sfe - (__psint_t) sf); do_warn( _("setting size to %" PRId64 " bytes to reflect junked entries\n"), ip->i_d.di_size); *ino_dirty = 1; } } /* * shortform directory v2 processing routines -- entry verification and * bad entry deletion (pruning). */ static void shortform_dir2_entry_check(xfs_mount_t *mp, xfs_ino_t ino, xfs_inode_t *ip, int *ino_dirty, ino_tree_node_t *current_irec, int current_ino_offset, dir_hash_tab_t *hashtab) { xfs_ino_t lino; xfs_ino_t parent; xfs_dir2_sf_t *sfp; xfs_dir2_sf_entry_t *sfep, *next_sfep, *tmp_sfep; xfs_ifork_t *ifp; ino_tree_node_t *irec; int max_size; int ino_offset; int i; int junkit; int tmp_len; int tmp_elen; int bad_sfnamelen; int namelen; int bytes_deleted; char fname[MAXNAMELEN + 1]; int i8; ifp = &ip->i_df; sfp = (xfs_dir2_sf_t *) ifp->if_u1.if_data; *ino_dirty = 0; bytes_deleted = 0; max_size = ifp->if_bytes; ASSERT(ip->i_d.di_size <= ifp->if_bytes); /* * if just rebuild a directory due to a "..", update and return */ if (dotdot_update) { parent = get_inode_parent(current_irec, current_ino_offset); if (no_modify) { do_warn( _("would set .. in sf dir inode %" PRIu64 " to %" PRIu64 "\n"), ino, parent); } else { do_warn( _("setting .. in sf dir inode %" PRIu64 " to %" PRIu64 "\n"), ino, parent); xfs_dir2_sf_put_inumber(sfp, &parent, &sfp->hdr.parent); *ino_dirty = 1; } return; } /* * no '.' entry in shortform dirs, just bump up ref count by 1 * '..' was already (or will be) accounted for and checked when * the directory is reached or will be taken care of when the * directory is moved to orphanage. */ add_inode_ref(current_irec, current_ino_offset); /* * Initialise i8 counter -- the parent inode number counts as well. */ i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) > XFS_DIR2_MAX_SHORT_INUM); /* * now run through entries, stop at first bad entry, don't need * to skip over '..' since that's encoded in its own field and * no need to worry about '.' since it doesn't exist. */ sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; i < sfp->hdr.count && max_size > (__psint_t)next_sfep - (__psint_t)sfp; sfep = next_sfep, i++) { junkit = 0; bad_sfnamelen = 0; tmp_sfep = NULL; lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); namelen = sfep->namelen; ASSERT(no_modify || namelen > 0); if (no_modify && namelen == 0) { /* * if we're really lucky, this is * the last entry in which case we * can use the dir size to set the * namelen value. otherwise, forget * it because we're not going to be * able to find the next entry. */ bad_sfnamelen = 1; if (i == sfp->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); } else { /* * don't process the rest of the directory, * break out of processing loop */ break; } } else if (no_modify && (__psint_t) sfep - (__psint_t) sfp + + xfs_dir2_sf_entsize_byentry(sfp, sfep) > ip->i_d.di_size) { bad_sfnamelen = 1; if (i == sfp->hdr.count - 1) { namelen = ip->i_d.di_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); } else { /* * don't process the rest of the directory, * break out of processing loop */ break; } } memmove(fname, sfep->name, sfep->namelen); fname[sfep->namelen] = '\0'; ASSERT(no_modify || (lino != NULLFSINO && lino != 0)); ASSERT(no_modify || !verify_inum(mp, lino)); /* * Also skip entries with bogus inode numbers if we're * in no modify mode. */ if (no_modify && verify_inum(mp, lino)) { next_sfep = (xfs_dir2_sf_entry_t *)((__psint_t)sfep + xfs_dir2_sf_entsize_byentry(sfp, sfep)); continue; } irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino)); if (irec == NULL) { do_warn( _("entry \"%s\" in shortform directory %" PRIu64 " references non-existent inode %" PRIu64 "\n"), fname, ino, lino); goto do_junkit; } ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum; /* * if it's a free inode, blow out the entry. * by now, any inode that we think is free * really is free. */ if (is_inode_free(irec, ino_offset)) { do_warn( _("entry \"%s\" in shortform directory inode %" PRIu64 " points to free inode %" PRIu64 "\n"), fname, ino, lino); goto do_junkit; } /* * check if this inode is lost+found dir in the root */ if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) { /* * if it's not a directory, trash it */ if (!inode_isadir(irec, ino_offset)) { do_warn( _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"), ORPHANAGE, lino, ino); goto do_junkit; } /* * if this is a dup, it will be picked up below, * otherwise, mark it as the orphanage for later. */ if (!orphanage_ino) orphanage_ino = lino; } /* * check for duplicate names in directory. */ if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) (sfep - xfs_dir2_sf_firstentry(sfp)), lino, sfep->namelen, sfep->name)) { do_warn( _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"), fname, lino, ino); goto do_junkit; } if (!inode_isadir(irec, ino_offset)) { /* * check easy case first, regular inode, just bump * the link count */ add_inode_reached(irec, ino_offset); } else { parent = get_inode_parent(irec, ino_offset); /* * bump up the link counts in parent and child. * directory but if the link doesn't agree with * the .. in the child, blow out the entry */ if (is_inode_reached(irec, ino_offset)) { junkit = 1; do_warn( _("entry \"%s\" in directory inode %" PRIu64 " references already connected inode %" PRIu64 ".\n"), fname, ino, lino); } else if (parent == ino) { add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); } else if (parent == NULLFSINO) { /* ".." was missing, but this entry refers to it, so, set it as the parent and mark for rebuild */ do_warn( _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"), fname, ino, lino); set_inode_parent(irec, ino_offset, ino); add_inode_reached(irec, ino_offset); add_inode_ref(current_irec, current_ino_offset); add_dotdot_update(XFS_INO_TO_AGNO(mp, lino), irec, ino_offset); } else { junkit = 1; do_warn( _("entry \"%s\" in directory inode %" PRIu64 " not consistent with .. value (%" PRIu64 ") in inode %" PRIu64 ",\n"), fname, ino, parent, lino); } } if (junkit) { do_junkit: if (lino == orphanage_ino) orphanage_ino = 0; if (!no_modify) { tmp_elen = xfs_dir2_sf_entsize_byentry(sfp, sfep); tmp_sfep = (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfep - (__psint_t) sfp); max_size -= tmp_elen; bytes_deleted += tmp_elen; memmove(sfep, tmp_sfep, tmp_len); sfp->hdr.count -= 1; memset((void *)((__psint_t)sfep + tmp_len), 0, tmp_elen); /* * set the tmp value to the current * pointer so we'll process the entry * we just moved up */ tmp_sfep = sfep; /* * WARNING: drop the index i by one * so it matches the decremented count for * accurate comparisons in the loop test */ i--; *ino_dirty = 1; if (verbose) do_warn(_("junking entry\n")); else do_warn("\n"); } else { do_warn(_("would junk entry\n")); } } else if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; /* * go onto next entry unless we've just junked an * entry in which the current entry pointer points * to an unprocessed entry. have to take into entries * with bad namelen into account in no modify mode since we * calculate size based on next_sfep. */ ASSERT(no_modify || bad_sfnamelen == 0); next_sfep = (tmp_sfep == NULL) ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + ((!bad_sfnamelen) ? xfs_dir2_sf_entsize_byentry(sfp, sfep) : xfs_dir2_sf_entsize_byname(sfp, namelen))) : tmp_sfep; } if (sfp->hdr.i8count != i8) { if (no_modify) { do_warn(_("would fix i8count in inode %" PRIu64 "\n"), ino); } else { if (i8 == 0) { tmp_sfep = next_sfep; process_sf_dir2_fixi8(sfp, &tmp_sfep); bytes_deleted += (__psint_t)next_sfep - (__psint_t)tmp_sfep; next_sfep = tmp_sfep; } else sfp->hdr.i8count = i8; *ino_dirty = 1; do_warn(_("fixing i8count in inode %" PRIu64 "\n"), ino); } } /* * sync up sizes if required */ if (*ino_dirty) { ASSERT(bytes_deleted > 0); ASSERT(!no_modify); libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK); ip->i_d.di_size -= bytes_deleted; } if (ip->i_d.di_size != ip->i_df.if_bytes) { ASSERT(ip->i_df.if_bytes == (xfs_fsize_t) ((__psint_t) next_sfep - (__psint_t) sfp)); ip->i_d.di_size = (xfs_fsize_t) ((__psint_t) next_sfep - (__psint_t) sfp); do_warn( _("setting size to %" PRId64 " bytes to reflect junked entries\n"), ip->i_d.di_size); *ino_dirty = 1; } } /* * processes all reachable inodes in directories */ static void process_dir_inode( xfs_mount_t *mp, xfs_agnumber_t agno, ino_tree_node_t *irec, int ino_offset) { xfs_ino_t ino; xfs_bmap_free_t flist; xfs_fsblock_t first; xfs_inode_t *ip; xfs_trans_t *tp; dir_hash_tab_t *hashtab; int need_dot, committed; int dirty, num_illegal, error, nres; ino = XFS_AGINO_TO_INO(mp, agno, irec->ino_startnum + ino_offset); /* * open up directory inode, check all entries, * then call prune_dir_entries to remove all * remaining illegal directory entries. */ ASSERT(!is_inode_refchecked(irec, ino_offset) || dotdot_update); error = libxfs_iget(mp, NULL, ino, 0, &ip, 0); if (error) { if (!no_modify) do_error( _("couldn't map inode %" PRIu64 ", err = %d\n"), ino, error); else { do_warn( _("couldn't map inode %" PRIu64 ", err = %d\n"), ino, error); /* * see below for what we're doing if this * is root. Why do we need to do this here? * to ensure that the root doesn't show up * as being disconnected in the no_modify case. */ if (mp->m_sb.sb_rootino == ino) { add_inode_reached(irec, 0); add_inode_ref(irec, 0); } } add_inode_refchecked(irec, 0); return; } need_dot = dirty = num_illegal = 0; if (mp->m_sb.sb_rootino == ino) { /* * mark root inode reached and bump up * link count for root inode to account * for '..' entry since the root inode is * never reached by a parent. we know * that root's '..' is always good -- * guaranteed by phase 3 and/or below. */ add_inode_reached(irec, ino_offset); } add_inode_refchecked(irec, ino_offset); hashtab = dir_hash_init(ip->i_d.di_size); /* * look for bogus entries */ switch (ip->i_d.di_format) { case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: /* * also check for missing '.' in longform dirs. * missing .. entries are added if required when * the directory is connected to lost+found. but * we need to create '.' entries here. */ if (xfs_sb_version_hasdirv2(&mp->m_sb)) longform_dir2_entry_check(mp, ino, ip, &num_illegal, &need_dot, irec, ino_offset, hashtab); else longform_dir_entry_check(mp, ino, ip, &num_illegal, &need_dot, irec, ino_offset, hashtab); break; case XFS_DINODE_FMT_LOCAL: tp = libxfs_trans_alloc(mp, 0); /* * using the remove reservation is overkill * since at most we'll only need to log the * inode but it's easier than wedging a * new define in ourselves. */ nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp); error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); if (xfs_sb_version_hasdirv2(&mp->m_sb)) shortform_dir2_entry_check(mp, ino, ip, &dirty, irec, ino_offset, hashtab); else shortform_dir_entry_check(mp, ino, ip, &dirty, irec, ino_offset, hashtab); ASSERT(dirty == 0 || (dirty && !no_modify)); if (dirty) { libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE | XFS_ILOG_DDATA); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_SYNC); } else { libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); } break; default: break; } dir_hash_done(hashtab); /* * We don't support repairing of v1 dir anymore, report errors and exit */ if (!xfs_sb_version_hasdirv2(&mp->m_sb)) { if (need_root_dotdot && ino == mp->m_sb.sb_rootino) do_warn(_("missing root directory .. entry, cannot " "fix in V1 dir filesystem\n")); if (num_illegal > 0) { ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL); do_warn( _("%d bad entries found in dir inode %" PRIu64 ", cannot fix in V1 dir filesystem\n"), num_illegal, ino); } if (need_dot) { add_inode_ref(irec, ino_offset); do_warn( _("missing \".\" entry in dir ino %" PRIu64 ", cannot in fix V1 dir filesystem\n"), ino); } goto out; } /* * if we have to create a .. for /, do it now *before* * we delete the bogus entries, otherwise the directory * could transform into a shortform dir which would * probably cause the simulation to choke. Even * if the illegal entries get shifted around, it's ok * because the entries are structurally intact and in * in hash-value order so the simulation won't get confused * if it has to move them around. */ if (!no_modify && need_root_dotdot && ino == mp->m_sb.sb_rootino) { ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL); do_warn(_("recreating root directory .. entry\n")); tp = libxfs_trans_alloc(mp, 0); ASSERT(tp != NULL); nres = XFS_MKDIR_SPACE_RES(mp, 2); error = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); xfs_bmap_init(&flist, &first); error = libxfs_dir_createname(tp, ip, &xfs_name_dotdot, ip->i_ino, &first, &flist, nres); if (error) do_error( _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = libxfs_bmap_finish(&tp, &flist, &committed); ASSERT(error == 0); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_SYNC); need_root_dotdot = 0; } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino) { do_warn(_("would recreate root directory .. entry\n")); } /* * if we need to create the '.' entry, do so only if * the directory is a longform dir. if it's been * turned into a shortform dir, then the inode is ok * since shortform dirs have no '.' entry and the inode * has already been committed by prune_lf_dir_entry(). */ if (need_dot) { /* * bump up our link count but don't * bump up the inode link count. chances * are good that even though we lost '.' * the inode link counts reflect '.' so * leave the inode link count alone and if * it turns out to be wrong, we'll catch * that in phase 7. */ add_inode_ref(irec, ino_offset); if (no_modify) { do_warn( _("would create missing \".\" entry in dir ino %" PRIu64 "\n"), ino); } else if (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) { /* * need to create . entry in longform dir. */ do_warn( _("creating missing \".\" entry in dir ino %" PRIu64 "\n"), ino); tp = libxfs_trans_alloc(mp, 0); ASSERT(tp != NULL); nres = XFS_MKDIR_SPACE_RES(mp, 1); error = libxfs_trans_reserve(tp, nres, XFS_MKDIR_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); if (error) res_failed(error); libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_ihold(tp, ip); xfs_bmap_init(&flist, &first); error = libxfs_dir_createname(tp, ip, &xfs_name_dot, ip->i_ino, &first, &flist, nres); if (error) do_error( _("can't make \".\" entry in dir ino %" PRIu64 ", createname error %d\n"), ino, error); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = libxfs_bmap_finish(&tp, &flist, &committed); ASSERT(error == 0); libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES |XFS_TRANS_SYNC); } } out: libxfs_iput(ip, 0); } /* * mark realtime bitmap and summary inodes as reached. * quota inode will be marked here as well */ static void mark_standalone_inodes(xfs_mount_t *mp) { ino_tree_node_t *irec; int offset; irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rbmino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino)); ASSERT(irec != NULL); offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino) - irec->ino_startnum; add_inode_reached(irec, offset); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rsumino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino)); offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino) - irec->ino_startnum; ASSERT(irec != NULL); add_inode_reached(irec, offset); if (fs_quotas) { if (mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) { irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_uquotino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino)); offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino) - irec->ino_startnum; add_inode_reached(irec, offset); } if (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO) { irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_gquotino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino)); offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino) - irec->ino_startnum; add_inode_reached(irec, offset); } } } static void check_for_orphaned_inodes( xfs_mount_t *mp, xfs_agnumber_t agno, ino_tree_node_t *irec) { int i; xfs_ino_t ino; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { ASSERT(is_inode_confirmed(irec, i)); if (is_inode_free(irec, i)) continue; if (is_inode_reached(irec, i)) continue; ASSERT(inode_isadir(irec, i) || num_inode_references(irec, i) == 0); ino = XFS_AGINO_TO_INO(mp, agno, i + irec->ino_startnum); if (inode_isadir(irec, i)) do_warn(_("disconnected dir inode %" PRIu64 ", "), ino); else do_warn(_("disconnected inode %" PRIu64 ", "), ino); if (!xfs_sb_version_hasdirv2(&mp->m_sb)) do_warn(_("cannot fix in V1 dir filesystem\n")); else if (!no_modify) { if (!orphanage_ino) orphanage_ino = mk_orphanage(mp); do_warn(_("moving to %s\n"), ORPHANAGE); mv_orphanage(mp, ino, inode_isadir(irec, i)); } else { do_warn(_("would move to %s\n"), ORPHANAGE); } /* * for read-only case, even though the inode isn't * really reachable, set the flag (and bump our link * count) anyway to fool phase 7 */ add_inode_reached(irec, i); } } static void traverse_function( work_queue_t *wq, xfs_agnumber_t agno, void *arg) { ino_tree_node_t *irec; int i; prefetch_args_t *pf_args = arg; wait_for_inode_prefetch(pf_args); if (verbose) do_log(_(" - agno = %d\n"), agno); for (irec = findfirst_inode_rec(agno); irec; irec = next_ino_rec(irec)) { if (irec->ino_isa_dir == 0) continue; if (pf_args) sem_post(&pf_args->ra_count); for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (inode_isadir(irec, i)) process_dir_inode(wq->mp, agno, irec, i); } } cleanup_inode_prefetch(pf_args); } static void update_missing_dotdot_entries( xfs_mount_t *mp) { dotdot_update_t *dir; /* * these entries parents were updated, rebuild them again * set dotdot_update flag so processing routines do not count links */ dotdot_update = 1; while (dotdot_update_list) { dir = dotdot_update_list; dotdot_update_list = dir->next; process_dir_inode(mp, dir->agno, dir->irec, dir->ino_offset); free(dir); } } static void traverse_ags( xfs_mount_t *mp) { int i; work_queue_t queue; prefetch_args_t *pf_args[2]; /* * we always do prefetch for phase 6 as it will fill in the gaps * not read during phase 3 prefetch. */ queue.mp = mp; pf_args[0] = start_inode_prefetch(0, 1, NULL); for (i = 0; i < glob_agcount; i++) { pf_args[(~i) & 1] = start_inode_prefetch(i + 1, 1, pf_args[i & 1]); traverse_function(&queue, i, pf_args[i & 1]); } } void phase6(xfs_mount_t *mp) { ino_tree_node_t *irec; int i; memset(&zerocr, 0, sizeof(struct cred)); memset(&zerofsx, 0, sizeof(struct fsxattr)); orphanage_ino = 0; do_log(_("Phase 6 - check inode connectivity...\n")); incore_ext_teardown(mp); add_ino_ex_data(mp); /* * verify existence of root directory - if we have to * make one, it's ok for the incore data structs not to * know about it since everything about it (and the other * inodes in its chunk if a new chunk was created) are ok */ if (need_root_inode) { if (!xfs_sb_version_hasdirv2(&mp->m_sb)) do_warn(_("need to reinitialize root directory, " "but not supported on V1 dir filesystem\n")); else if (!no_modify) { do_warn(_("reinitializing root directory\n")); mk_root_dir(mp); need_root_inode = 0; need_root_dotdot = 0; } else { do_warn(_("would reinitialize root directory\n")); } } if (need_rbmino) { if (!no_modify) { do_warn(_("reinitializing realtime bitmap inode\n")); mk_rbmino(mp); need_rbmino = 0; } else { do_warn(_("would reinitialize realtime bitmap inode\n")); } } if (need_rsumino) { if (!no_modify) { do_warn(_("reinitializing realtime summary inode\n")); mk_rsumino(mp); need_rsumino = 0; } else { do_warn(_("would reinitialize realtime summary inode\n")); } } if (!no_modify) { do_log( _(" - resetting contents of realtime bitmap and summary inodes\n")); if (fill_rbmino(mp)) { do_warn( _("Warning: realtime bitmap may be inconsistent\n")); } if (fill_rsumino(mp)) { do_warn( _("Warning: realtime bitmap may be inconsistent\n")); } } mark_standalone_inodes(mp); do_log(_(" - traversing filesystem ...\n")); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); /* * we always have a root inode, even if it's free... * if the root is free, forget it, lost+found is already gone */ if (is_inode_free(irec, 0) || !inode_isadir(irec, 0)) { need_root_inode = 1; } /* * then process all inodes by walking incore inode tree */ traverse_ags(mp); /* * any directories that had updated ".." entries, rebuild them now */ update_missing_dotdot_entries(mp); do_log(_(" - traversal finished ...\n")); do_log(_(" - moving disconnected inodes to %s ...\n"), ORPHANAGE); /* * move all disconnected inodes to the orphanage */ for (i = 0; i < glob_agcount; i++) { irec = findfirst_inode_rec(i); while (irec != NULL) { check_for_orphaned_inodes(mp, i, irec); irec = next_ino_rec(irec); } } } xfsprogs-3.1.9ubuntu2/repair/rt.h0000664000000000000000000000206011140033220013654 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct blkmap; void rtinit(xfs_mount_t *mp); int generate_rtinfo(xfs_mount_t *mp, xfs_rtword_t *words, xfs_suminfo_t *sumcompute); #if 0 int check_summary(xfs_mount_t *mp); void process_rtbitmap(xfs_mount_t *mp, xfs_dinode_t *dino, struct blkmap *blkmap); void process_rtsummary(xfs_mount_t *mp, struct blkmap *blkmap); #endif xfsprogs-3.1.9ubuntu2/repair/phase7.c0000664000000000000000000000722412062210562014432 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "versions.h" #include "progress.h" /* dinoc is a pointer to the IN-CORE dinode core */ static void set_nlinks( xfs_icdinode_t *dinoc, xfs_ino_t ino, __uint32_t nrefs, int *dirty) { if (dinoc->di_nlink == nrefs) return; if (!no_modify) { *dirty = 1; do_warn(_("resetting inode %" PRIu64 " nlinks from %u to %u\n"), ino, dinoc->di_nlink, nrefs); if (dinoc->di_version == 1 && nrefs > XFS_MAXLINK_1) { ASSERT(fs_inode_nlink); do_warn( _("nlinks %u will overflow v1 ino, ino %" PRIu64 " will be converted to version 2\n"), nrefs, ino); } dinoc->di_nlink = nrefs; } else { do_warn( _("would have reset inode %" PRIu64 " nlinks from %u to %u\n"), ino, dinoc->di_nlink, nrefs); } } static void update_inode_nlinks( xfs_mount_t *mp, xfs_ino_t ino, __uint32_t nlinks) { xfs_trans_t *tp; xfs_inode_t *ip; int error; int dirty; tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE); error = libxfs_trans_reserve(tp, (no_modify ? 0 : 10), XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_REMOVE_LOG_COUNT); ASSERT(error == 0); error = libxfs_trans_iget(mp, tp, ino, 0, 0, &ip); if (error) { if (!no_modify) do_error( _("couldn't map inode %" PRIu64 ", err = %d\n"), ino, error); else { do_warn( _("couldn't map inode %" PRIu64 ", err = %d, can't compare link counts\n"), ino, error); return; } } dirty = 0; /* * compare and set links for all inodes */ set_nlinks(&ip->i_d, ino, nlinks, &dirty); if (!dirty) { libxfs_trans_iput(tp, ip, 0); libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); } else { libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); /* * no need to do a bmap finish since * we're not allocating anything */ ASSERT(error == 0); error = libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_SYNC); ASSERT(error == 0); } } void phase7(xfs_mount_t *mp) { ino_tree_node_t *irec; int i; int j; __uint32_t nrefs; if (!no_modify) do_log(_("Phase 7 - verify and correct link counts...\n")); else do_log(_("Phase 7 - verify link counts...\n")); /* * for each ag, look at each inode 1 at a time. If the number of * links is bad, reset it, log the inode core, commit the transaction */ for (i = 0; i < glob_agcount; i++) { irec = findfirst_inode_rec(i); while (irec != NULL) { for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { ASSERT(is_inode_confirmed(irec, j)); if (is_inode_free(irec, j)) continue; ASSERT(no_modify || is_inode_reached(irec, j)); nrefs = num_inode_references(irec, j); ASSERT(no_modify || nrefs > 0); if (get_inode_disk_nlinks(irec, j) != nrefs) update_inode_nlinks(mp, XFS_AGINO_TO_INO(mp, i, irec->ino_startnum + j), nrefs); } irec = next_ino_rec(irec); } } } xfsprogs-3.1.9ubuntu2/repair/incore.h0000664000000000000000000003657012062210562014535 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef XFS_REPAIR_INCORE_H #define XFS_REPAIR_INCORE_H #include "avl.h" /* * contains definition information. implementation (code) * is spread out in separate files. */ /* * block map -- track state of each filesystem block. */ void init_bmaps(xfs_mount_t *mp); void reset_bmaps(xfs_mount_t *mp); void free_bmaps(xfs_mount_t *mp); void set_bmap_ext(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t blen, int state); int get_bmap_ext(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_agblock_t maxbno, xfs_extlen_t *blen); void set_rtbmap(xfs_drtbno_t bno, int state); int get_rtbmap(xfs_drtbno_t bno); static inline void set_bmap(xfs_agnumber_t agno, xfs_agblock_t agbno, int state) { set_bmap_ext(agno, agbno, 1, state); } static inline int get_bmap(xfs_agnumber_t agno, xfs_agblock_t agbno) { return get_bmap_ext(agno, agbno, agbno + 1, NULL); } /* * extent tree definitions * right now, there are 3 trees per AG, a bno tree, a bcnt tree * and a tree for dup extents. If the code is modified in the * future to use an extent tree instead of a bitmask for tracking * fs blocks, then we could lose the dup extent tree if we labelled * each extent with the inode that owned it. */ typedef unsigned char extent_state_t; typedef struct extent_tree_node { avlnode_t avl_node; xfs_agblock_t ex_startblock; /* starting block (agbno) */ xfs_extlen_t ex_blockcount; /* number of blocks in extent */ extent_state_t ex_state; /* see state flags below */ struct extent_tree_node *next; /* for bcnt extent lists */ struct extent_tree_node *last; /* for bcnt extent list anchors */ #if 0 xfs_ino_t ex_inode; /* owner, NULL if free or */ /* multiply allocated */ #endif } extent_tree_node_t; typedef struct rt_extent_tree_node { avlnode_t avl_node; xfs_drtbno_t rt_startblock; /* starting realtime block */ xfs_extlen_t rt_blockcount; /* number of blocks in extent */ extent_state_t rt_state; /* see state flags below */ #if 0 xfs_ino_t ex_inode; /* owner, NULL if free or */ /* multiply allocated */ #endif } rt_extent_tree_node_t; /* extent states, prefix with XR_ to avoid conflict with buffer cache defines */ #define XR_E_UNKNOWN 0 /* unknown state */ #define XR_E_FREE1 1 /* free block (marked by one fs space tree) */ #define XR_E_FREE 2 /* free block (marked by both fs space trees) */ #define XR_E_INUSE 3 /* extent used by file/dir data or metadata */ #define XR_E_INUSE_FS 4 /* extent used by fs ag header or log */ #define XR_E_MULT 5 /* extent is multiply referenced */ #define XR_E_INO 6 /* extent used by inodes (inode blocks) */ #define XR_E_FS_MAP 7 /* extent used by fs space/inode maps */ #define XR_E_BAD_STATE 8 /* extent states, in 64 bit word chunks */ #define XR_E_UNKNOWN_LL 0x0000000000000000LL #define XR_E_FREE1_LL 0x1111111111111111LL #define XR_E_FREE_LL 0x2222222222222222LL #define XR_E_INUSE_LL 0x3333333333333333LL #define XR_E_INUSE_FS_LL 0x4444444444444444LL #define XR_E_MULT_LL 0x5555555555555555LL #define XR_E_INO_LL 0x6666666666666666LL #define XR_E_FS_MAP_LL 0x7777777777777777LL /* separate state bit, OR'ed into high (4th) bit of ex_state field */ #define XR_E_WRITTEN 0x8 /* extent has been written out, can't reclaim */ #define good_state(state) (((state) & (~XR_E_WRITTEN)) >= XR_E_UNKNOWN && \ ((state) & (~XR_E_WRITTEN) < XF_E_BAD_STATE)) #define written(state) ((state) & XR_E_WRITTEN) #define set_written(state) (state) &= XR_E_WRITTEN /* * bno extent tree functions */ void add_bno_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount); extent_tree_node_t * findfirst_bno_extent(xfs_agnumber_t agno); extent_tree_node_t * find_bno_extent(xfs_agnumber_t agno, xfs_agblock_t agbno); extent_tree_node_t * findfirst_bno_extent(xfs_agnumber_t agno); #define findnext_bno_extent(exent_ptr) \ ((extent_tree_node_t *) ((exent_ptr)->avl_node.avl_nextino)) void get_bno_extent(xfs_agnumber_t agno, extent_tree_node_t *ext); /* * bcnt tree functions */ void add_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount); extent_tree_node_t * findfirst_bcnt_extent(xfs_agnumber_t agno); extent_tree_node_t * find_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t agbno); extent_tree_node_t * findbiggest_bcnt_extent(xfs_agnumber_t agno); extent_tree_node_t * findnext_bcnt_extent(xfs_agnumber_t agno, extent_tree_node_t *ext); extent_tree_node_t * get_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount); /* * duplicate extent tree functions */ int add_dup_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount); int search_dup_extent(xfs_agnumber_t agno, xfs_agblock_t start_agbno, xfs_agblock_t end_agbno); void add_rt_dup_extent(xfs_drtbno_t startblock, xfs_extlen_t blockcount); int search_rt_dup_extent(xfs_mount_t *mp, xfs_drtbno_t bno); /* * extent/tree recyling and deletion routines */ /* * return an extent node to the extent node free list */ void release_extent_tree_node(extent_tree_node_t *node); /* * recycle all the nodes in the per-AG tree */ void release_dup_extent_tree(xfs_agnumber_t agno); void release_agbno_extent_tree(xfs_agnumber_t agno); void release_agbcnt_extent_tree(xfs_agnumber_t agno); /* * realtime duplicate extent tree - this one actually frees the memory */ void free_rt_dup_extent_tree(xfs_mount_t *mp); void incore_ext_init(xfs_mount_t *); /* * per-AG extent trees shutdown routine -- all (bno, bcnt and dup) * at once. this one actually frees the memory instead of just recyling * the nodes. */ void incore_ext_teardown(xfs_mount_t *mp); void incore_ino_init(xfs_mount_t *); int count_bno_extents(xfs_agnumber_t); int count_bno_extents_blocks(xfs_agnumber_t, uint *); int count_bcnt_extents(xfs_agnumber_t); /* * inode definitions */ /* inode types */ #define XR_INO_UNKNOWN 0 /* unknown */ #define XR_INO_DIR 1 /* directory */ #define XR_INO_RTDATA 2 /* realtime file */ #define XR_INO_RTBITMAP 3 /* realtime bitmap inode */ #define XR_INO_RTSUM 4 /* realtime summary inode */ #define XR_INO_DATA 5 /* regular file */ #define XR_INO_SYMLINK 6 /* symlink */ #define XR_INO_CHRDEV 7 /* character device */ #define XR_INO_BLKDEV 8 /* block device */ #define XR_INO_SOCK 9 /* socket */ #define XR_INO_FIFO 10 /* fifo */ #define XR_INO_MOUNTPOINT 11 /* mountpoint */ /* inode allocation tree */ /* * Inodes in the inode allocation trees are allocated in chunks. * Those groups can be easily duplicated in our trees. * Disconnected inodes are harder. We can do one of two * things in that case: if we know the inode allocation btrees * are good, then we can disallow directory references to unknown * inode chunks. If the inode allocation trees have been trashed or * we feel like being aggressive, then as we hit unknown inodes, * we can search on the disk for all contiguous inodes and see if * they fit into chunks. Before putting them into the inode tree, * we can scan each inode starting at the earliest inode to see which * ones are good. This protects us from the pathalogical case of * inodes appearing in user-data. We still may have to mark the * inodes as "possibly fake" so that if a file claims the blocks, * we decide to believe the inodes, especially if they're not * connected. */ #define PLIST_CHUNK_SIZE 4 typedef xfs_ino_t parent_entry_t; struct nlink_ops; typedef struct parent_list { __uint64_t pmask; parent_entry_t *pentries; #ifdef DEBUG short cnt; #endif } parent_list_t; union ino_nlink { __uint8_t *un8; __uint16_t *un16; __uint32_t *un32; }; typedef struct ino_ex_data { __uint64_t ino_reached; /* bit == 1 if reached */ __uint64_t ino_processed; /* reference checked bit mask */ parent_list_t *parents; union ino_nlink counted_nlinks;/* counted nlinks in P6 */ } ino_ex_data_t; typedef struct ino_tree_node { avlnode_t avl_node; xfs_agino_t ino_startnum; /* starting inode # */ xfs_inofree_t ir_free; /* inode free bit mask */ __uint64_t ino_confirmed; /* confirmed bitmask */ __uint64_t ino_isa_dir; /* bit == 1 if a directory */ __uint8_t nlink_size; union ino_nlink disk_nlinks; /* on-disk nlinks, set in P3 */ union { ino_ex_data_t *ex_data; /* phases 6,7 */ parent_list_t *plist; /* phases 2-5 */ } ino_un; } ino_tree_node_t; #define INOS_PER_IREC (sizeof(__uint64_t) * NBBY) #define IREC_MASK(i) ((__uint64_t)1 << (i)) void add_ino_ex_data(xfs_mount_t *mp); /* * return an inode record to the free inode record pool */ void free_inode_rec(xfs_agnumber_t agno, ino_tree_node_t *ino_rec); /* * get pulls the inode record from the good inode tree */ void get_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, ino_tree_node_t *ino_rec); extern avltree_desc_t **inode_tree_ptrs; static inline int get_inode_offset(struct xfs_mount *mp, xfs_ino_t ino, ino_tree_node_t *irec) { return XFS_INO_TO_AGINO(mp, ino) - irec->ino_startnum; } static inline ino_tree_node_t * findfirst_inode_rec(xfs_agnumber_t agno) { return((ino_tree_node_t *) inode_tree_ptrs[agno]->avl_firstino); } static inline ino_tree_node_t * find_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t ino) { /* * Is the AG inside the file system */ if (agno >= mp->m_sb.sb_agcount) return NULL; return((ino_tree_node_t *) avl_findrange(inode_tree_ptrs[agno], ino)); } void find_inode_rec_range(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t start_ino, xfs_agino_t end_ino, ino_tree_node_t **first, ino_tree_node_t **last); /* * set inode states -- setting an inode to used or free also * automatically marks it as "existing". Note -- all the inode * add/set/get routines assume a valid inode number. */ ino_tree_node_t *set_inode_used_alloc(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t ino); ino_tree_node_t *set_inode_free_alloc(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t ino); void print_inode_list(xfs_agnumber_t agno); void print_uncertain_inode_list(xfs_agnumber_t agno); /* * separate trees for uncertain inodes (they may not exist). */ ino_tree_node_t *findfirst_uncertain_inode_rec(xfs_agnumber_t agno); ino_tree_node_t *find_uncertain_inode_rec(xfs_agnumber_t agno, xfs_agino_t ino); void add_inode_uncertain(xfs_mount_t *mp, xfs_ino_t ino, int free); void add_aginode_uncertain(xfs_agnumber_t agno, xfs_agino_t agino, int free); void get_uncertain_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, ino_tree_node_t *ino_rec); void clear_uncertain_ino_cache(xfs_agnumber_t agno); /* * return next in-order inode tree node. takes an "ino_tree_node_t *" */ #define next_ino_rec(ino_node_ptr) \ ((ino_tree_node_t *) ((ino_node_ptr)->avl_node.avl_nextino)) /* * return the next linked inode (forward avl tree link)-- meant to be used * by linked list routines (uncertain inode routines/records) */ #define next_link_rec(ino_node_ptr) \ ((ino_tree_node_t *) ((ino_node_ptr)->avl_node.avl_forw)) /* * Has an inode been processed for phase 6 (reference count checking)? * * add_inode_refchecked() is set on an inode when it gets traversed * during the reference count phase (6). It's set so that if the inode * is a directory, it's traversed (and it's links counted) only once. */ static inline void add_inode_refchecked(struct ino_tree_node *irec, int offset) { irec->ino_un.ex_data->ino_processed |= IREC_MASK(offset); } static inline int is_inode_refchecked(struct ino_tree_node *irec, int offset) { return (irec->ino_un.ex_data->ino_processed & IREC_MASK(offset)) != 0; } /* * set/test is inode known to be valid (although perhaps corrupt) */ static inline void set_inode_confirmed(struct ino_tree_node *irec, int offset) { irec->ino_confirmed |= IREC_MASK(offset); } static inline int is_inode_confirmed(struct ino_tree_node *irec, int offset) { return (irec->ino_confirmed & IREC_MASK(offset)) != 0; } /* * set/clear/test is inode a directory inode */ static inline void set_inode_isadir(struct ino_tree_node *irec, int offset) { irec->ino_isa_dir |= IREC_MASK(offset); } static inline void clear_inode_isadir(struct ino_tree_node *irec, int offset) { irec->ino_isa_dir &= ~IREC_MASK(offset); } static inline int inode_isadir(struct ino_tree_node *irec, int offset) { return (irec->ino_isa_dir & IREC_MASK(offset)) != 0; } /* * set/clear/test is inode free or used */ static inline void set_inode_free(struct ino_tree_node *irec, int offset) { set_inode_confirmed(irec, offset); irec->ir_free |= XFS_INOBT_MASK(offset); } static inline void set_inode_used(struct ino_tree_node *irec, int offset) { set_inode_confirmed(irec, offset); irec->ir_free &= ~XFS_INOBT_MASK(offset); } static inline int is_inode_free(struct ino_tree_node *irec, int offset) { return (irec->ir_free & XFS_INOBT_MASK(offset)) != 0; } /* * add_inode_reached() is set on inode I only if I has been reached * by an inode P claiming to be the parent and if I is a directory, * the .. link in the I says that P is I's parent. * * add_inode_ref() is called every time a link to an inode is * detected and drop_inode_ref() is called every time a link to * an inode that we've counted is removed. */ void add_inode_ref(struct ino_tree_node *irec, int offset); void drop_inode_ref(struct ino_tree_node *irec, int offset); __uint32_t num_inode_references(struct ino_tree_node *irec, int offset); void set_inode_disk_nlinks(struct ino_tree_node *irec, int offset, __uint32_t nlinks); __uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int offset); static inline int is_inode_reached(struct ino_tree_node *irec, int offset) { ASSERT(irec->ino_un.ex_data != NULL); return (irec->ino_un.ex_data->ino_reached & IREC_MASK(offset)) != 0; } static inline void add_inode_reached(struct ino_tree_node *irec, int offset) { add_inode_ref(irec, offset); irec->ino_un.ex_data->ino_reached |= IREC_MASK(offset); } /* * set/get inode number of parent -- works for directory inodes only */ void set_inode_parent(ino_tree_node_t *irec, int ino_offset, xfs_ino_t ino); xfs_ino_t get_inode_parent(ino_tree_node_t *irec, int ino_offset); /* * bmap cursor for tracking and fixing bmap btrees. All xfs btrees number * the levels with 0 being the leaf and every level up being 1 greater. */ #define XR_MAX_BMLEVELS 10 /* XXX - rcc need to verify number */ typedef struct bm_level_state { xfs_dfsbno_t fsbno; xfs_dfsbno_t left_fsbno; xfs_dfsbno_t right_fsbno; __uint64_t first_key; __uint64_t last_key; /* int level; __uint64_t prev_last_key; xfs_buf_t *bp; xfs_bmbt_block_t *block; */ } bm_level_state_t; typedef struct bm_cursor { int num_levels; xfs_ino_t ino; xfs_dinode_t *dip; bm_level_state_t level[XR_MAX_BMLEVELS]; } bmap_cursor_t; void init_bm_cursor(bmap_cursor_t *cursor, int num_level); #endif /* XFS_REPAIR_INCORE_H */ xfsprogs-3.1.9ubuntu2/repair/Makefile0000664000000000000000000000272111330256617014544 0ustar # # Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LSRCFILES = README LTCOMMAND = xfs_repair HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h btree.h \ dinode.h dir.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \ progress.h scan.h versions.h prefetch.h threads.h CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ dino_chunks.c dinode.c dir.c dir2.c globals.c incore.c \ incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \ phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c \ progress.c prefetch.c rt.c sb.c scan.c threads.c \ versions.c xfs_repair.c LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS = -static default: depend $(LTCOMMAND) globals.o: globals.h include $(BUILDRULES) # # Tracing flags: # -DXR_INODE_TRACE inode processing # -DXR_DIR_TRACE directory processing # -DXR_DUP_TRACE duplicate extent processing # -DXR_BCNT_TRACE incore bcnt freespace btree building # -DXR_BLD_FREE_TRACE building on-disk freespace (bcnt/bno) btrees # -DXR_BLD_INO_TRACE building on-disk inode allocation btrees # -DXR_BLD_ADD_EXTENT track phase 5 block extent creation # -DXR_BCKPTR_DBG parent list debugging info # -DXR_PF_TRACE prefetch trace # #CFLAGS += ... install: default $(INSTALL) -m 755 -d $(PKG_ROOT_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_ROOT_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/repair/phase5.c0000664000000000000000000013011412062210562014423 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "rt.h" #include "versions.h" #include "threads.h" #include "progress.h" /* * we maintain the current slice (path from root to leaf) * of the btree incore. when we need a new block, we ask * the block allocator for the address of a block on that * level, map the block in, and set up the appropriate * pointers (child, silbing, etc.) and keys that should * point to the new block. */ typedef struct bt_stat_level { /* * set in setup_cursor routine and maintained in the tree-building * routines */ xfs_buf_t *buf_p; /* 2 buffer pointers to ... */ xfs_buf_t *prev_buf_p; xfs_agblock_t agbno; /* current block being filled */ xfs_agblock_t prev_agbno; /* previous block */ /* * set in calculate/init cursor routines for each btree level */ int num_recs_tot; /* # tree recs in level */ int num_blocks; /* # tree blocks in level */ int num_recs_pb; /* num_recs_tot / num_blocks */ int modulo; /* num_recs_tot % num_blocks */ } bt_stat_level_t; typedef struct bt_status { int init; /* cursor set up once? */ int num_levels; /* # of levels in btree */ xfs_extlen_t num_tot_blocks; /* # blocks alloc'ed for tree */ xfs_extlen_t num_free_blocks;/* # blocks currently unused */ xfs_agblock_t root; /* root block */ /* * list of blocks to be used to set up this tree * and pointer to the first unused block on the list */ xfs_agblock_t *btree_blocks; /* block list */ xfs_agblock_t *free_btree_blocks; /* first unused block */ /* * per-level status info */ bt_stat_level_t level[XFS_BTREE_MAXLEVELS]; } bt_status_t; static __uint64_t *sb_icount_ag; /* allocated inodes per ag */ static __uint64_t *sb_ifree_ag; /* free inodes per ag */ static __uint64_t *sb_fdblocks_ag; /* free data blocks per ag */ static int mk_incore_fstree(xfs_mount_t *mp, xfs_agnumber_t agno) { int in_extent; int num_extents; xfs_agblock_t extent_start; xfs_extlen_t extent_len; xfs_agblock_t agbno; xfs_agblock_t ag_end; uint free_blocks; xfs_extlen_t blen; int bstate; /* * scan the bitmap for the ag looking for continuous * extents of free blocks. At this point, we know * that blocks in the bitmap are either set to an * "in use" state or set to unknown (0) since the * bmaps were zero'ed in phase 4 and only blocks * being used by inodes, inode bmaps, ag headers, * and the files themselves were put into the bitmap. * */ ASSERT(agno < mp->m_sb.sb_agcount); extent_start = extent_len = 0; in_extent = 0; num_extents = free_blocks = 0; if (agno < mp->m_sb.sb_agcount - 1) ag_end = mp->m_sb.sb_agblocks; else ag_end = mp->m_sb.sb_dblocks - (xfs_drfsbno_t)mp->m_sb.sb_agblocks * (mp->m_sb.sb_agcount - 1); /* * ok, now find the number of extents, keep track of the * largest extent. */ for (agbno = 0; agbno < ag_end; agbno += blen) { bstate = get_bmap_ext(agno, agbno, ag_end, &blen); if (bstate < XR_E_INUSE) { free_blocks += blen; if (in_extent == 0) { /* * found the start of a free extent */ in_extent = 1; num_extents++; extent_start = agbno; extent_len = blen; } else { extent_len += blen; } } else { if (in_extent) { /* * free extent ends here, add extent to the * 2 incore extent (avl-to-be-B+) trees */ in_extent = 0; #if defined(XR_BLD_FREE_TRACE) && defined(XR_BLD_ADD_EXTENT) fprintf(stderr, "adding extent %u [%u %u]\n", agno, extent_start, extent_len); #endif add_bno_extent(agno, extent_start, extent_len); add_bcnt_extent(agno, extent_start, extent_len); } } } if (in_extent) { /* * free extent ends here */ in_extent = 0; #if defined(XR_BLD_FREE_TRACE) && defined(XR_BLD_ADD_EXTENT) fprintf(stderr, "adding extent %u [%u %u]\n", agno, extent_start, extent_len); #endif add_bno_extent(agno, extent_start, extent_len); add_bcnt_extent(agno, extent_start, extent_len); } return(num_extents); } static xfs_agblock_t get_next_blockaddr(xfs_agnumber_t agno, int level, bt_status_t *curs) { ASSERT(curs->free_btree_blocks < curs->btree_blocks + curs->num_tot_blocks); ASSERT(curs->num_free_blocks > 0); curs->num_free_blocks--; return(*curs->free_btree_blocks++); } /* * set up the dynamically allocated block allocation data in the btree * cursor that depends on the info in the static portion of the cursor. * allocates space from the incore bno/bcnt extent trees and sets up * the first path up the left side of the tree. Also sets up the * cursor pointer to the btree root. called by init_freespace_cursor() * and init_ino_cursor() */ static void setup_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *curs) { int j; unsigned int u; xfs_extlen_t big_extent_len; xfs_agblock_t big_extent_start; extent_tree_node_t *ext_ptr; extent_tree_node_t *bno_ext_ptr; xfs_extlen_t blocks_allocated; xfs_agblock_t *agb_ptr; /* * get the number of blocks we need to allocate, then * set up block number array, set the free block pointer * to the first block in the array, and null the array */ big_extent_len = curs->num_tot_blocks; blocks_allocated = 0; ASSERT(big_extent_len > 0); if ((curs->btree_blocks = malloc(sizeof(xfs_agblock_t *) * big_extent_len)) == NULL) do_error(_("could not set up btree block array\n")); agb_ptr = curs->free_btree_blocks = curs->btree_blocks; for (j = 0; j < curs->num_free_blocks; j++, agb_ptr++) *agb_ptr = NULLAGBLOCK; /* * grab the smallest extent and use it up, then get the * next smallest. This mimics the init_*_cursor code. */ if ((ext_ptr = findfirst_bcnt_extent(agno)) == NULL) do_error(_("error - not enough free space in filesystem\n")); agb_ptr = curs->btree_blocks; j = curs->level[0].num_blocks; /* * set up the free block array */ while (blocks_allocated < big_extent_len) { /* * use up the extent we've got */ for (u = 0; u < ext_ptr->ex_blockcount && blocks_allocated < big_extent_len; u++) { ASSERT(agb_ptr < curs->btree_blocks + curs->num_tot_blocks); *agb_ptr++ = ext_ptr->ex_startblock + u; blocks_allocated++; } /* * if we only used part of this last extent, then we * need only to reset the extent in the extent * trees and we're done */ if (u < ext_ptr->ex_blockcount) { big_extent_start = ext_ptr->ex_startblock + u; big_extent_len = ext_ptr->ex_blockcount - u; ASSERT(big_extent_len > 0); bno_ext_ptr = find_bno_extent(agno, ext_ptr->ex_startblock); ASSERT(bno_ext_ptr != NULL); get_bno_extent(agno, bno_ext_ptr); release_extent_tree_node(bno_ext_ptr); ext_ptr = get_bcnt_extent(agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); release_extent_tree_node(ext_ptr); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "releasing extent: %u [%u %u]\n", agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); fprintf(stderr, "blocks_allocated = %d\n", blocks_allocated); #endif add_bno_extent(agno, big_extent_start, big_extent_len); add_bcnt_extent(agno, big_extent_start, big_extent_len); return; } /* * delete the used-up extent from both extent trees and * find next biggest extent */ #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "releasing extent: %u [%u %u]\n", agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); #endif bno_ext_ptr = find_bno_extent(agno, ext_ptr->ex_startblock); ASSERT(bno_ext_ptr != NULL); get_bno_extent(agno, bno_ext_ptr); release_extent_tree_node(bno_ext_ptr); ext_ptr = get_bcnt_extent(agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); ASSERT(ext_ptr != NULL); release_extent_tree_node(ext_ptr); ext_ptr = findfirst_bcnt_extent(agno); } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "blocks_allocated = %d\n", blocks_allocated); #endif } static void write_cursor(bt_status_t *curs) { int i; for (i = 0; i < curs->num_levels; i++) { #if defined(XR_BLD_FREE_TRACE) || defined(XR_BLD_INO_TRACE) fprintf(stderr, "writing bt block %u\n", curs->level[i].agbno); #endif if (curs->level[i].prev_buf_p != NULL) { ASSERT(curs->level[i].prev_agbno != NULLAGBLOCK); #if defined(XR_BLD_FREE_TRACE) || defined(XR_BLD_INO_TRACE) fprintf(stderr, "writing bt prev block %u\n", curs->level[i].prev_agbno); #endif libxfs_writebuf(curs->level[i].prev_buf_p, 0); } libxfs_writebuf(curs->level[i].buf_p, 0); } } static void finish_cursor(bt_status_t *curs) { ASSERT(curs->num_free_blocks == 0); free(curs->btree_blocks); } /* * XXX(hch): any reason we don't just look at mp->m_alloc_mxr? */ #define XR_ALLOC_BLOCK_MAXRECS(mp, level) \ xfs_allocbt_maxrecs((mp), (mp)->m_sb.sb_blocksize, \ (level) == 0) /* * this calculates a freespace cursor for an ag. * btree_curs is an in/out. returns the number of * blocks that will show up in the AGFL. */ static int calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t *extents, bt_status_t *btree_curs) { xfs_extlen_t blocks_needed; /* a running count */ xfs_extlen_t blocks_allocated_pt; /* per tree */ xfs_extlen_t blocks_allocated_total; /* for both trees */ xfs_agblock_t num_extents; int i; int extents_used; int extra_blocks; bt_stat_level_t *lptr; bt_stat_level_t *p_lptr; extent_tree_node_t *ext_ptr; int level; #ifdef XR_BLD_FREE_TRACE int old_state; int state = XR_E_BAD_STATE; #endif #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "in init_freespace_cursor, agno = %d\n", agno); #endif num_extents = *extents; extents_used = 0; ASSERT(num_extents != 0); lptr = &btree_curs->level[0]; btree_curs->init = 1; /* * figure out how much space we need for the leaf level * of the tree and set up the cursor for the leaf level * (note that the same code is duplicated further down) */ lptr->num_blocks = howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0)); lptr->num_recs_pb = num_extents / lptr->num_blocks; lptr->modulo = num_extents % lptr->num_blocks; lptr->num_recs_tot = num_extents; level = 1; /* * if we need more levels, set them up. # of records * per level is the # of blocks in the level below it */ if (lptr->num_blocks > 1) { for (; btree_curs->level[level - 1].num_blocks > 1 && level < XFS_BTREE_MAXLEVELS; level++) { lptr = &btree_curs->level[level]; p_lptr = &btree_curs->level[level - 1]; lptr->num_blocks = howmany(p_lptr->num_blocks, XR_ALLOC_BLOCK_MAXRECS(mp, level)); lptr->modulo = p_lptr->num_blocks % lptr->num_blocks; lptr->num_recs_pb = p_lptr->num_blocks / lptr->num_blocks; lptr->num_recs_tot = p_lptr->num_blocks; } } ASSERT(lptr->num_blocks == 1); btree_curs->num_levels = level; /* * ok, now we have a hypothetical cursor that * will work for both the bno and bcnt trees. * now figure out if using up blocks to set up the * trees will perturb the shape of the freespace tree. * if so, we've over-allocated. the freespace trees * as they will be *after* accounting for the free space * we've used up will need fewer blocks to to represent * than we've allocated. We can use the AGFL to hold * XFS_AGFL_SIZE (sector/xfs_agfl_t) blocks but that's it. * Thus we limit things to XFS_AGFL_SIZE/2 for each of the 2 btrees. * if the number of extra blocks is more than that, * we'll have to be called again. */ for (blocks_needed = 0, i = 0; i < level; i++) { blocks_needed += btree_curs->level[i].num_blocks; } /* * record the # of blocks we've allocated */ blocks_allocated_pt = blocks_needed; blocks_needed *= 2; blocks_allocated_total = blocks_needed; /* * figure out how many free extents will be used up by * our space allocation */ if ((ext_ptr = findfirst_bcnt_extent(agno)) == NULL) do_error(_("can't rebuild fs trees -- not enough free space " "on ag %u\n"), agno); i = 0; while (ext_ptr != NULL && blocks_needed > 0) { if (ext_ptr->ex_blockcount <= blocks_needed) { blocks_needed -= ext_ptr->ex_blockcount; extents_used++; } else { blocks_needed = 0; } ext_ptr = findnext_bcnt_extent(agno, ext_ptr); #ifdef XR_BLD_FREE_TRACE if (ext_ptr != NULL) { fprintf(stderr, "got next extent [%u %u]\n", ext_ptr->ex_startblock, ext_ptr->ex_blockcount); } else { fprintf(stderr, "out of extents\n"); } #endif } if (blocks_needed > 0) do_error(_("ag %u - not enough free space to build freespace " "btrees\n"), agno); ASSERT(num_extents >= extents_used); num_extents -= extents_used; /* * see if the number of leaf blocks will change as a result * of the number of extents changing */ if (howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0)) != btree_curs->level[0].num_blocks) { /* * yes -- recalculate the cursor. If the number of * excess (overallocated) blocks is < XFS_AGFL_SIZE/2, we're ok. * we can put those into the AGFL. we don't try * and get things to converge exactly (reach a * state with zero excess blocks) because there * exist pathological cases which will never * converge. first, check for the zero-case. */ if (num_extents == 0) { /* * ok, we've used up all the free blocks * trying to lay out the leaf level. go * to a one block (empty) btree and put the * already allocated blocks into the AGFL */ if (btree_curs->level[0].num_blocks != 1) { /* * we really needed more blocks because * the old tree had more than one level. * this is bad. */ do_warn(_("not enough free blocks left to " "describe all free blocks in AG " "%u\n"), agno); } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "ag %u -- no free extents, alloc'ed %d\n", agno, blocks_allocated_pt); #endif lptr->num_blocks = 1; lptr->modulo = 0; lptr->num_recs_pb = 0; lptr->num_recs_tot = 0; btree_curs->num_levels = 1; /* * don't reset the allocation stats, assume * they're all extra blocks * don't forget to return the total block count * not the per-tree block count. these are the * extras that will go into the AGFL. subtract * two for the root blocks. */ btree_curs->num_tot_blocks = blocks_allocated_pt; btree_curs->num_free_blocks = blocks_allocated_pt; *extents = 0; return(blocks_allocated_total - 2); } lptr = &btree_curs->level[0]; lptr->num_blocks = howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0)); lptr->num_recs_pb = num_extents / lptr->num_blocks; lptr->modulo = num_extents % lptr->num_blocks; lptr->num_recs_tot = num_extents; level = 1; /* * if we need more levels, set them up */ if (lptr->num_blocks > 1) { for (level = 1; btree_curs->level[level-1].num_blocks > 1 && level < XFS_BTREE_MAXLEVELS; level++) { lptr = &btree_curs->level[level]; p_lptr = &btree_curs->level[level-1]; lptr->num_blocks = howmany(p_lptr->num_blocks, XR_ALLOC_BLOCK_MAXRECS(mp, level)); lptr->modulo = p_lptr->num_blocks % lptr->num_blocks; lptr->num_recs_pb = p_lptr->num_blocks / lptr->num_blocks; lptr->num_recs_tot = p_lptr->num_blocks; } } ASSERT(lptr->num_blocks == 1); btree_curs->num_levels = level; /* * now figure out the number of excess blocks */ for (blocks_needed = 0, i = 0; i < level; i++) { blocks_needed += btree_curs->level[i].num_blocks; } blocks_needed *= 2; ASSERT(blocks_allocated_total >= blocks_needed); extra_blocks = blocks_allocated_total - blocks_needed; } else { if (extents_used > 0) { /* * reset the leaf level geometry to account * for consumed extents. we can leave the * rest of the cursor alone since the number * of leaf blocks hasn't changed. */ lptr = &btree_curs->level[0]; lptr->num_recs_pb = num_extents / lptr->num_blocks; lptr->modulo = num_extents % lptr->num_blocks; lptr->num_recs_tot = num_extents; } extra_blocks = 0; } btree_curs->num_tot_blocks = blocks_allocated_pt; btree_curs->num_free_blocks = blocks_allocated_pt; *extents = num_extents; return(extra_blocks); } static void prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, xfs_agblock_t startblock, xfs_extlen_t blockcount, int level, __uint32_t magic) { struct xfs_btree_block *bt_hdr; xfs_alloc_key_t *bt_key; xfs_alloc_ptr_t *bt_ptr; xfs_agblock_t agbno; bt_stat_level_t *lptr; level++; if (level >= btree_curs->num_levels) return; lptr = &btree_curs->level[level]; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { /* * only happens once when initializing the * left-hand side of the tree. */ prop_freespace_cursor(mp, agno, btree_curs, startblock, blockcount, level, magic); } if (be16_to_cpu(bt_hdr->bb_numrecs) == lptr->num_recs_pb + (lptr->modulo > 0)) { /* * write out current prev block, grab us a new block, * and set the rightsib pointer of current block */ #ifdef XR_BLD_FREE_TRACE fprintf(stderr, " %d ", lptr->prev_agbno); #endif if (lptr->prev_agbno != NULLAGBLOCK) { ASSERT(lptr->prev_buf_p != NULL); libxfs_writebuf(lptr->prev_buf_p, 0); } lptr->prev_agbno = lptr->agbno;; lptr->prev_buf_p = lptr->buf_p; agbno = get_next_blockaddr(agno, level, btree_curs); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1)); lptr->agbno = agbno; if (lptr->modulo) lptr->modulo--; /* * initialize block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(magic); bt_hdr->bb_level = cpu_to_be16(level); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; /* * propagate extent record for first extent in new block up */ prop_freespace_cursor(mp, agno, btree_curs, startblock, blockcount, level, magic); } /* * add extent info to current block */ be16_add_cpu(&bt_hdr->bb_numrecs, 1); bt_key = XFS_ALLOC_KEY_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); bt_ptr = XFS_ALLOC_PTR_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs), mp->m_alloc_mxr[1]); bt_key->ar_startblock = cpu_to_be32(startblock); bt_key->ar_blockcount = cpu_to_be32(blockcount); *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); } /* * rebuilds a freespace tree given a cursor and magic number of type * of tree to build (bno or bcnt). returns the number of free blocks * represented by the tree. */ static xfs_extlen_t build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, __uint32_t magic) { xfs_agnumber_t i; xfs_agblock_t j; struct xfs_btree_block *bt_hdr; xfs_alloc_rec_t *bt_rec; int level; xfs_agblock_t agbno; extent_tree_node_t *ext_ptr; bt_stat_level_t *lptr; xfs_extlen_t freeblks; #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "in build_freespace_tree, agno = %d\n", agno); #endif level = btree_curs->num_levels; freeblks = 0; ASSERT(level > 0); /* * initialize the first block on each btree level */ for (i = 0; i < level; i++) { lptr = &btree_curs->level[i]; agbno = get_next_blockaddr(agno, i, btree_curs); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1)); if (i == btree_curs->num_levels - 1) btree_curs->root = agbno; lptr->agbno = agbno; lptr->prev_agbno = NULLAGBLOCK; lptr->prev_buf_p = NULL; /* * initialize block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(magic); bt_hdr->bb_level = cpu_to_be16(i); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; } /* * run along leaf, setting up records. as we have to switch * blocks, call the prop_freespace_cursor routine to set up the new * pointers for the parent. that can recurse up to the root * if required. set the sibling pointers for leaf level here. */ if (magic == XFS_ABTB_MAGIC) ext_ptr = findfirst_bno_extent(agno); else ext_ptr = findfirst_bcnt_extent(agno); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "bft, agno = %d, start = %u, count = %u\n", agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); #endif lptr = &btree_curs->level[0]; for (i = 0; i < btree_curs->level[0].num_blocks; i++) { /* * block initialization, lay in block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(magic); bt_hdr->bb_level = 0; bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + (lptr->modulo > 0)); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "bft, bb_numrecs = %d\n", be16_to_cpu(bt_hdr->bb_numrecs)); #endif if (lptr->modulo > 0) lptr->modulo--; /* * initialize values in the path up to the root if * this is a multi-level btree */ if (btree_curs->num_levels > 1) prop_freespace_cursor(mp, agno, btree_curs, ext_ptr->ex_startblock, ext_ptr->ex_blockcount, 0, magic); bt_rec = (xfs_alloc_rec_t *) ((char *)bt_hdr + XFS_ALLOC_BLOCK_LEN(mp)); for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { ASSERT(ext_ptr != NULL); bt_rec[j].ar_startblock = cpu_to_be32( ext_ptr->ex_startblock); bt_rec[j].ar_blockcount = cpu_to_be32( ext_ptr->ex_blockcount); freeblks += ext_ptr->ex_blockcount; if (magic == XFS_ABTB_MAGIC) ext_ptr = findnext_bno_extent(ext_ptr); else ext_ptr = findnext_bcnt_extent(agno, ext_ptr); #if 0 #ifdef XR_BLD_FREE_TRACE if (ext_ptr == NULL) fprintf(stderr, "null extent pointer, j = %d\n", j); else fprintf(stderr, "bft, agno = %d, start = %u, count = %u\n", agno, ext_ptr->ex_startblock, ext_ptr->ex_blockcount); #endif #endif } if (ext_ptr != NULL) { /* * get next leaf level block */ if (lptr->prev_buf_p != NULL) { #ifdef XR_BLD_FREE_TRACE fprintf(stderr, " writing fst agbno %u\n", lptr->prev_agbno); #endif ASSERT(lptr->prev_agbno != NULLAGBLOCK); libxfs_writebuf(lptr->prev_buf_p, 0); } lptr->prev_buf_p = lptr->buf_p; lptr->prev_agbno = lptr->agbno; lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(lptr->agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), XFS_FSB_TO_BB(mp, 1)); } } return(freeblks); } /* * XXX(hch): any reason we don't just look at mp->m_inobt_mxr? */ #define XR_INOBT_BLOCK_MAXRECS(mp, level) \ xfs_inobt_maxrecs((mp), (mp)->m_sb.sb_blocksize, \ (level) == 0) /* * we don't have to worry here about how chewing up free extents * may perturb things because inode tree building happens before * freespace tree building. */ static void init_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, __uint64_t *num_inos, __uint64_t *num_free_inos) { __uint64_t ninos; __uint64_t nfinos; ino_tree_node_t *ino_rec; int num_recs; int level; bt_stat_level_t *lptr; bt_stat_level_t *p_lptr; xfs_extlen_t blocks_allocated; int i; *num_inos = *num_free_inos = 0; ninos = nfinos = 0; lptr = &btree_curs->level[0]; btree_curs->init = 1; if ((ino_rec = findfirst_inode_rec(agno)) == NULL) { /* * easy corner-case -- no inode records */ lptr->num_blocks = 1; lptr->modulo = 0; lptr->num_recs_pb = 0; lptr->num_recs_tot = 0; btree_curs->num_levels = 1; btree_curs->num_tot_blocks = btree_curs->num_free_blocks = 1; setup_cursor(mp, agno, btree_curs); return; } /* * build up statistics */ for (num_recs = 0; ino_rec != NULL; ino_rec = next_ino_rec(ino_rec)) { ninos += XFS_INODES_PER_CHUNK; num_recs++; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { ASSERT(is_inode_confirmed(ino_rec, i)); if (is_inode_free(ino_rec, i)) nfinos++; } } blocks_allocated = lptr->num_blocks = howmany(num_recs, XR_INOBT_BLOCK_MAXRECS(mp, 0)); lptr->modulo = num_recs % lptr->num_blocks; lptr->num_recs_pb = num_recs / lptr->num_blocks; lptr->num_recs_tot = num_recs; level = 1; if (lptr->num_blocks > 1) { for (; btree_curs->level[level-1].num_blocks > 1 && level < XFS_BTREE_MAXLEVELS; level++) { lptr = &btree_curs->level[level]; p_lptr = &btree_curs->level[level - 1]; lptr->num_blocks = howmany(p_lptr->num_blocks, XR_INOBT_BLOCK_MAXRECS(mp, level)); lptr->modulo = p_lptr->num_blocks % lptr->num_blocks; lptr->num_recs_pb = p_lptr->num_blocks / lptr->num_blocks; lptr->num_recs_tot = p_lptr->num_blocks; blocks_allocated += lptr->num_blocks; } } ASSERT(lptr->num_blocks == 1); btree_curs->num_levels = level; btree_curs->num_tot_blocks = btree_curs->num_free_blocks = blocks_allocated; setup_cursor(mp, agno, btree_curs); *num_inos = ninos; *num_free_inos = nfinos; return; } static void prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, xfs_agino_t startino, int level) { struct xfs_btree_block *bt_hdr; xfs_inobt_key_t *bt_key; xfs_inobt_ptr_t *bt_ptr; xfs_agblock_t agbno; bt_stat_level_t *lptr; level++; if (level >= btree_curs->num_levels) return; lptr = &btree_curs->level[level]; bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { /* * this only happens once to initialize the * first path up the left side of the tree * where the agbno's are already set up */ prop_ino_cursor(mp, agno, btree_curs, startino, level); } if (be16_to_cpu(bt_hdr->bb_numrecs) == lptr->num_recs_pb + (lptr->modulo > 0)) { /* * write out current prev block, grab us a new block, * and set the rightsib pointer of current block */ #ifdef XR_BLD_INO_TRACE fprintf(stderr, " ino prop agbno %d ", lptr->prev_agbno); #endif if (lptr->prev_agbno != NULLAGBLOCK) { ASSERT(lptr->prev_buf_p != NULL); libxfs_writebuf(lptr->prev_buf_p, 0); } lptr->prev_agbno = lptr->agbno;; lptr->prev_buf_p = lptr->buf_p; agbno = get_next_blockaddr(agno, level, btree_curs); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1)); lptr->agbno = agbno; if (lptr->modulo) lptr->modulo--; /* * initialize block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); bt_hdr->bb_level = cpu_to_be16(level); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; /* * propagate extent record for first extent in new block up */ prop_ino_cursor(mp, agno, btree_curs, startino, level); } /* * add inode info to current block */ be16_add_cpu(&bt_hdr->bb_numrecs, 1); bt_key = XFS_INOBT_KEY_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs)); bt_ptr = XFS_INOBT_PTR_ADDR(mp, bt_hdr, be16_to_cpu(bt_hdr->bb_numrecs), mp->m_inobt_mxr[1]); bt_key->ir_startino = cpu_to_be32(startino); *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); } static void build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, xfs_agino_t first_agino, xfs_agino_t count, xfs_agino_t freecount) { xfs_buf_t *agi_buf; xfs_agi_t *agi; int i; agi_buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE); agi = XFS_BUF_TO_AGI(agi_buf); memset(agi, 0, mp->m_sb.sb_sectsize); agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); agi->agi_seqno = cpu_to_be32(agno); if (agno < mp->m_sb.sb_agcount - 1) agi->agi_length = cpu_to_be32(mp->m_sb.sb_agblocks); else agi->agi_length = cpu_to_be32(mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno); agi->agi_count = cpu_to_be32(count); agi->agi_root = cpu_to_be32(btree_curs->root); agi->agi_level = cpu_to_be32(btree_curs->num_levels); agi->agi_freecount = cpu_to_be32(freecount); agi->agi_newino = cpu_to_be32(first_agino); agi->agi_dirino = cpu_to_be32(NULLAGINO); for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) agi->agi_unlinked[i] = cpu_to_be32(NULLAGINO); libxfs_writebuf(agi_buf, 0); } /* * rebuilds an inode tree given a cursor. We're lazy here and call * the routine that builds the agi */ static void build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs) { xfs_agnumber_t i; xfs_agblock_t j; xfs_agblock_t agbno; xfs_agino_t first_agino; struct xfs_btree_block *bt_hdr; xfs_inobt_rec_t *bt_rec; ino_tree_node_t *ino_rec; bt_stat_level_t *lptr; xfs_agino_t count = 0; xfs_agino_t freecount = 0; int inocnt; int k; int level = btree_curs->num_levels; for (i = 0; i < level; i++) { lptr = &btree_curs->level[i]; agbno = get_next_blockaddr(agno, i, btree_curs); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1)); if (i == btree_curs->num_levels - 1) btree_curs->root = agbno; lptr->agbno = agbno; lptr->prev_agbno = NULLAGBLOCK; lptr->prev_buf_p = NULL; /* * initialize block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); bt_hdr->bb_level = cpu_to_be16(i); bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = 0; } /* * run along leaf, setting up records. as we have to switch * blocks, call the prop_ino_cursor routine to set up the new * pointers for the parent. that can recurse up to the root * if required. set the sibling pointers for leaf level here. */ ino_rec = findfirst_inode_rec(agno); if (ino_rec != NULL) first_agino = ino_rec->ino_startnum; else first_agino = NULLAGINO; lptr = &btree_curs->level[0]; for (i = 0; i < lptr->num_blocks; i++) { /* * block initialization, lay in block header */ bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); memset(bt_hdr, 0, mp->m_sb.sb_blocksize); bt_hdr->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); bt_hdr->bb_level = 0; bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + (lptr->modulo > 0)); if (lptr->modulo > 0) lptr->modulo--; if (lptr->num_recs_pb > 0) prop_ino_cursor(mp, agno, btree_curs, ino_rec->ino_startnum, 0); bt_rec = (xfs_inobt_rec_t *) ((char *)bt_hdr + XFS_INOBT_BLOCK_LEN(mp)); for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { ASSERT(ino_rec != NULL); bt_rec[j].ir_startino = cpu_to_be32(ino_rec->ino_startnum); bt_rec[j].ir_free = cpu_to_be64(ino_rec->ir_free); inocnt = 0; for (k = 0; k < sizeof(xfs_inofree_t)*NBBY; k++) { ASSERT(is_inode_confirmed(ino_rec, k)); inocnt += is_inode_free(ino_rec, k); } bt_rec[j].ir_freecount = cpu_to_be32(inocnt); freecount += inocnt; count += XFS_INODES_PER_CHUNK; ino_rec = next_ino_rec(ino_rec); } if (ino_rec != NULL) { /* * get next leaf level block */ if (lptr->prev_buf_p != NULL) { #ifdef XR_BLD_INO_TRACE fprintf(stderr, "writing inobt agbno %u\n", lptr->prev_agbno); #endif ASSERT(lptr->prev_agbno != NULLAGBLOCK); libxfs_writebuf(lptr->prev_buf_p, 0); } lptr->prev_buf_p = lptr->buf_p; lptr->prev_agbno = lptr->agbno; lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(lptr->agbno); lptr->buf_p = libxfs_getbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), XFS_FSB_TO_BB(mp, 1)); } } build_agi(mp, agno, btree_curs, first_agino, count, freecount); } /* * build both the agf and the agfl for an agno given both * btree cursors */ static void build_agf_agfl(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *bno_bt, bt_status_t *bcnt_bt, xfs_extlen_t freeblks, /* # free blocks in tree */ int lostblocks) /* # blocks that will be lost */ { extent_tree_node_t *ext_ptr; xfs_buf_t *agf_buf, *agfl_buf; int i; int j; xfs_agfl_t *agfl; xfs_agf_t *agf; agf_buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE); agf = XFS_BUF_TO_AGF(agf_buf); memset(agf, 0, mp->m_sb.sb_sectsize); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "agf = 0x%x, agf_buf->b_un.b_addr = 0x%x\n", (__psint_t) agf, (__psint_t) agf_buf->b_un.b_addr); #endif /* * set up fixed part of agf */ agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); agf->agf_seqno = cpu_to_be32(agno); if (agno < mp->m_sb.sb_agcount - 1) agf->agf_length = cpu_to_be32(mp->m_sb.sb_agblocks); else agf->agf_length = cpu_to_be32(mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno); agf->agf_roots[XFS_BTNUM_BNO] = cpu_to_be32(bno_bt->root); agf->agf_levels[XFS_BTNUM_BNO] = cpu_to_be32(bno_bt->num_levels); agf->agf_roots[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->root); agf->agf_levels[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->num_levels); agf->agf_freeblks = cpu_to_be32(freeblks); /* * Count and record the number of btree blocks consumed if required. */ if (xfs_sb_version_haslazysbcount(&mp->m_sb)) { /* * Don't count the root blocks as they are already * accounted for. */ agf->agf_btreeblks = cpu_to_be32( (bno_bt->num_tot_blocks - bno_bt->num_free_blocks) + (bcnt_bt->num_tot_blocks - bcnt_bt->num_free_blocks) - 2); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "agf->agf_btreeblks = %u\n", be32_to_cpu(agf->agf_btreeblks)); #endif } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "bno root = %u, bcnt root = %u, indices = %u %u\n", be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), XFS_BTNUM_BNO, XFS_BTNUM_CNT); #endif /* * do we have left-over blocks in the btree cursors that should * be used to fill the AGFL? */ if (bno_bt->num_free_blocks > 0 || bcnt_bt->num_free_blocks > 0) { /* * yes - grab the AGFL buffer */ agfl_buf = libxfs_getbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE); agfl = XFS_BUF_TO_AGFL(agfl_buf); memset(agfl, 0, mp->m_sb.sb_sectsize); /* * ok, now grab as many blocks as we can */ i = j = 0; while (bno_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { agfl->agfl_bno[i] = cpu_to_be32( get_next_blockaddr(agno, 0, bno_bt)); i++; } while (bcnt_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp)) { agfl->agfl_bno[i] = cpu_to_be32( get_next_blockaddr(agno, 0, bcnt_bt)); i++; } /* * now throw the rest of the blocks away and complain */ while (bno_bt->num_free_blocks > 0) { (void) get_next_blockaddr(agno, 0, bno_bt); j++; } while (bcnt_bt->num_free_blocks > 0) { (void) get_next_blockaddr(agno, 0, bcnt_bt); j++; } if (j > 0) { if (j == lostblocks) do_warn(_("lost %d blocks in ag %u\n"), j, agno); else do_warn(_("thought we were going to lose %d " "blocks in ag %u, actually lost " "%d\n"), lostblocks, j, agno); } agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(i - 1); agf->agf_flcount = cpu_to_be32(i); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "writing agfl for ag %u\n", agno); #endif libxfs_writebuf(agfl_buf, 0); } else { agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; } ext_ptr = findbiggest_bcnt_extent(agno); agf->agf_longest = cpu_to_be32((ext_ptr != NULL) ? ext_ptr->ex_blockcount : 0); ASSERT(be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]) != be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); libxfs_writebuf(agf_buf, 0); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "wrote agf for ag %u, error = %d\n", agno, error); #endif } /* * update the superblock counters, sync the sb version numbers and * feature bits to the filesystem, and sync up the on-disk superblock * to match the incore superblock. */ static void sync_sb(xfs_mount_t *mp) { xfs_buf_t *bp; bp = libxfs_getsb(mp, 0); if (!bp) do_error(_("couldn't get superblock\n")); mp->m_sb.sb_icount = sb_icount; mp->m_sb.sb_ifree = sb_ifree; mp->m_sb.sb_fdblocks = sb_fdblocks; mp->m_sb.sb_frextents = sb_frextents; update_sb_version(mp); libxfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); libxfs_writebuf(bp, 0); } /* * make sure the root and realtime inodes show up allocated * even if they've been freed. they get reinitialized in phase6. */ static void keep_fsinos(xfs_mount_t *mp) { ino_tree_node_t *irec; int i; irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); for (i = 0; i < 3; i++) set_inode_used(irec, i); } static void phase5_func( xfs_mount_t *mp, xfs_agnumber_t agno) { __uint64_t num_inos; __uint64_t num_free_inos; bt_status_t bno_btree_curs; bt_status_t bcnt_btree_curs; bt_status_t ino_btree_curs; int extra_blocks = 0; uint num_freeblocks; xfs_extlen_t freeblks1; #ifdef DEBUG xfs_extlen_t freeblks2; #endif xfs_agblock_t num_extents; if (verbose) do_log(_(" - agno = %d\n"), agno); { /* * build up incore bno and bcnt extent btrees */ num_extents = mk_incore_fstree(mp, agno); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", count_bno_extents(agno)); #endif if (num_extents == 0) { /* * XXX - what we probably should do here is pick an * inode for a regular file in the allocation group * that has space allocated and shoot it by traversing * the bmap list and putting all its extents on the * incore freespace trees, clearing the inode, * and clearing the in-use bit in the incore inode * tree. Then try mk_incore_fstree() again. */ do_error(_("unable to rebuild AG %u. " "Not enough free space in on-disk AG.\n"), agno); } /* * ok, now set up the btree cursors for the * on-disk btrees (includs pre-allocating all * required blocks for the trees themselves) */ init_ino_cursor(mp, agno, &ino_btree_curs, &num_inos, &num_free_inos); sb_icount_ag[agno] += num_inos; sb_ifree_ag[agno] += num_free_inos; num_extents = count_bno_extents_blocks(agno, &num_freeblocks); /* * lose two blocks per AG -- the space tree roots * are counted as allocated since the space trees * always have roots */ sb_fdblocks_ag[agno] += num_freeblocks - 2; if (num_extents == 0) { /* * XXX - what we probably should do here is pick an * inode for a regular file in the allocation group * that has space allocated and shoot it by traversing * the bmap list and putting all its extents on the * incore freespace trees, clearing the inode, * and clearing the in-use bit in the incore inode * tree. Then try mk_incore_fstree() again. */ do_error( _("unable to rebuild AG %u. No free space.\n"), agno); } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", num_extents); #endif /* * track blocks that we might really lose */ extra_blocks = calculate_freespace_cursor(mp, agno, &num_extents, &bno_btree_curs); /* * freespace btrees live in the "free space" but * the filesystem treats AGFL blocks as allocated * since they aren't described by the freespace trees */ /* * see if we can fit all the extra blocks into the AGFL */ extra_blocks = (extra_blocks - XFS_AGFL_SIZE(mp) > 0) ? extra_blocks - XFS_AGFL_SIZE(mp) : 0; if (extra_blocks > 0) { do_warn(_("lost %d blocks in agno %d, sorry.\n"), extra_blocks, agno); sb_fdblocks_ag[agno] -= extra_blocks; } bcnt_btree_curs = bno_btree_curs; setup_cursor(mp, agno, &bno_btree_curs); setup_cursor(mp, agno, &bcnt_btree_curs); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", count_bno_extents(agno)); fprintf(stderr, "# of bcnt extents is %d\n", count_bcnt_extents(agno)); #endif /* * now rebuild the freespace trees */ freeblks1 = build_freespace_tree(mp, agno, &bno_btree_curs, XFS_ABTB_MAGIC); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of free blocks == %d\n", freeblks1); #endif write_cursor(&bno_btree_curs); #ifdef DEBUG freeblks2 = build_freespace_tree(mp, agno, &bcnt_btree_curs, XFS_ABTC_MAGIC); #else (void) build_freespace_tree(mp, agno, &bcnt_btree_curs, XFS_ABTC_MAGIC); #endif write_cursor(&bcnt_btree_curs); ASSERT(freeblks1 == freeblks2); /* * set up agf and agfl */ build_agf_agfl(mp, agno, &bno_btree_curs, &bcnt_btree_curs, freeblks1, extra_blocks); /* * build inode allocation tree. this also build the agi */ build_ino_tree(mp, agno, &ino_btree_curs); write_cursor(&ino_btree_curs); /* * tear down cursors */ finish_cursor(&bno_btree_curs); finish_cursor(&ino_btree_curs); finish_cursor(&bcnt_btree_curs); /* * release the incore per-AG bno/bcnt trees so * the extent nodes can be recycled */ release_agbno_extent_tree(agno); release_agbcnt_extent_tree(agno); } PROG_RPT_INC(prog_rpt_done[agno], 1); } void phase5(xfs_mount_t *mp) { xfs_agnumber_t agno; do_log(_("Phase 5 - rebuild AG headers and trees...\n")); set_progress_msg(PROG_FMT_REBUILD_AG, (__uint64_t )glob_agcount); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "inobt level 1, maxrec = %d, minrec = %d\n", xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, 0), xfs_inobt_maxrecs(mp->m_sb.sb_blocksize, 0) / 2 ); fprintf(stderr, "inobt level 0 (leaf), maxrec = %d, minrec = %d\n", xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, xfs_inobt, 1), xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, xfs_inobt, 1) / 2); fprintf(stderr, "xr inobt level 0 (leaf), maxrec = %d\n", XR_INOBT_BLOCK_MAXRECS(mp, 0)); fprintf(stderr, "xr inobt level 1 (int), maxrec = %d\n", XR_INOBT_BLOCK_MAXRECS(mp, 1)); fprintf(stderr, "bnobt level 1, maxrec = %d, minrec = %d\n", xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 0), xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 0) / 2); fprintf(stderr, "bnobt level 0 (leaf), maxrec = %d, minrec = %d\n", xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 1), xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 1) / 2); #endif /* * make sure the root and realtime inodes show up allocated */ keep_fsinos(mp); /* allocate per ag counters */ sb_icount_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t)); if (sb_icount_ag == NULL) do_error(_("cannot alloc sb_icount_ag buffers\n")); sb_ifree_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t)); if (sb_ifree_ag == NULL) do_error(_("cannot alloc sb_ifree_ag buffers\n")); sb_fdblocks_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t)); if (sb_fdblocks_ag == NULL) do_error(_("cannot alloc sb_fdblocks_ag buffers\n")); for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) phase5_func(mp, agno); print_final_rpt(); /* aggregate per ag counters */ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { sb_icount += sb_icount_ag[agno]; sb_ifree += sb_ifree_ag[agno]; sb_fdblocks += sb_fdblocks_ag[agno]; } free(sb_icount_ag); free(sb_ifree_ag); free(sb_fdblocks_ag); if (mp->m_sb.sb_rblocks) { do_log( _(" - generate realtime summary info and bitmap...\n")); rtinit(mp); generate_rtinfo(mp, btmcompute, sumcompute); } do_log(_(" - reset superblock...\n")); /* * sync superblock counter and set version bits correctly */ sync_sb(mp); bad_ino_btree = 0; } xfsprogs-3.1.9ubuntu2/repair/btree.h0000664000000000000000000000354011307015331014344 0ustar /* * Copyright (c) 2007 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _BTREE_H #define _BTREE_H struct btree_root; void btree_init( struct btree_root **root); void btree_destroy( struct btree_root *root); int btree_is_empty( struct btree_root *root); void * btree_lookup( struct btree_root *root, unsigned long key); void * btree_find( struct btree_root *root, unsigned long key, unsigned long *actual_key); void * btree_peek_prev( struct btree_root *root, unsigned long *key); void * btree_peek_next( struct btree_root *root, unsigned long *key); void * btree_lookup_next( struct btree_root *root, unsigned long *key); void * btree_lookup_prev( struct btree_root *root, unsigned long *key); int btree_insert( struct btree_root *root, unsigned long key, void *value); void * btree_delete( struct btree_root *root, unsigned long key); int btree_update_key( struct btree_root *root, unsigned long old_key, unsigned long new_key); int btree_update_value( struct btree_root *root, unsigned long key, void *new_value); void btree_clear( struct btree_root *root); #ifdef BTREE_STATS void btree_print_stats( struct btree_root *root, FILE *f); #endif #endif /* _BTREE_H */ xfsprogs-3.1.9ubuntu2/repair/dir2.c0000664000000000000000000015472312062210562014112 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "incore.h" #include "err_protos.h" #include "dinode.h" #include "dir.h" #include "dir2.h" #include "bmap.h" #include "prefetch.h" #include "progress.h" /* * Tag bad directory entries with this. * We can't tag them with -1 since that will look like a * data_unused_t instead of a data_entry_t. */ #define BADFSINO ((xfs_ino_t)0xfeffffffffffffffULL) /* * Known bad inode list. These are seen when the leaf and node * block linkages are incorrect. */ typedef struct dir2_bad { xfs_ino_t ino; struct dir2_bad *next; } dir2_bad_t; static dir2_bad_t *dir2_bad_list; static void dir2_add_badlist( xfs_ino_t ino) { dir2_bad_t *l; if ((l = malloc(sizeof(dir2_bad_t))) == NULL) { do_error( _("malloc failed (%zu bytes) dir2_add_badlist:ino %" PRIu64 "\n"), sizeof(dir2_bad_t), ino); exit(1); } l->next = dir2_bad_list; dir2_bad_list = l; l->ino = ino; } int dir2_is_badino( xfs_ino_t ino) { dir2_bad_t *l; for (l = dir2_bad_list; l; l = l->next) if (l->ino == ino) return 1; return 0; } /* * Multibuffer handling. * V2 directory blocks can be noncontiguous, needing multiple buffers. */ static xfs_dabuf_t * da_read_buf( xfs_mount_t *mp, int nex, bmap_ext_t *bmp) { xfs_buf_t *bp; xfs_buf_t *bparray[4]; xfs_buf_t **bplist; xfs_dabuf_t *dabuf; int i; int off; if (nex > (sizeof(bparray)/sizeof(xfs_buf_t *))) { bplist = calloc(nex, sizeof(*bplist)); if (bplist == NULL) { do_error(_("couldn't malloc dir2 buffer list\n")); exit(1); } } else { /* common case avoids calloc/free */ bplist = bparray; } for (i = 0; i < nex; i++) { pftrace("about to read off %llu (len = %d)", (long long)XFS_FSB_TO_DADDR(mp, bmp[i].startblock), XFS_FSB_TO_BB(mp, bmp[i].blockcount)); bplist[i] = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bmp[i].startblock), XFS_FSB_TO_BB(mp, bmp[i].blockcount), 0); if (!bplist[i]) { nex = i; goto failed; } pftrace("readbuf %p (%llu, %d)", bplist[i], (long long)XFS_BUF_ADDR(bplist[i]), XFS_BUF_COUNT(bplist[i])); } dabuf = malloc(XFS_DA_BUF_SIZE(nex)); if (dabuf == NULL) { do_error(_("couldn't malloc dir2 buffer header\n")); exit(1); } dabuf->dirty = 0; dabuf->nbuf = nex; if (nex == 1) { bp = bplist[0]; dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); dabuf->data = XFS_BUF_PTR(bp); dabuf->bps[0] = bp; } else { for (i = 0, dabuf->bbcount = 0; i < nex; i++) { dabuf->bps[i] = bp = bplist[i]; dabuf->bbcount += BTOBB(XFS_BUF_COUNT(bp)); } dabuf->data = malloc(BBTOB(dabuf->bbcount)); if (dabuf->data == NULL) { do_error(_("couldn't malloc dir2 buffer data\n")); exit(1); } for (i = off = 0; i < nex; i++, off += XFS_BUF_COUNT(bp)) { bp = bplist[i]; memmove((char *)dabuf->data + off, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp)); } } if (bplist != bparray) free(bplist); return dabuf; failed: for (i = 0; i < nex; i++) libxfs_putbuf(bplist[i]); if (bplist != bparray) free(bplist); return NULL; } static void da_buf_clean( xfs_dabuf_t *dabuf) { xfs_buf_t *bp; int i; int off; if (dabuf->dirty) { dabuf->dirty = 0; for (i=off=0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = dabuf->bps[i]; memmove(XFS_BUF_PTR(bp), (char *)dabuf->data + off, XFS_BUF_COUNT(bp)); } } } static void da_buf_done( xfs_dabuf_t *dabuf) { da_buf_clean(dabuf); if (dabuf->nbuf > 1) free(dabuf->data); free(dabuf); } static int da_bwrite( xfs_mount_t *mp, xfs_dabuf_t *dabuf) { xfs_buf_t *bp; xfs_buf_t **bplist; int e; int error; int i; int nbuf; int off; if ((nbuf = dabuf->nbuf) == 1) { bplist = &bp; bp = dabuf->bps[0]; } else { bplist = malloc(nbuf * sizeof(*bplist)); if (bplist == NULL) { do_error(_("couldn't malloc dir2 buffer list\n")); exit(1); } memmove(bplist, dabuf->bps, nbuf * sizeof(*bplist)); for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = bplist[i]; memmove(XFS_BUF_PTR(bp), (char *)dabuf->data + off, XFS_BUF_COUNT(bp)); } } da_buf_done(dabuf); for (i = error = 0; i < nbuf; i++) { e = libxfs_writebuf(bplist[i], 0); if (e) error = e; } if (bplist != &bp) free(bplist); return error; } static void da_brelse( xfs_dabuf_t *dabuf) { xfs_buf_t *bp; xfs_buf_t **bplist; int i; int nbuf; if ((nbuf = dabuf->nbuf) == 1) { bplist = &bp; bp = dabuf->bps[0]; } else { bplist = malloc(nbuf * sizeof(*bplist)); if (bplist == NULL) { do_error(_("couldn't malloc dir2 buffer list\n")); exit(1); } memmove(bplist, dabuf->bps, nbuf * sizeof(*bplist)); } da_buf_done(dabuf); for (i = 0; i < nbuf; i++) { pftrace("putbuf %p (%llu)", bplist[i], (long long)XFS_BUF_ADDR(bplist[i])); libxfs_putbuf(bplist[i]); } if (bplist != &bp) free(bplist); } /* * walk tree from root to the left-most leaf block reading in * blocks and setting up cursor. passes back file block number of the * left-most leaf block if successful (bno). returns 1 if successful, * 0 if unsuccessful. */ static int traverse_int_dir2block(xfs_mount_t *mp, dir2_bt_cursor_t *da_cursor, xfs_dablk_t *rbno) { bmap_ext_t *bmp; xfs_dablk_t bno; xfs_dabuf_t *bp; int i; int nex; xfs_da_blkinfo_t *info; xfs_da_intnode_t *node; bmap_ext_t lbmp; /* * traverse down left-side of tree until we hit the * left-most leaf block setting up the btree cursor along * the way. */ bno = mp->m_dirleafblk; i = -1; info = NULL; da_cursor->active = 0; do { /* * read in each block along the way and set up cursor */ nex = blkmap_getn(da_cursor->blkmap, bno, mp->m_dirblkfsbs, &bmp, &lbmp); if (nex == 0) goto error_out; bp = da_read_buf(mp, nex, bmp); if (bmp != &lbmp) free(bmp); if (bp == NULL) { do_warn( _("can't read block %u for directory inode %" PRIu64 "\n"), bno, da_cursor->ino); goto error_out; } info = bp->data; if (be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC) { if ( i != -1 ) { do_warn( _("found non-root LEAFN node in inode %" PRIu64 " bno = %u\n"), da_cursor->ino, bno); } *rbno = 0; da_brelse(bp); return(1); } else if (be16_to_cpu(info->magic) != XFS_DA_NODE_MAGIC) { da_brelse(bp); do_warn( _("bad dir magic number 0x%x in inode %" PRIu64 " bno = %u\n"), be16_to_cpu(info->magic), da_cursor->ino, bno); goto error_out; } node = (xfs_da_intnode_t*)info; if (be16_to_cpu(node->hdr.count) > mp->m_dir_node_ents) { da_brelse(bp); do_warn( _("bad record count in inode %" PRIu64 ", count = %d, max = %d\n"), da_cursor->ino, be16_to_cpu(node->hdr.count), mp->m_dir_node_ents); goto error_out; } /* * maintain level counter */ if (i == -1) { i = da_cursor->active = be16_to_cpu(node->hdr.level); if (i >= XFS_DA_NODE_MAXDEPTH) { do_warn( _("bad header depth for directory inode %" PRIu64 "\n"), da_cursor->ino); da_brelse(bp); i = -1; goto error_out; } } else { if (be16_to_cpu(node->hdr.level) == i - 1) { i--; } else { do_warn( _("bad directory btree for directory inode %" PRIu64 "\n"), da_cursor->ino); da_brelse(bp); goto error_out; } } da_cursor->level[i].hashval = be32_to_cpu(node->btree[0].hashval); da_cursor->level[i].bp = bp; da_cursor->level[i].bno = bno; da_cursor->level[i].index = 0; /* * set up new bno for next level down */ bno = be32_to_cpu(node->btree[0].before); } while (info != NULL && i > 1); /* * now return block number and get out */ *rbno = da_cursor->level[0].bno = bno; return(1); error_out: while (i > 1 && i <= da_cursor->active) { da_brelse(da_cursor->level[i].bp); i++; } return(0); } /* * blow out buffer for this level and all the rest above as well * if error == 0, we are not expecting to encounter any unreleased * buffers (e.g. if we do, it's a mistake). if error == 1, we're * in an error-handling case so unreleased buffers may exist. */ static void release_dir2_cursor_int(xfs_mount_t *mp, dir2_bt_cursor_t *cursor, int prev_level, int error) { int level = prev_level + 1; if (cursor->level[level].bp != NULL) { if (!error) { do_warn(_("release_dir2_cursor_int got unexpected " "non-null bp, dabno = %u\n"), cursor->level[level].bno); } ASSERT(error != 0); da_brelse(cursor->level[level].bp); cursor->level[level].bp = NULL; } if (level < cursor->active) release_dir2_cursor_int(mp, cursor, level, error); return; } static void release_dir2_cursor(xfs_mount_t *mp, dir2_bt_cursor_t *cursor, int prev_level) { release_dir2_cursor_int(mp, cursor, prev_level, 0); } static void err_release_dir2_cursor(xfs_mount_t *mp, dir2_bt_cursor_t *cursor, int prev_level) { release_dir2_cursor_int(mp, cursor, prev_level, 1); } /* * make sure that all entries in all blocks along the right side of * of the tree are used and hashval's are consistent. level is the * level of the descendent block. returns 0 if good (even if it had * to be fixed up), and 1 if bad. The right edge of the tree is * technically a block boundary. This routine should be used then * instead of verify_dir2_path(). */ static int verify_final_dir2_path(xfs_mount_t *mp, dir2_bt_cursor_t *cursor, const int p_level) { xfs_da_intnode_t *node; int bad = 0; int entry; int this_level = p_level + 1; /* * the index should point to the next "unprocessed" entry * in the block which should be the final (rightmost) entry */ entry = cursor->level[this_level].index; node = (xfs_da_intnode_t *)(cursor->level[this_level].bp->data); /* * check internal block consistency on this level -- ensure * that all entries are used, encountered and expected hashvals * match, etc. */ if (entry != be16_to_cpu(node->hdr.count) - 1) { do_warn( _("directory block used/count inconsistency - %d / %hu\n"), entry, be16_to_cpu(node->hdr.count)); bad++; } /* * hash values monotonically increasing ??? */ if (cursor->level[this_level].hashval >= be32_to_cpu(node->btree[entry].hashval)) { do_warn(_("directory/attribute block hashvalue inconsistency, " "expected > %u / saw %u\n"), cursor->level[this_level].hashval, be32_to_cpu(node->btree[entry].hashval)); bad++; } if (be32_to_cpu(node->hdr.info.forw) != 0) { do_warn(_("bad directory/attribute forward block pointer, " "expected 0, saw %u\n"), be32_to_cpu(node->hdr.info.forw)); bad++; } if (bad) { do_warn(_("bad directory block in inode %" PRIu64 "\n"), cursor->ino); return(1); } /* * keep track of greatest block # -- that gets * us the length of the directory */ if (cursor->level[this_level].bno > cursor->greatest_bno) cursor->greatest_bno = cursor->level[this_level].bno; /* * ok, now check descendant block number against this level */ if (cursor->level[p_level].bno != be32_to_cpu(node->btree[entry].before)) return(1); if (cursor->level[p_level].hashval != be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn( _("correcting bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); node->btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn( _("would correct bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); } } /* * release/write buffer */ ASSERT(cursor->level[this_level].dirty == 0 || (cursor->level[this_level].dirty && !no_modify)); if (cursor->level[this_level].dirty && !no_modify) da_bwrite(mp, cursor->level[this_level].bp); else da_brelse(cursor->level[this_level].bp); cursor->level[this_level].bp = NULL; /* * bail out if this is the root block (top of tree) */ if (this_level >= cursor->active) return(0); /* * set hashvalue to correctl reflect the now-validated * last entry in this block and continue upwards validation */ cursor->level[this_level].hashval = be32_to_cpu(node->btree[entry].hashval); return(verify_final_dir2_path(mp, cursor, this_level)); } /* * Verifies the path from a descendant block up to the root. * Should be called when the descendant level traversal hits * a block boundary before crossing the boundary (reading in a new * block). * * the directory/attr btrees work differently to the other fs btrees. * each interior block contains records that are * pairs. The bno is a file bno, not a filesystem bno. The last * hashvalue in the block will be . BUT unlike * the freespace btrees, the *last* value in each block gets * propagated up the tree instead of the first value in each block. * that is, the interior records point to child blocks and the *greatest* * hash value contained by the child block is the one the block above * uses as the key for the child block. * * level is the level of the descendent block. returns 0 if good, * and 1 if bad. The descendant block may be a leaf block. * * the invariant here is that the values in the cursor for the * levels beneath this level (this_level) and the cursor index * for this level *must* be valid. * * that is, the hashval/bno info is accurate for all * DESCENDANTS and match what the node[index] information * for the current index in the cursor for this level. * * the index values in the cursor for the descendant level * are allowed to be off by one as they will reflect the * next entry at those levels to be processed. * * the hashvalue for the current level can't be set until * we hit the last entry in the block so, it's garbage * until set by this routine. * * bno and bp for the current block/level are always valid * since they have to be set so we can get a buffer for the * block. */ static int verify_dir2_path(xfs_mount_t *mp, dir2_bt_cursor_t *cursor, const int p_level) { xfs_da_intnode_t *node; xfs_da_intnode_t *newnode; xfs_dablk_t dabno; xfs_dabuf_t *bp; int bad; int entry; int this_level = p_level + 1; bmap_ext_t *bmp; int nex; bmap_ext_t lbmp; /* * index is currently set to point to the entry that * should be processed now in this level. */ entry = cursor->level[this_level].index; node = cursor->level[this_level].bp->data; /* * if this block is out of entries, validate this * block and move on to the next block. * and update cursor value for said level */ if (entry >= be16_to_cpu(node->hdr.count)) { /* * update the hash value for this level before * validating it. bno value should be ok since * it was set when the block was first read in. */ cursor->level[this_level].hashval = be32_to_cpu(node->btree[entry - 1].hashval); /* * keep track of greatest block # -- that gets * us the length of the directory */ if (cursor->level[this_level].bno > cursor->greatest_bno) cursor->greatest_bno = cursor->level[this_level].bno; /* * validate the path for the current used-up block * before we trash it */ if (verify_dir2_path(mp, cursor, this_level)) return(1); /* * ok, now get the next buffer and check sibling pointers */ dabno = be32_to_cpu(node->hdr.info.forw); ASSERT(dabno != 0); nex = blkmap_getn(cursor->blkmap, dabno, mp->m_dirblkfsbs, &bmp, &lbmp); if (nex == 0) { do_warn( _("can't get map info for block %u of directory inode %" PRIu64 "\n"), dabno, cursor->ino); return(1); } bp = da_read_buf(mp, nex, bmp); if (bmp != &lbmp) free(bmp); if (bp == NULL) { do_warn( _("can't read block %u for directory inode %" PRIu64 "\n"), dabno, cursor->ino); return(1); } newnode = bp->data; /* * verify magic number and back pointer, sanity-check * entry count, verify level */ bad = 0; if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { do_warn( _("bad magic number %x in block %u for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.info.magic), dabno, cursor->ino); bad++; } if (be32_to_cpu(newnode->hdr.info.back) != cursor->level[this_level].bno) { do_warn( _("bad back pointer in block %u for directory inode %" PRIu64 "\n"), dabno, cursor->ino); bad++; } if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { do_warn( _("entry count %d too large in block %u for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.count), dabno, cursor->ino); bad++; } if (be16_to_cpu(newnode->hdr.level) != this_level) { do_warn( _("bad level %d in block %u for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.level), dabno, cursor->ino); bad++; } if (bad) { da_brelse(bp); return(1); } /* * update cursor, write out the *current* level if * required. don't write out the descendant level */ ASSERT(cursor->level[this_level].dirty == 0 || (cursor->level[this_level].dirty && !no_modify)); if (cursor->level[this_level].dirty && !no_modify) da_bwrite(mp, cursor->level[this_level].bp); else da_brelse(cursor->level[this_level].bp); cursor->level[this_level].bp = bp; cursor->level[this_level].dirty = 0; cursor->level[this_level].bno = dabno; cursor->level[this_level].hashval = be32_to_cpu(newnode->btree[0].hashval); node = newnode; entry = cursor->level[this_level].index = 0; } /* * ditto for block numbers */ if (cursor->level[p_level].bno != be32_to_cpu(node->btree[entry].before)) return(1); /* * ok, now validate last hashvalue in the descendant * block against the hashval in the current entry */ if (cursor->level[p_level].hashval != be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn( _("correcting bad hashval in interior dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); node->btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn( _("would correct bad hashval in interior dir block\n" "\tin (level %d) in inode %" PRIu64 ".\n"), this_level, cursor->ino); } } /* * increment index for this level to point to next entry * (which should point to the next descendant block) */ cursor->level[this_level].index++; return(0); } /* * Fix up a shortform directory which was in long form (i8count set) * and is now in short form (i8count clear). * Return pointer to the end of the data when done. */ void process_sf_dir2_fixi8( xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t **next_sfep) { xfs_ino_t ino; xfs_dir2_sf_t *newsfp; xfs_dir2_sf_entry_t *newsfep; xfs_dir2_sf_t *oldsfp; xfs_dir2_sf_entry_t *oldsfep; int oldsize; newsfp = sfp; oldsize = (__psint_t)*next_sfep - (__psint_t)sfp; oldsfp = malloc(oldsize); if (oldsfp == NULL) { do_error(_("couldn't malloc dir2 shortform copy\n")); exit(1); } memmove(oldsfp, newsfp, oldsize); newsfp->hdr.count = oldsfp->hdr.count; newsfp->hdr.i8count = 0; ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); xfs_dir2_sf_put_inumber(newsfp, &ino, &newsfp->hdr.parent); oldsfep = xfs_dir2_sf_firstentry(oldsfp); newsfep = xfs_dir2_sf_firstentry(newsfp); while ((int)((char *)oldsfep - (char *)oldsfp) < oldsize) { newsfep->namelen = oldsfep->namelen; xfs_dir2_sf_put_offset(newsfep, xfs_dir2_sf_get_offset(oldsfep)); memmove(newsfep->name, oldsfep->name, newsfep->namelen); ino = xfs_dir2_sf_get_inumber(oldsfp, xfs_dir2_sf_inumberp(oldsfep)); xfs_dir2_sf_put_inumber(newsfp, &ino, xfs_dir2_sf_inumberp(newsfep)); oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep); newsfep = xfs_dir2_sf_nextentry(newsfp, newsfep); } *next_sfep = newsfep; free(oldsfp); } /* * Regenerate legal (minimal) offsets for the shortform directory. */ static void process_sf_dir2_fixoff( xfs_dinode_t *dip) { int i; int offset; xfs_dir2_sf_entry_t *sfep; xfs_dir2_sf_t *sfp; sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); sfep = xfs_dir2_sf_firstentry(sfp); offset = XFS_DIR2_DATA_FIRST_OFFSET; for (i = 0; i < sfp->hdr.count; i++) { xfs_dir2_sf_put_offset(sfep, offset); offset += xfs_dir2_data_entsize(sfep->namelen); sfep = xfs_dir2_sf_nextentry(sfp, sfep); } } /* * this routine performs inode discovery and tries to fix things * in place. available redundancy -- inode data size should match * used directory space in inode. * a non-zero return value means the directory is bogus and should be blasted. */ /* ARGSUSED */ static int process_sf_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, /* out - 1 if dinode buffer dirty */ char *dirname, /* directory pathname */ xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */ int *repair) /* out - 1 if dir was fixed up */ { int bad_offset; int bad_sfnamelen; int i; int i8; __int64_t ino_dir_size; int ino_off; ino_tree_node_t *irec_p; int junkit; char *junkreason = NULL; xfs_ino_t lino; int max_size; char name[MAXNAMELEN + 1]; int namelen; xfs_dir2_sf_entry_t *next_sfep; int num_entries; int offset; xfs_dir2_sf_t *sfp; xfs_dir2_sf_entry_t *sfep; int tmp_elen; int tmp_len; xfs_dir2_sf_entry_t *tmp_sfep; xfs_ino_t zero = 0; sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); max_size = XFS_DFORK_DSIZE(dip, mp); num_entries = sfp->hdr.count; ino_dir_size = be64_to_cpu(dip->di_size); offset = XFS_DIR2_DATA_FIRST_OFFSET; bad_offset = *repair = 0; ASSERT(ino_dir_size <= max_size); /* * Initialize i8 based on size of parent inode number. */ i8 = (xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent) > XFS_DIR2_MAX_SHORT_INUM); /* * check for bad entry count */ if (num_entries * xfs_dir2_sf_entsize_byname(sfp, 1) + xfs_dir2_sf_hdr_size(0) > max_size || num_entries == 0) num_entries = 0xFF; /* * run through entries, stop at first bad entry, don't need * to check for .. since that's encoded in its own field */ sfep = next_sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; i < num_entries && ino_dir_size > (char *)next_sfep - (char *)sfp; i++) { tmp_sfep = NULL; sfep = next_sfep; junkit = 0; bad_sfnamelen = 0; lino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); /* * if entry points to self, junk it since only '.' or '..' * should do that and shortform dirs don't contain either * entry. if inode number is invalid, trash entry. * if entry points to special inodes, trash it. * if inode is unknown but number is valid, * add it to the list of uncertain inodes. don't * have to worry about an entry pointing to a * deleted lost+found inode because the entry was * deleted at the same time that the inode was cleared. */ if (lino == ino) { junkit = 1; junkreason = _("current"); } else if (verify_inum(mp, lino)) { junkit = 1; junkreason = _("invalid"); } else if (lino == mp->m_sb.sb_rbmino) { junkit = 1; junkreason = _("realtime bitmap"); } else if (lino == mp->m_sb.sb_rsumino) { junkit = 1; junkreason = _("realtime summary"); } else if (lino == mp->m_sb.sb_uquotino) { junkit = 1; junkreason = _("user quota"); } else if (lino == mp->m_sb.sb_gquotino) { junkit = 1; junkreason = _("group quota"); } else if ((irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino))) != NULL) { /* * if inode is marked free and we're in inode * discovery mode, leave the entry alone for now. * if the inode turns out to be used, we'll figure * that out when we scan it. If the inode really * is free, we'll hit this code again in phase 4 * after we've finished inode discovery and blow * out the entry then. */ ino_off = XFS_INO_TO_AGINO(mp, lino) - irec_p->ino_startnum; ASSERT(is_inode_confirmed(irec_p, ino_off)); if (is_inode_free(irec_p, ino_off) && !ino_discovery) { junkit = 1; junkreason = _("free"); } } else if (ino_discovery) { /* * put the inode on the uncertain list. we'll * pull the inode off the list and check it later. * if the inode turns out be bogus, we'll delete * this entry in phase 6. */ add_inode_uncertain(mp, lino, 0); } else { /* * blow the entry out. we know about all * undiscovered entries now (past inode discovery * phase) so this is clearly a bogus entry. */ junkit = 1; junkreason = _("non-existent"); } namelen = sfep->namelen; if (junkit) do_warn( _("entry \"%*.*s\" in shortform directory %" PRIu64 " references %s inode %" PRIu64 "\n"), namelen, namelen, sfep->name, ino, junkreason, lino); if (namelen == 0) { /* * if we're really lucky, this is * the last entry in which case we * can use the dir size to set the * namelen value. otherwise, forget * it because we're not going to be * able to find the next entry. */ bad_sfnamelen = 1; if (i == num_entries - 1) { namelen = ino_dir_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); if (!no_modify) { do_warn( _("zero length entry in shortform dir %" PRIu64 ", resetting to %d\n"), ino, namelen); sfep->namelen = namelen; } else { do_warn( _("zero length entry in shortform dir %" PRIu64 ", would set to %d\n"), ino, namelen); } } else { do_warn( _("zero length entry in shortform dir %" PRIu64 ""), ino); if (!no_modify) do_warn(_(", junking %d entries\n"), num_entries - i); else do_warn(_(", would junk %d entries\n"), num_entries - i); /* * don't process the rest of the directory, * break out of processing looop */ break; } } else if ((__psint_t) sfep - (__psint_t) sfp + xfs_dir2_sf_entsize_byentry(sfp, sfep) > ino_dir_size) { bad_sfnamelen = 1; if (i == num_entries - 1) { namelen = ino_dir_size - ((__psint_t) &sfep->name[0] - (__psint_t) sfp); do_warn( _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "), ino); if (!no_modify) { do_warn(_("resetting to %d\n"), namelen); sfep->namelen = namelen; *dino_dirty = 1; } else { do_warn(_("would reset to %d\n"), namelen); } } else { do_warn( _("size of entry #%d overflows space left in in shortform dir %" PRIu64 "\n"), i, ino); if (!no_modify) { if (i == num_entries - 1) do_warn( _("junking entry #%d\n"), i); else do_warn( _("junking %d entries\n"), num_entries - i); } else { if (i == num_entries - 1) do_warn( _("would junk entry #%d\n"), i); else do_warn( _("would junk %d entries\n"), num_entries - i); } break; } } /* * check for illegal chars in name. * no need to check for bad length because * the length value is stored in a byte * so it can't be too big, it can only wrap */ if (namecheck((char *)&sfep->name[0], namelen)) { /* * junk entry */ do_warn( _("entry contains illegal character in shortform dir %" PRIu64 "\n"), ino); junkit = 1; } if (xfs_dir2_sf_get_offset(sfep) < offset) { do_warn( _("entry contains offset out of order in shortform dir %" PRIu64 "\n"), ino); bad_offset = 1; } offset = xfs_dir2_sf_get_offset(sfep) + xfs_dir2_data_entsize(namelen); /* * junk the entry by copying up the rest of the * fork over the current entry and decrementing * the entry count. if we're in no_modify mode, * just issue the warning instead. then continue * the loop with the next_sfep pointer set to the * correct place in the fork and other counters * properly set to reflect the deletion if it * happened. */ if (junkit) { memmove(name, sfep->name, namelen); name[namelen] = '\0'; if (!no_modify) { tmp_elen = xfs_dir2_sf_entsize_byentry(sfp, sfep); be64_add_cpu(&dip->di_size, -tmp_elen); ino_dir_size -= tmp_elen; tmp_sfep = (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfep - (__psint_t) sfp); memmove(sfep, tmp_sfep, tmp_len); sfp->hdr.count -= 1; num_entries--; memset((void *) ((__psint_t) sfep + tmp_len), 0, tmp_elen); /* * reset the tmp value to the current * pointer so we'll process the entry * we just moved up */ tmp_sfep = sfep; /* * WARNING: drop the index i by one * so it matches the decremented count * for accurate comparisons later */ i--; *dino_dirty = 1; *repair = 1; do_warn( _("junking entry \"%s\" in directory inode %" PRIu64 "\n"), name, ino); } else { do_warn( _("would have junked entry \"%s\" in directory inode %" PRIu64 "\n"), name, ino); } } else if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; /* * go onto next entry unless we've just junked an * entry in which the current entry pointer points * to an unprocessed entry. have to take into zero-len * entries into account in no modify mode since we * calculate size based on next_sfep. */ next_sfep = (tmp_sfep == NULL) ? (xfs_dir2_sf_entry_t *) ((__psint_t) sfep + ((!bad_sfnamelen) ? xfs_dir2_sf_entsize_byentry(sfp, sfep) : xfs_dir2_sf_entsize_byname(sfp, namelen))) : tmp_sfep; } /* sync up sizes and entry counts */ if (sfp->hdr.count != i) { if (no_modify) { do_warn( _("would have corrected entry count in directory %" PRIu64 " from %d to %d\n"), ino, sfp->hdr.count, i); } else { do_warn( _("corrected entry count in directory %" PRIu64 ", was %d, now %d\n"), ino, sfp->hdr.count, i); sfp->hdr.count = i; *dino_dirty = 1; *repair = 1; } } if (sfp->hdr.i8count != i8) { if (no_modify) { do_warn( _("would have corrected i8 count in directory %" PRIu64 " from %d to %d\n"), ino, sfp->hdr.i8count, i8); } else { do_warn( _("corrected i8 count in directory %" PRIu64 ", was %d, now %d\n"), ino, sfp->hdr.i8count, i8); if (i8 == 0) process_sf_dir2_fixi8(sfp, &next_sfep); else sfp->hdr.i8count = i8; *dino_dirty = 1; *repair = 1; } } if ((intptr_t)next_sfep - (intptr_t)sfp != ino_dir_size) { if (no_modify) { do_warn( _("would have corrected directory %" PRIu64 " size from %" PRId64 " to %" PRIdPTR "\n"), ino, ino_dir_size, (intptr_t)next_sfep - (intptr_t)sfp); } else { do_warn( _("corrected directory %" PRIu64 " size, was %" PRId64 ", now %" PRIdPTR "\n"), ino, ino_dir_size, (intptr_t)next_sfep - (intptr_t)sfp); dip->di_size = cpu_to_be64( (__psint_t)next_sfep - (__psint_t)sfp); *dino_dirty = 1; *repair = 1; } } if (offset + (sfp->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { do_warn(_("directory %" PRIu64 " offsets too high\n"), ino); bad_offset = 1; } if (bad_offset) { if (no_modify) { do_warn( _("would have corrected entry offsets in directory %" PRIu64 "\n"), ino); } else { do_warn( _("corrected entry offsets in directory %" PRIu64 "\n"), ino); process_sf_dir2_fixoff(dip); *dino_dirty = 1; *repair = 1; } } /* * check parent (..) entry */ *parent = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); /* * if parent entry is bogus, null it out. we'll fix it later . */ if (verify_inum(mp, *parent)) { do_warn( _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "), *parent, ino); *parent = NULLFSINO; if (!no_modify) { do_warn(_("clearing inode number\n")); xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn(_("would clear inode number\n")); } } else if (ino == mp->m_sb.sb_rootino && ino != *parent) { /* * root directories must have .. == . */ if (!no_modify) { do_warn( _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 "\n"), ino, *parent, ino); *parent = ino; xfs_dir2_sf_put_inumber(sfp, parent, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn( _("would have corrected root directory %" PRIu64 " .. entry from %" PRIu64" to %" PRIu64 "\n"), ino, *parent, ino); } } else if (ino == *parent && ino != mp->m_sb.sb_rootino) { /* * likewise, non-root directories can't have .. pointing * to . */ *parent = NULLFSINO; do_warn( _("bad .. entry in directory inode %" PRIu64 ", points to self, "), ino); if (!no_modify) { do_warn(_("clearing inode number\n")); xfs_dir2_sf_put_inumber(sfp, &zero, &sfp->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn(_("would clear inode number\n")); } } return(0); } /* * Process one directory data block. */ /* ARGSUSED */ static int process_dir2_data( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, char *dirname, /* directory pathname */ xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */ xfs_dabuf_t *bp, int *dot, /* out - 1 if there is a dot, else 0 */ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ xfs_dablk_t da_bno, char *endptr) { int badbest; xfs_dir2_data_free_t *bf; int clearino; char *clearreason = NULL; xfs_dir2_data_t *d; xfs_dir2_data_entry_t *dep; xfs_dir2_data_free_t *dfp; xfs_dir2_data_unused_t *dup; int freeseen; int i; int ino_off; ino_tree_node_t *irec_p; int junkit; int lastfree; int nm_illegal; char *ptr; xfs_ino_t ent_ino; d = bp->data; bf = d->hdr.bestfree; ptr = (char *)d->u; badbest = lastfree = freeseen = 0; if (be16_to_cpu(bf[0].length) == 0) { badbest |= be16_to_cpu(bf[0].offset) != 0; freeseen |= 1 << 0; } if (be16_to_cpu(bf[1].length) == 0) { badbest |= be16_to_cpu(bf[1].offset) != 0; freeseen |= 1 << 1; } if (be16_to_cpu(bf[2].length) == 0) { badbest |= be16_to_cpu(bf[2].offset) != 0; freeseen |= 1 << 2; } badbest |= be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length); badbest |= be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length); while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; /* * If it's unused, look for the space in the bestfree table. * If we find it, account for that, else make sure it doesn't * need to be there. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (ptr + be16_to_cpu(dup->length) > endptr || be16_to_cpu(dup->length) == 0 || (be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1))) break; if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != (char *)dup - (char *)d) break; badbest |= lastfree != 0; dfp = xfs_dir2_data_freefind(d, dup); if (dfp) { i = dfp - bf; badbest |= (freeseen & (1 << i)) != 0; freeseen |= 1 << i; } else badbest |= be16_to_cpu(dup->length) > be16_to_cpu(bf[2].length); ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } dep = (xfs_dir2_data_entry_t *)ptr; if (ptr + xfs_dir2_data_entsize(dep->namelen) > endptr) break; if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != (char *)dep - (char *)d) break; ptr += xfs_dir2_data_entsize(dep->namelen); lastfree = 0; } /* * Dropped out before we processed everything, give up. * Phase 6 will kill this block if we don't kill the inode. */ if (ptr != endptr) { do_warn(_("corrupt block %u in directory inode %" PRIu64 "\n"), da_bno, ino); if (!no_modify) do_warn(_("\twill junk block\n")); else do_warn(_("\twould junk block\n")); return 1; } ptr = (char *)d->u; /* * Process the entries now. */ while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ptr += be16_to_cpu(dup->length); continue; } dep = (xfs_dir2_data_entry_t *)ptr; ent_ino = be64_to_cpu(dep->inumber); clearino = 1; clearreason = NULL; /* * We may have to blow out an entry because of bad inode * numbers. Do NOT touch the name until after we've computed * the hashvalue and done a namecheck() on the name. * * Conditions must either set clearino to zero or set * clearreason why it's being cleared. */ if (!ino_discovery && ent_ino == BADFSINO) { /* * Don't do a damned thing. We already found this * (or did it ourselves) during phase 3. */ clearino = 0; } else if (verify_inum(mp, ent_ino)) { /* * Bad inode number. Clear the inode number and the * entry will get removed later. We don't trash the * directory since it's still structurally intact. */ clearreason = _("invalid"); } else if (ent_ino == mp->m_sb.sb_rbmino) { clearreason = _("realtime bitmap"); } else if (ent_ino == mp->m_sb.sb_rsumino) { clearreason = _("realtime summary"); } else if (ent_ino == mp->m_sb.sb_uquotino) { clearreason = _("user quota"); } else if (ent_ino == mp->m_sb.sb_gquotino) { clearreason = _("group quota"); } else { irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ent_ino), XFS_INO_TO_AGINO(mp, ent_ino)); if (irec_p == NULL) { if (ino_discovery) { add_inode_uncertain(mp, ent_ino, 0); clearino = 0; } else clearreason = _("non-existent"); } else { /* * Inode recs should have only confirmed * inodes in them. */ ino_off = XFS_INO_TO_AGINO(mp, ent_ino) - irec_p->ino_startnum; ASSERT(is_inode_confirmed(irec_p, ino_off)); /* * If inode is marked free and we're in inode * discovery mode, leave the entry alone for * now. If the inode turns out to be used, * we'll figure that out when we scan it. * If the inode really is free, we'll hit this * code again in phase 4 after we've finished * inode discovery and blow out the entry then. */ if (!ino_discovery && is_inode_free(irec_p, ino_off)) clearreason = _("free"); else clearino = 0; } } ASSERT((clearino == 0 && clearreason == NULL) || (clearino != 0 && clearreason != NULL)); if (clearino) do_warn( _("entry \"%*.*s\" at block %d offset %" PRIdPTR " in directory inode %" PRIu64 " references %s inode %" PRIu64 "\n"), dep->namelen, dep->namelen, dep->name, da_bno, (intptr_t)ptr - (intptr_t)d, ino, clearreason, ent_ino); /* * If the name length is 0 (illegal) make it 1 and blast * the entry. */ if (dep->namelen == 0) { do_warn( _("entry at block %u offset %" PRIdPTR " in directory inode %" PRIu64 "has 0 namelength\n"), da_bno, (intptr_t)ptr - (intptr_t)d, ino); if (!no_modify) dep->namelen = 1; clearino = 1; } /* * If needed to clear the inode number, do it now. */ if (clearino) { if (!no_modify) { do_warn( _("\tclearing inode number in entry at offset %" PRIdPTR "...\n"), (intptr_t)ptr - (intptr_t)d); dep->inumber = cpu_to_be64(BADFSINO); ent_ino = BADFSINO; bp->dirty = 1; } else { do_warn( _("\twould clear inode number in entry at offset %" PRIdPTR "...\n"), (intptr_t)ptr - (intptr_t)d); } } /* * Only complain about illegal names in phase 3 (when inode * discovery is turned on). Otherwise, we'd complain a lot * during phase 4. */ junkit = ent_ino == BADFSINO; nm_illegal = namecheck((char *)dep->name, dep->namelen); if (ino_discovery && nm_illegal) { do_warn( _("entry at block %u offset %" PRIdPTR " in directory inode %" PRIu64 " has illegal name \"%*.*s\": "), da_bno, (intptr_t)ptr - (intptr_t)d, ino, dep->namelen, dep->namelen, dep->name); junkit = 1; } /* * Now we can mark entries with BADFSINO's bad. */ if (!no_modify && ent_ino == BADFSINO) { dep->name[0] = '/'; bp->dirty = 1; junkit = 0; } /* * Special .. entry processing. */ if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') { if (!*dotdot) { (*dotdot)++; *parent = ent_ino; /* * What if .. == .? Legal only in the root * inode. Blow out entry and set parent to * NULLFSINO otherwise. */ if (ino == ent_ino && ino != mp->m_sb.sb_rootino) { *parent = NULLFSINO; do_warn( _("bad .. entry in directory inode %" PRIu64 ", points to self: "), ino); junkit = 1; } /* * We have to make sure that . == .. in the * root inode. */ else if (ino != ent_ino && ino == mp->m_sb.sb_rootino) { do_warn( _("bad .. entry in root directory inode %" PRIu64 ", was %" PRIu64 ": "), ino, ent_ino); if (!no_modify) { do_warn(_("correcting\n")); dep->inumber = cpu_to_be64(ino); bp->dirty = 1; } else { do_warn(_("would correct\n")); } } } /* * Can't fix the directory unless we know which .. * entry is the right one. Both have valid inode * numbers or we wouldn't be here. So since both * seem equally valid, trash this one. */ else { do_warn( _("multiple .. entries in directory inode %" PRIu64 ": "), ino); junkit = 1; } } /* * Special . entry processing. */ else if (dep->namelen == 1 && dep->name[0] == '.') { if (!*dot) { (*dot)++; if (ent_ino != ino) { do_warn( _("bad . entry in directory inode %" PRIu64 ", was %" PRIu64 ": "), ino, ent_ino); if (!no_modify) { do_warn(_("correcting\n")); dep->inumber = cpu_to_be64(ino); bp->dirty = 1; } else { do_warn(_("would correct\n")); } } } else { do_warn( _("multiple . entries in directory inode %" PRIu64 ": "), ino); junkit = 1; } } /* * All other entries -- make sure only . references self. */ else if (ent_ino == ino) { do_warn( _("entry \"%*.*s\" in directory inode %" PRIu64 " points to self: "), dep->namelen, dep->namelen, dep->name, ino); junkit = 1; } /* * Clear junked entries. */ if (junkit) { if (!no_modify) { dep->name[0] = '/'; bp->dirty = 1; do_warn(_("clearing entry\n")); } else { do_warn(_("would clear entry\n")); } } /* * Advance to the next entry. */ ptr += xfs_dir2_data_entsize(dep->namelen); } /* * Check the bestfree table. */ if (freeseen != 7 || badbest) { do_warn( _("bad bestfree table in block %u in directory inode %" PRIu64 ": "), da_bno, ino); if (!no_modify) { do_warn(_("repairing table\n")); libxfs_dir2_data_freescan(mp, d, &i); bp->dirty = 1; } else { do_warn(_("would repair table\n")); } } return 0; } /* * Process a block-format directory. */ /* ARGSUSED */ static int process_block_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, /* out - 1 if dinode buffer dirty */ char *dirname, /* directory pathname */ xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */ blkmap_t *blkmap, int *dot, /* out - 1 if there is a dot, else 0 */ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ int *repair) /* out - 1 if something was fixed */ { xfs_dir2_block_t *block; xfs_dir2_leaf_entry_t *blp; bmap_ext_t *bmp; xfs_dabuf_t *bp; xfs_dir2_block_tail_t *btp; int nex; int rval; bmap_ext_t lbmp; *repair = *dot = *dotdot = 0; *parent = NULLFSINO; nex = blkmap_getn(blkmap, mp->m_dirdatablk, mp->m_dirblkfsbs, &bmp, &lbmp); if (nex == 0) { do_warn( _("block %u for directory inode %" PRIu64 " is missing\n"), mp->m_dirdatablk, ino); return 1; } bp = da_read_buf(mp, nex, bmp); if (bmp != &lbmp) free(bmp); if (bp == NULL) { do_warn( _("can't read block %u for directory inode %" PRIu64 "\n"), mp->m_dirdatablk, ino); return 1; } /* * Verify the block */ block = bp->data; if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) do_warn( _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 "\n"), be32_to_cpu(block->hdr.magic), mp->m_dirdatablk, ino); /* * process the data area * this also checks & fixes the bestfree */ btp = xfs_dir2_block_tail_p(mp, block); blp = xfs_dir2_block_leaf_p(btp); /* * Don't let this go past the end of the block. */ if ((char *)blp > (char *)btp) blp = (xfs_dir2_leaf_entry_t *)btp; rval = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent, bp, dot, dotdot, mp->m_dirdatablk, (char *)blp); if (bp->dirty && !no_modify) { *repair = 1; da_bwrite(mp, bp); } else da_brelse(bp); return rval; } /* * Validates leaf contents, node format directories only. * magic number and sibling pointers checked by caller. * Returns 0 if block is ok, 1 if the block is bad. * Looking for: out of order hash values, bad stale counts. */ static int process_leaf_block_dir2( xfs_mount_t *mp, xfs_dir2_leaf_t *leaf, xfs_dablk_t da_bno, xfs_ino_t ino, xfs_dahash_t last_hashval, xfs_dahash_t *next_hashval) { int i; int stale; for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if ((char *)&leaf->ents[i] >= (char *)leaf + mp->m_dirblksize) { do_warn( _("bad entry count in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); return 1; } if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; else if (be32_to_cpu(leaf->ents[i].hashval) < last_hashval) { do_warn( _("bad hash ordering in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); return 1; } *next_hashval = last_hashval = be32_to_cpu(leaf->ents[i].hashval); } if (stale != be16_to_cpu(leaf->hdr.stale)) { do_warn( _("bad stale count in block %u of directory inode %" PRIu64 "\n"), da_bno, ino); return 1; } return 0; } /* * Returns 0 if the directory is ok, 1 if it has to be rebuilt. */ static int process_leaf_level_dir2( xfs_mount_t *mp, dir2_bt_cursor_t *da_cursor, int *repair) { bmap_ext_t *bmp; xfs_dabuf_t *bp; int buf_dirty; xfs_dahash_t current_hashval; xfs_dablk_t da_bno; xfs_dahash_t greatest_hashval; xfs_ino_t ino; xfs_dir2_leaf_t *leaf; int nex; xfs_dablk_t prev_bno; bmap_ext_t lbmp; da_bno = da_cursor->level[0].bno; ino = da_cursor->ino; prev_bno = 0; bmp = NULL; current_hashval = 0; greatest_hashval = 0; buf_dirty = 0; do { nex = blkmap_getn(da_cursor->blkmap, da_bno, mp->m_dirblkfsbs, &bmp, &lbmp); /* * Directory code uses 0 as the NULL block pointer since 0 * is the root block and no directory block pointer can point * to the root block of the btree. */ ASSERT(da_bno != 0); if (nex == 0) { do_warn( _("can't map block %u for directory inode %" PRIu64 "\n"), da_bno, ino); goto error_out; } bp = da_read_buf(mp, nex, bmp); if (bmp != &lbmp) free(bmp); bmp = NULL; if (bp == NULL) { do_warn( _("can't read file block %u for directory inode %" PRIu64 "\n"), da_bno, ino); goto error_out; } leaf = bp->data; /* * Check magic number for leaf directory btree block. */ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) { do_warn( _("bad directory leaf magic # %#x for directory inode %" PRIu64 " block %u\n"), be16_to_cpu(leaf->hdr.info.magic), ino, da_bno); da_brelse(bp); goto error_out; } buf_dirty = 0; /* * For each block, process the block, verify its path, * then get next block. Update cursor values along the way. */ if (process_leaf_block_dir2(mp, leaf, da_bno, ino, current_hashval, &greatest_hashval)) { da_brelse(bp); goto error_out; } /* * Index can be set to hdr.count so match the indices of the * interior blocks -- which at the end of the block will point * to 1 after the final real entry in the block. */ da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = buf_dirty; if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn( _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"), da_bno, ino); da_brelse(bp); goto error_out; } prev_bno = da_bno; da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0) { if (verify_dir2_path(mp, da_cursor, 0)) { da_brelse(bp); goto error_out; } } current_hashval = greatest_hashval; ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); if (buf_dirty && !no_modify) { *repair = 1; da_bwrite(mp, bp); } else da_brelse(bp); } while (da_bno != 0); if (verify_final_dir2_path(mp, da_cursor, 0)) { /* * Verify the final path up (right-hand-side) if still ok. */ do_warn(_("bad hash path in directory %" PRIu64 "\n"), ino); goto error_out; } /* * Redundant but just for testing. */ release_dir2_cursor(mp, da_cursor, 0); return 0; error_out: /* * Release all buffers holding interior btree blocks. */ err_release_dir2_cursor(mp, da_cursor, 0); if (bmp && (bmp != &lbmp)) free(bmp); return 1; } /* * Return 1 if the directory's leaf/node space is corrupted and * needs to be rebuilt, 0 if it's ok. */ static int process_node_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, blkmap_t *blkmap, int *repair) { xfs_dablk_t bno; dir2_bt_cursor_t da_cursor; /* * Try again -- traverse down left-side of tree until we hit the * left-most leaf block setting up the btree cursor along the way. * Then walk the leaf blocks left-to-right, calling a parent * verification routine each time we traverse a block. */ memset(&da_cursor, 0, sizeof(da_cursor)); da_cursor.ino = ino; da_cursor.dip = dip; da_cursor.blkmap = blkmap; /* * Now process interior node. */ if (traverse_int_dir2block(mp, &da_cursor, &bno) == 0) return 1; /* * Skip directories with a root marked XFS_DIR2_LEAFN_MAGIC */ if (bno == 0) { release_dir2_cursor(mp, &da_cursor, 0); return 0; } else { /* * Now pass cursor and bno into leaf-block processing routine. * The leaf dir level routine checks the interior paths up to * the root including the final right-most path. */ return process_leaf_level_dir2(mp, &da_cursor, repair); } } /* * Process leaf and node directories. * Process the data blocks then, if it's a node directory, check * the consistency of those blocks. */ static int process_leaf_node_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, char *dirname, /* directory pathname */ xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */ blkmap_t *blkmap, int *dot, /* out - 1 if there is a dot, else 0 */ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ int *repair, /* out - 1 if something was fixed */ int isnode) /* node directory not leaf */ { bmap_ext_t *bmp; xfs_dabuf_t *bp; xfs_dir2_data_t *data; xfs_dfiloff_t dbno; int good; int i; xfs_dfiloff_t ndbno; int nex; int t; bmap_ext_t lbmp; *repair = *dot = *dotdot = good = 0; *parent = NULLFSINO; ndbno = NULLDFILOFF; while ((dbno = blkmap_next_off(blkmap, ndbno, &t)) < mp->m_dirleafblk) { nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp, &lbmp); /* Advance through map to last dfs block in this dir block */ ndbno = dbno; while (ndbno < dbno + mp->m_dirblkfsbs - 1) { ndbno = blkmap_next_off(blkmap, ndbno, &t); } if (nex == 0) { do_warn( _("block %" PRIu64 " for directory inode %" PRIu64 " is missing\n"), dbno, ino); continue; } bp = da_read_buf(mp, nex, bmp); if (bmp != &lbmp) free(bmp); if (bp == NULL) { do_warn( _("can't read block %" PRIu64 " for directory inode %" PRIu64 "\n"), dbno, ino); continue; } data = bp->data; if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) do_warn( _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" PRIu64 "\n"), be32_to_cpu(data->hdr.magic), dbno, ino); i = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent, bp, dot, dotdot, (xfs_dablk_t)dbno, (char *)data + mp->m_dirblksize); if (i == 0) good++; if (bp->dirty && !no_modify) { *repair = 1; da_bwrite(mp, bp); } else da_brelse(bp); } if (good == 0) return 1; if (!isnode) return 0; if (dir2_is_badino(ino)) return 0; if (process_node_dir2(mp, ino, dip, blkmap, repair)) dir2_add_badlist(ino); return 0; } /* * Returns 1 if things are bad (directory needs to be junked) * and 0 if things are ok. If ino_discovery is 1, add unknown * inodes to uncertain inode list. */ int process_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, char *dirname, xfs_ino_t *parent, blkmap_t *blkmap) { int dot; int dotdot; xfs_dfiloff_t last; int repair; int res; *parent = NULLFSINO; dot = dotdot = 0; last = 0; /* * branch off depending on the type of inode. This routine * is only called ONCE so all the subordinate routines will * fix '.' and junk '..' if they're bogus. */ if (blkmap) last = blkmap_last_off(blkmap); if (be64_to_cpu(dip->di_size) <= XFS_DFORK_DSIZE(dip, mp) && dip->di_format == XFS_DINODE_FMT_LOCAL) { dot = dotdot = 1; res = process_sf_dir2(mp, ino, dip, ino_discovery, dino_dirty, dirname, parent, &repair); } else if (last == mp->m_dirblkfsbs && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) { res = process_block_dir2(mp, ino, dip, ino_discovery, dino_dirty, dirname, parent, blkmap, &dot, &dotdot, &repair); } else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) { res = process_leaf_node_dir2(mp, ino, dip, ino_discovery, dirname, parent, blkmap, &dot, &dotdot, &repair, last > mp->m_dirleafblk + mp->m_dirblkfsbs); } else { do_warn(_("bad size/format for directory %" PRIu64 "\n"), ino); return 1; } /* * bad . entries in all directories will be fixed up in phase 6 */ if (dot == 0) { do_warn(_("no . entry for directory %" PRIu64 "\n"), ino); } /* * shortform dirs always have a .. entry. .. for all longform * directories will get fixed in phase 6. .. for other shortform * dirs also get fixed there. .. for a shortform root was * fixed in place since we know what it should be */ if (dotdot == 0 && ino != mp->m_sb.sb_rootino) { do_warn(_("no .. entry for directory %" PRIu64 "\n"), ino); } else if (dotdot == 0 && ino == mp->m_sb.sb_rootino) { do_warn(_("no .. entry for root directory %" PRIu64 "\n"), ino); need_root_dotdot = 1; } ASSERT((ino != mp->m_sb.sb_rootino && ino != *parent) || (ino == mp->m_sb.sb_rootino && (ino == *parent || need_root_dotdot == 1))); return res; } xfsprogs-3.1.9ubuntu2/repair/agheader.c0000664000000000000000000003042312062210562015000 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "globals.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" static int verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i) { xfs_drfsbno_t agblocks; int retval = 0; /* check common fields */ if (be32_to_cpu(agf->agf_magicnum) != XFS_AGF_MAGIC) { retval = XR_AG_AGF; do_warn(_("bad magic # 0x%x for agf %d\n"), be32_to_cpu(agf->agf_magicnum), i); if (!no_modify) agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); } if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum))) { retval = XR_AG_AGF; do_warn(_("bad version # %d for agf %d\n"), be32_to_cpu(agf->agf_versionnum), i); if (!no_modify) agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); } if (be32_to_cpu(agf->agf_seqno) != i) { retval = XR_AG_AGF; do_warn(_("bad sequence # %d for agf %d\n"), be32_to_cpu(agf->agf_seqno), i); if (!no_modify) agf->agf_seqno = cpu_to_be32(i); } if (be32_to_cpu(agf->agf_length) != mp->m_sb.sb_agblocks) { if (i != mp->m_sb.sb_agcount - 1) { retval = XR_AG_AGF; do_warn(_("bad length %d for agf %d, should be %d\n"), be32_to_cpu(agf->agf_length), i, mp->m_sb.sb_agblocks); if (!no_modify) agf->agf_length = cpu_to_be32(mp->m_sb.sb_agblocks); } else { agblocks = mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i; if (be32_to_cpu(agf->agf_length) != agblocks) { retval = XR_AG_AGF; do_warn( _("bad length %d for agf %d, should be %" PRIu64 "\n"), be32_to_cpu(agf->agf_length), i, agblocks); if (!no_modify) agf->agf_length = cpu_to_be32(agblocks); } } } /* * check first/last AGF fields. if need be, lose the free * space in the AGFL, we'll reclaim it later. */ if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp)) { do_warn(_("flfirst %d in agf %d too large (max = %zu)\n"), be32_to_cpu(agf->agf_flfirst), i, XFS_AGFL_SIZE(mp)); if (!no_modify) agf->agf_flfirst = cpu_to_be32(0); } if (be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { do_warn(_("fllast %d in agf %d too large (max = %zu)\n"), be32_to_cpu(agf->agf_fllast), i, XFS_AGFL_SIZE(mp)); if (!no_modify) agf->agf_fllast = cpu_to_be32(0); } /* don't check freespace btrees -- will be checked by caller */ return(retval); } static int verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno) { xfs_drfsbno_t agblocks; int retval = 0; /* check common fields */ if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { retval = XR_AG_AGI; do_warn(_("bad magic # 0x%x for agi %d\n"), be32_to_cpu(agi->agi_magicnum), agno); if (!no_modify) agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); } if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) { retval = XR_AG_AGI; do_warn(_("bad version # %d for agi %d\n"), be32_to_cpu(agi->agi_versionnum), agno); if (!no_modify) agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); } if (be32_to_cpu(agi->agi_seqno) != agno) { retval = XR_AG_AGI; do_warn(_("bad sequence # %d for agi %d\n"), be32_to_cpu(agi->agi_seqno), agno); if (!no_modify) agi->agi_seqno = cpu_to_be32(agno); } if (be32_to_cpu(agi->agi_length) != mp->m_sb.sb_agblocks) { if (agno != mp->m_sb.sb_agcount - 1) { retval = XR_AG_AGI; do_warn(_("bad length # %d for agi %d, should be %d\n"), be32_to_cpu(agi->agi_length), agno, mp->m_sb.sb_agblocks); if (!no_modify) agi->agi_length = cpu_to_be32(mp->m_sb.sb_agblocks); } else { agblocks = mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno; if (be32_to_cpu(agi->agi_length) != agblocks) { retval = XR_AG_AGI; do_warn( _("bad length # %d for agi %d, should be %" PRIu64 "\n"), be32_to_cpu(agi->agi_length), agno, agblocks); if (!no_modify) agi->agi_length = cpu_to_be32(agblocks); } } } /* don't check inode btree -- will be checked by caller */ return(retval); } /* * superblock comparison - compare arbitrary superblock with * filesystem mount-point superblock * * the verified fields include id and geometry. * * the inprogress fields, version numbers, and counters * are allowed to differ as well as all fields after the * counters to cope with the pre-6.5 mkfs non-zeroed * secondary superblock sectors. */ static int compare_sb(xfs_mount_t *mp, xfs_sb_t *sb) { fs_geometry_t fs_geo, sb_geo; get_sb_geometry(&fs_geo, &mp->m_sb); get_sb_geometry(&sb_geo, sb); if (memcmp(&fs_geo, &sb_geo, (char *) &fs_geo.sb_shared_vn - (char *) &fs_geo)) return(XR_SB_GEO_MISMATCH); return(XR_OK); } /* * Possible fields that may have been set at mkfs time, * sb_inoalignmt, sb_unit, sb_width and sb_dirblklog. * The quota inode fields in the secondaries should be zero. * Likewise, the sb_flags and sb_shared_vn should also be * zero and the shared version bit should be cleared for * current mkfs's. * * And everything else in the buffer beyond either sb_width, * sb_dirblklog (v2 dirs), or sb_logsectsize can be zeroed. * * Note: contrary to the name, this routine is called for all * superblocks, not just the secondary superblocks. */ static int secondary_sb_wack(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, xfs_agnumber_t i) { int do_bzero; int size; char *ip; int rval; rval = do_bzero = 0; /* * mkfs's that stamped a feature bit besides the ones in the mask * (e.g. were pre-6.5 beta) could leave garbage in the secondary * superblock sectors. Anything stamping the shared fs bit or better * into the secondaries is ok and should generate clean secondary * superblock sectors. so only run the zero check on the * potentially garbaged secondaries. */ if (pre_65_beta || (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK) == 0 || sb->sb_versionnum < XFS_SB_VERSION_4) { /* * Check for garbage beyond the last field. * Use field addresses instead so this code will still * work against older filesystems when the superblock * gets rev'ed again with new fields appended. */ if (xfs_sb_version_hasmorebits(sb)) size = (__psint_t)&sb->sb_features2 + sizeof(sb->sb_features2) - (__psint_t)sb; else if (xfs_sb_version_haslogv2(sb)) size = (__psint_t)&sb->sb_logsunit + sizeof(sb->sb_logsunit) - (__psint_t)sb; else if (xfs_sb_version_hassector(sb)) size = (__psint_t)&sb->sb_logsectsize + sizeof(sb->sb_logsectsize) - (__psint_t)sb; else if (xfs_sb_version_hasdirv2(sb)) size = (__psint_t)&sb->sb_dirblklog + sizeof(sb->sb_dirblklog) - (__psint_t)sb; else size = (__psint_t)&sb->sb_width + sizeof(sb->sb_width) - (__psint_t)sb; for (ip = (char *)((__psint_t)sb + size); ip < (char *)((__psint_t)sb + mp->m_sb.sb_sectsize); ip++) { if (*ip) { do_bzero = 1; break; } } if (do_bzero) { rval |= XR_AG_SB_SEC; if (!no_modify) { do_warn( _("zeroing unused portion of %s superblock (AG #%u)\n"), !i ? _("primary") : _("secondary"), i); memset((void *)((__psint_t)sb + size), 0, mp->m_sb.sb_sectsize - size); } else do_warn( _("would zero unused portion of %s superblock (AG #%u)\n"), !i ? _("primary") : _("secondary"), i); } } /* * now look for the fields we can manipulate directly. * if we did a zero and that zero could have included * the field in question, just silently reset it. otherwise, * complain. * * for now, just zero the flags field since only * the readonly flag is used */ if (sb->sb_flags) { if (!no_modify) sb->sb_flags = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn(_("bad flags field in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } /* * quota inodes and flags in secondary superblocks * are never set by mkfs. However, they could be set * in a secondary if a fs with quotas was growfs'ed since * growfs copies the new primary into the secondaries. */ if (sb->sb_inprogress == 1 && sb->sb_uquotino) { if (!no_modify) sb->sb_uquotino = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("non-null user quota inode field in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } if (sb->sb_inprogress == 1 && sb->sb_gquotino) { if (!no_modify) sb->sb_gquotino = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("non-null group quota inode field in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } if (sb->sb_inprogress == 1 && sb->sb_qflags) { if (!no_modify) sb->sb_qflags = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn(_("non-null quota flags in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } /* * if the secondaries agree on a stripe unit/width or inode * alignment, those fields ought to be valid since they are * written at mkfs time (and the corresponding sb version bits * are set). */ if (!xfs_sb_version_hasshared(sb) && sb->sb_shared_vn != 0) { if (!no_modify) sb->sb_shared_vn = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("bad shared version number in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } if (!xfs_sb_version_hasalign(sb) && sb->sb_inoalignmt != 0) { if (!no_modify) sb->sb_inoalignmt = 0; if (sb->sb_versionnum & XR_PART_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("bad inode alignment field in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } if (!xfs_sb_version_hasdalign(sb) && (sb->sb_unit != 0 || sb->sb_width != 0)) { if (!no_modify) sb->sb_unit = sb->sb_width = 0; if (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("bad stripe unit/width fields in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } if (!xfs_sb_version_hassector(sb) && (sb->sb_sectsize != BBSIZE || sb->sb_sectlog != BBSHIFT || sb->sb_logsectsize != 0 || sb->sb_logsectlog != 0)) { if (!no_modify) { sb->sb_sectsize = BBSIZE; sb->sb_sectlog = BBSHIFT; sb->sb_logsectsize = 0; sb->sb_logsectlog = 0; } if (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK || !do_bzero) { rval |= XR_AG_SB; do_warn( _("bad log/data device sector size fields in superblock %d\n"), i); } else rval |= XR_AG_SB_SEC; } return(rval); } /* * verify and reset the ag header if required. * * lower 4 bits of rval are set depending on what got modified. * (see agheader.h for more details) * * NOTE -- this routine does not tell the user that it has * altered things. Rather, it is up to the caller to do so * using the bits encoded into the return value. */ int verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, xfs_agf_t *agf, xfs_agi_t *agi, xfs_agnumber_t i) { int rval = 0; int status = XR_OK; int status_sb = XR_OK; status = verify_sb(sb, (i == 0)); if (status != XR_OK) { do_warn(_("bad on-disk superblock %d - %s\n"), i, err_string(status)); } status_sb = compare_sb(mp, sb); if (status_sb != XR_OK) { do_warn(_("primary/secondary superblock %d conflict - %s\n"), i, err_string(status_sb)); } if (status != XR_OK || status_sb != XR_OK) { if (!no_modify) { *sb = mp->m_sb; /* * clear the more transient fields */ sb->sb_inprogress = 1; sb->sb_icount = 0; sb->sb_ifree = 0; sb->sb_fdblocks = 0; sb->sb_frextents = 0; sb->sb_qflags = 0; } rval |= XR_AG_SB; } rval |= secondary_sb_wack(mp, sbuf, sb, i); rval |= verify_set_agf(mp, agf, i); rval |= verify_set_agi(mp, agi, i); return(rval); } xfsprogs-3.1.9ubuntu2/repair/prefetch.c0000664000000000000000000005064512062210562015050 0ustar #include #include #include "avl.h" #include "btree.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "dir.h" #include "dir2.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "bmap.h" #include "versions.h" #include "threads.h" #include "prefetch.h" #include "progress.h" int do_prefetch = 1; /* * Performs prefetching by priming the libxfs cache by using a dedicate thread * scanning inodes and reading blocks in ahead of time they are required. * * Any I/O errors can be safely ignored. */ static xfs_mount_t *mp; static int mp_fd; static int pf_max_bytes; static int pf_max_bbs; static int pf_max_fsbs; static int pf_batch_bytes; static int pf_batch_fsbs; static void pf_read_inode_dirs(prefetch_args_t *, xfs_buf_t *); /* * Buffer priorities for the libxfs cache * * Directory metadata is ranked higher than other metadata as it's used * in phases 3, 4 and 6, while other metadata is only used in 3 & 4. */ /* intermediate directory btree nodes - can't be queued */ #define B_DIR_BMAP CACHE_PREFETCH_PRIORITY + 7 /* directory metadata in secondary queue */ #define B_DIR_META_2 CACHE_PREFETCH_PRIORITY + 6 /* dir metadata that had to fetched from the primary queue to avoid stalling */ #define B_DIR_META_H CACHE_PREFETCH_PRIORITY + 5 /* single block of directory metadata (can't batch read) */ #define B_DIR_META_S CACHE_PREFETCH_PRIORITY + 4 /* dir metadata with more than one block fetched in a single I/O */ #define B_DIR_META CACHE_PREFETCH_PRIORITY + 3 /* inode clusters with directory inodes */ #define B_DIR_INODE CACHE_PREFETCH_PRIORITY + 2 /* intermediate extent btree nodes */ #define B_BMAP CACHE_PREFETCH_PRIORITY + 1 /* inode clusters without any directory entries */ #define B_INODE CACHE_PREFETCH_PRIORITY /* * Test if bit 0 or 2 is set in the "priority tag" of the buffer to see if * the buffer is for an inode or other metadata. */ #define B_IS_INODE(f) (((f) & 5) == 0) #define DEF_BATCH_BYTES 0x10000 #define MAX_BUFS 128 #define IO_THRESHOLD (MAX_BUFS * 2) typedef enum pf_which { PF_PRIMARY, PF_SECONDARY, PF_META_ONLY } pf_which_t; static inline void pf_start_processing( prefetch_args_t *args) { if (!args->can_start_processing) { pftrace("signalling processing for AG %d", args->agno); args->can_start_processing = 1; pthread_cond_signal(&args->start_processing); } } static inline void pf_start_io_workers( prefetch_args_t *args) { if (!args->can_start_reading) { pftrace("signalling reading for AG %d", args->agno); args->can_start_reading = 1; pthread_cond_broadcast(&args->start_reading); } } static void pf_queue_io( prefetch_args_t *args, xfs_fsblock_t fsbno, int blen, int flag) { xfs_buf_t *bp; /* * Never block on a buffer lock here, given that the actual repair * code might lock buffers in a different order from us. Given that * the lock holder is either reading it from disk himself or * completely overwriting it this behaviour is perfectly fine. */ bp = libxfs_getbuf_flags(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, blen), LIBXFS_GETBUF_TRYLOCK); if (!bp) return; if (bp->b_flags & LIBXFS_B_UPTODATE) { if (B_IS_INODE(flag)) pf_read_inode_dirs(args, bp); XFS_BUF_SET_PRIORITY(bp, XFS_BUF_PRIORITY(bp) + CACHE_PREFETCH_PRIORITY); libxfs_putbuf(bp); return; } XFS_BUF_SET_PRIORITY(bp, flag); pthread_mutex_lock(&args->lock); btree_insert(args->io_queue, fsbno, bp); if (fsbno > args->last_bno_read) { if (B_IS_INODE(flag)) { args->inode_bufs_queued++; if (args->inode_bufs_queued == IO_THRESHOLD) pf_start_io_workers(args); } } else { ASSERT(!B_IS_INODE(flag)); XFS_BUF_SET_PRIORITY(bp, B_DIR_META_2); } pftrace("getbuf %c %p (%llu) in AG %d (fsbno = %lu) added to queue" "(inode_bufs_queued = %d, last_bno = %lu)", B_IS_INODE(flag) ? 'I' : 'M', bp, (long long)XFS_BUF_ADDR(bp), args->agno, fsbno, args->inode_bufs_queued, args->last_bno_read); pf_start_processing(args); pthread_mutex_unlock(&args->lock); } static int pf_read_bmbt_reclist( prefetch_args_t *args, xfs_bmbt_rec_t *rp, int numrecs) { int i; xfs_bmbt_irec_t irec; xfs_dfilblks_t cp = 0; /* prev count */ xfs_dfiloff_t op = 0; /* prev offset */ for (i = 0; i < numrecs; i++) { libxfs_bmbt_disk_get_all(rp + i, &irec); if (((i > 0) && (op + cp > irec.br_startoff)) || (irec.br_blockcount == 0) || (irec.br_startoff >= fs_max_file_offset)) return 0; if (!verify_dfsbno(mp, irec.br_startblock) || !verify_dfsbno(mp, irec.br_startblock + irec.br_blockcount - 1)) return 0; if (!args->dirs_only && ((irec.br_startoff + irec.br_blockcount) >= mp->m_dirfreeblk)) break; /* only Phase 6 reads the free blocks */ op = irec.br_startoff; cp = irec.br_blockcount; while (irec.br_blockcount) { unsigned int len; pftrace("queuing dir extent in AG %d", args->agno); len = (irec.br_blockcount > mp->m_dirblkfsbs) ? mp->m_dirblkfsbs : irec.br_blockcount; pf_queue_io(args, irec.br_startblock, len, B_DIR_META); irec.br_blockcount -= len; irec.br_startblock += len; } } return 1; } /* * simplified version of the main scan_lbtree. Returns 0 to stop. */ static int pf_scan_lbtree( xfs_dfsbno_t dbno, int level, int isadir, prefetch_args_t *args, int (*func)(struct xfs_btree_block *block, int level, int isadir, prefetch_args_t *args)) { xfs_buf_t *bp; int rc; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) return 0; XFS_BUF_SET_PRIORITY(bp, isadir ? B_DIR_BMAP : B_BMAP); rc = (*func)(XFS_BUF_TO_BLOCK(bp), level - 1, isadir, args); libxfs_putbuf(bp); return rc; } static int pf_scanfunc_bmap( struct xfs_btree_block *block, int level, int isadir, prefetch_args_t *args) { xfs_bmbt_ptr_t *pp; int numrecs; int i; xfs_dfsbno_t dbno; /* * do some validation on the block contents */ if ((be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) || (be16_to_cpu(block->bb_level) != level)) return 0; numrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (numrecs > mp->m_bmap_dmxr[0] || !isadir) return 0; return pf_read_bmbt_reclist(args, XFS_BMBT_REC_ADDR(mp, block, 1), numrecs); } if (numrecs > mp->m_bmap_dmxr[1]) return 0; pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < numrecs; i++) { dbno = be64_to_cpu(pp[i]); if (!verify_dfsbno(mp, dbno)) return 0; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) return 0; } return 1; } static void pf_read_btinode( prefetch_args_t *args, xfs_dinode_t *dino, int isadir) { xfs_bmdr_block_t *dib; xfs_bmbt_ptr_t *pp; int i; int level; int numrecs; int dsize; xfs_dfsbno_t dbno; dib = (xfs_bmdr_block_t *)XFS_DFORK_DPTR(dino); level = be16_to_cpu(dib->bb_level); numrecs = be16_to_cpu(dib->bb_numrecs); if ((numrecs == 0) || (level == 0) || (level > XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))) return; /* * use bmdr/dfork_dsize since the root block is in the data fork */ if (XFS_BMDR_SPACE_CALC(numrecs) > XFS_DFORK_DSIZE(dino, mp)) return; dsize = XFS_DFORK_DSIZE(dino, mp); pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(mp, dsize, 0)); for (i = 0; i < numrecs; i++) { dbno = be64_to_cpu(pp[i]); if (!verify_dfsbno(mp, dbno)) break; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) break; } } static void pf_read_exinode( prefetch_args_t *args, xfs_dinode_t *dino) { pf_read_bmbt_reclist(args, (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino), be32_to_cpu(dino->di_nextents)); } static void pf_read_inode_dirs( prefetch_args_t *args, xfs_buf_t *bp) { xfs_dinode_t *dino; int icnt = 0; int hasdir = 0; int isadir; for (icnt = 0; icnt < (XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog); icnt++) { dino = xfs_make_iptr(mp, bp, icnt); /* * We are only prefetching directory contents in extents * and btree nodes for other inodes */ isadir = (be16_to_cpu(dino->di_mode) & S_IFMT) == S_IFDIR; hasdir |= isadir; if (dino->di_format <= XFS_DINODE_FMT_LOCAL) continue; if (!isadir && (dino->di_format == XFS_DINODE_FMT_EXTENTS || args->dirs_only)) continue; /* * do some checks on the inode to see if we can prefetch * its directory data. It's a cut down version of * process_dinode_int() in dinode.c. */ if (dino->di_format > XFS_DINODE_FMT_BTREE) continue; if (be16_to_cpu(dino->di_magic) != XFS_DINODE_MAGIC) continue; if (!XFS_DINODE_GOOD_VERSION(dino->di_version) || (!fs_inode_nlink && dino->di_version > 1)) continue; if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) continue; if ((dino->di_forkoff != 0) && (dino->di_forkoff >= (XFS_LITINO(mp) >> 3))) continue; switch (dino->di_format) { case XFS_DINODE_FMT_EXTENTS: pf_read_exinode(args, dino); break; case XFS_DINODE_FMT_BTREE: pf_read_btinode(args, dino, isadir); break; } } if (hasdir) XFS_BUF_SET_PRIORITY(bp, B_DIR_INODE); } /* * pf_batch_read must be called with the lock locked. */ static void pf_batch_read( prefetch_args_t *args, pf_which_t which, void *buf) { xfs_buf_t *bplist[MAX_BUFS]; unsigned int num; off64_t first_off, last_off, next_off; int len, size; int i; int inode_bufs; unsigned long fsbno = 0; unsigned long max_fsbno; char *pbuf; for (;;) { num = 0; if (which == PF_SECONDARY) { bplist[0] = btree_find(args->io_queue, 0, &fsbno); max_fsbno = MIN(fsbno + pf_max_fsbs, args->last_bno_read); } else { bplist[0] = btree_find(args->io_queue, args->last_bno_read, &fsbno); max_fsbno = fsbno + pf_max_fsbs; } while (bplist[num] && num < MAX_BUFS && fsbno < max_fsbno) { if (which != PF_META_ONLY || !B_IS_INODE(XFS_BUF_PRIORITY(bplist[num]))) num++; bplist[num] = btree_lookup_next(args->io_queue, &fsbno); } if (!num) return; /* * do a big read if 25% of the potential buffer is useful, * otherwise, find as many close together blocks and * read them in one read */ first_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[0])); last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) + XFS_BUF_SIZE(bplist[num-1]); while (last_off - first_off > pf_max_bytes) { num--; last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) + XFS_BUF_SIZE(bplist[num-1]); } if (num < ((last_off - first_off) >> (mp->m_sb.sb_blocklog + 3))) { /* * not enough blocks for one big read, so determine * the number of blocks that are close enough. */ last_off = first_off + XFS_BUF_SIZE(bplist[0]); for (i = 1; i < num; i++) { next_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[i])) + XFS_BUF_SIZE(bplist[i]); if (next_off - last_off > pf_batch_bytes) break; last_off = next_off; } num = i; } for (i = 0; i < num; i++) { if (btree_delete(args->io_queue, XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bplist[i]))) == NULL) do_error(_("prefetch corruption\n")); } if (which == PF_PRIMARY) { for (inode_bufs = 0, i = 0; i < num; i++) { if (B_IS_INODE(XFS_BUF_PRIORITY(bplist[i]))) inode_bufs++; } args->inode_bufs_queued -= inode_bufs; if (inode_bufs && (first_off >> mp->m_sb.sb_blocklog) > pf_batch_fsbs) args->last_bno_read = (first_off >> mp->m_sb.sb_blocklog); } #ifdef XR_PF_TRACE pftrace("reading bbs %llu to %llu (%d bufs) from %s queue in AG %d (last_bno = %lu, inode_bufs = %d)", (long long)XFS_BUF_ADDR(bplist[0]), (long long)XFS_BUF_ADDR(bplist[num-1]), num, (which != PF_SECONDARY) ? "pri" : "sec", args->agno, args->last_bno_read, args->inode_bufs_queued); #endif pthread_mutex_unlock(&args->lock); /* * now read the data and put into the xfs_but_t's */ len = pread64(mp_fd, buf, (int)(last_off - first_off), first_off); if (len > 0) { /* * go through the xfs_buf_t list copying from the * read buffer into the xfs_buf_t's and release them. */ last_off = first_off; for (i = 0; i < num; i++) { pbuf = ((char *)buf) + (LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[i])) - first_off); size = XFS_BUF_SIZE(bplist[i]); if (len < size) break; memcpy(XFS_BUF_PTR(bplist[i]), pbuf, size); bplist[i]->b_flags |= LIBXFS_B_UPTODATE; len -= size; if (B_IS_INODE(XFS_BUF_PRIORITY(bplist[i]))) pf_read_inode_dirs(args, bplist[i]); else if (which == PF_META_ONLY) XFS_BUF_SET_PRIORITY(bplist[i], B_DIR_META_H); else if (which == PF_PRIMARY && num == 1) XFS_BUF_SET_PRIORITY(bplist[i], B_DIR_META_S); } } for (i = 0; i < num; i++) { pftrace("putbuf %c %p (%llu) in AG %d", B_IS_INODE(XFS_BUF_PRIORITY(bplist[i])) ? 'I' : 'M', bplist[i], (long long)XFS_BUF_ADDR(bplist[i]), args->agno); libxfs_putbuf(bplist[i]); } pthread_mutex_lock(&args->lock); if (which != PF_SECONDARY) { pftrace("inode_bufs_queued for AG %d = %d", args->agno, args->inode_bufs_queued); /* * if primary inode queue running low, process metadata * in boths queues to avoid I/O starvation as the * processing thread would be waiting for a metadata * buffer */ if (which == PF_PRIMARY && !args->queuing_done && args->inode_bufs_queued < IO_THRESHOLD) { pftrace("reading metadata bufs from primary queue for AG %d", args->agno); pf_batch_read(args, PF_META_ONLY, buf); pftrace("reading bufs from secondary queue for AG %d", args->agno); pf_batch_read(args, PF_SECONDARY, buf); } } } } static void * pf_io_worker( void *param) { prefetch_args_t *args = param; void *buf = memalign(libxfs_device_alignment(), pf_max_bytes); if (buf == NULL) return NULL; pthread_mutex_lock(&args->lock); while (!args->queuing_done || !btree_is_empty(args->io_queue)) { pftrace("waiting to start prefetch I/O for AG %d", args->agno); while (!args->can_start_reading && !args->queuing_done) pthread_cond_wait(&args->start_reading, &args->lock); pftrace("starting prefetch I/O for AG %d", args->agno); pf_batch_read(args, PF_PRIMARY, buf); pf_batch_read(args, PF_SECONDARY, buf); pftrace("ran out of bufs to prefetch for AG %d", args->agno); if (!args->queuing_done) args->can_start_reading = 0; } pthread_mutex_unlock(&args->lock); free(buf); pftrace("finished prefetch I/O for AG %d", args->agno); return NULL; } static int pf_create_prefetch_thread( prefetch_args_t *args); static void * pf_queuing_worker( void *param) { prefetch_args_t *args = param; int num_inos; ino_tree_node_t *irec; ino_tree_node_t *cur_irec; int blks_per_cluster; xfs_agblock_t bno; int i; int err; blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; if (blks_per_cluster == 0) blks_per_cluster = 1; for (i = 0; i < PF_THREAD_COUNT; i++) { err = pthread_create(&args->io_threads[i], NULL, pf_io_worker, args); if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); if (i == 0) { pf_start_processing(args); return NULL; } /* * since we have at least one I/O thread, use them for * prefetch */ break; } } pftrace("starting prefetch for AG %d", args->agno); for (irec = findfirst_inode_rec(args->agno); irec != NULL; irec = next_ino_rec(irec)) { cur_irec = irec; num_inos = XFS_INODES_PER_CHUNK; while (num_inos < XFS_IALLOC_INODES(mp) && irec != NULL) { irec = next_ino_rec(irec); num_inos += XFS_INODES_PER_CHUNK; } if (args->dirs_only && cur_irec->ino_isa_dir == 0) continue; #ifdef XR_PF_TRACE sem_getvalue(&args->ra_count, &i); pftrace("queuing irec %p in AG %d, sem count = %d", irec, args->agno, i); #endif err = sem_trywait(&args->ra_count); if (err == EAGAIN) { /* * Kick the queue once we have reached the limit; * without this the threads processing the inodes * might get stuck on a buffer that has been locked * and added to the I/O queue but is waiting for * the thread to be woken. */ pf_start_io_workers(args); sem_wait(&args->ra_count); } num_inos = 0; bno = XFS_AGINO_TO_AGBNO(mp, cur_irec->ino_startnum); do { pf_queue_io(args, XFS_AGB_TO_FSB(mp, args->agno, bno), blks_per_cluster, (cur_irec->ino_isa_dir != 0) ? B_DIR_INODE : B_INODE); bno += blks_per_cluster; num_inos += inodes_per_cluster; } while (num_inos < XFS_IALLOC_INODES(mp)); } pthread_mutex_lock(&args->lock); pftrace("finished queuing inodes for AG %d (inode_bufs_queued = %d)", args->agno, args->inode_bufs_queued); args->queuing_done = 1; pf_start_io_workers(args); pf_start_processing(args); pthread_mutex_unlock(&args->lock); /* now wait for the readers to finish */ for (i = 0; i < PF_THREAD_COUNT; i++) if (args->io_threads[i]) pthread_join(args->io_threads[i], NULL); pftrace("prefetch for AG %d finished", args->agno); pthread_mutex_lock(&args->lock); ASSERT(btree_is_empty(args->io_queue)); args->prefetch_done = 1; if (args->next_args) pf_create_prefetch_thread(args->next_args); pthread_mutex_unlock(&args->lock); return NULL; } static int pf_create_prefetch_thread( prefetch_args_t *args) { int err; pftrace("creating queue thread for AG %d", args->agno); err = pthread_create(&args->queuing_thread, NULL, pf_queuing_worker, args); if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); cleanup_inode_prefetch(args); } return err == 0; } void init_prefetch( xfs_mount_t *pmp) { mp = pmp; mp_fd = libxfs_device_to_fd(mp->m_dev); pf_max_bytes = sysconf(_SC_PAGE_SIZE) << 7; pf_max_bbs = pf_max_bytes >> BBSHIFT; pf_max_fsbs = pf_max_bytes >> mp->m_sb.sb_blocklog; pf_batch_bytes = DEF_BATCH_BYTES; pf_batch_fsbs = DEF_BATCH_BYTES >> (mp->m_sb.sb_blocklog + 1); } prefetch_args_t * start_inode_prefetch( xfs_agnumber_t agno, int dirs_only, prefetch_args_t *prev_args) { prefetch_args_t *args; long max_queue; if (!do_prefetch || agno >= mp->m_sb.sb_agcount) return NULL; args = calloc(1, sizeof(prefetch_args_t)); btree_init(&args->io_queue); if (pthread_mutex_init(&args->lock, NULL) != 0) do_error(_("failed to initialize prefetch mutex\n")); if (pthread_cond_init(&args->start_reading, NULL) != 0) do_error(_("failed to initialize prefetch cond var\n")); if (pthread_cond_init(&args->start_processing, NULL) != 0) do_error(_("failed to initialize prefetch cond var\n")); args->agno = agno; args->dirs_only = dirs_only; /* * use only 1/8 of the libxfs cache as we are only counting inodes * and not any other associated metadata like directories */ max_queue = libxfs_bcache->c_maxcount / thread_count / 8; if (XFS_INODE_CLUSTER_SIZE(mp) > mp->m_sb.sb_blocksize) max_queue = max_queue * (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog) / XFS_IALLOC_BLOCKS(mp); sem_init(&args->ra_count, 0, max_queue); if (!prev_args) { if (!pf_create_prefetch_thread(args)) return NULL; } else { pthread_mutex_lock(&prev_args->lock); if (prev_args->prefetch_done) { if (!pf_create_prefetch_thread(args)) args = NULL; } else prev_args->next_args = args; pthread_mutex_unlock(&prev_args->lock); } return args; } void wait_for_inode_prefetch( prefetch_args_t *args) { if (args == NULL) return; pthread_mutex_lock(&args->lock); while (!args->can_start_processing) { pftrace("waiting to start processing AG %d", args->agno); pthread_cond_wait(&args->start_processing, &args->lock); } pftrace("can start processing AG %d", args->agno); pthread_mutex_unlock(&args->lock); } void cleanup_inode_prefetch( prefetch_args_t *args) { if (args == NULL) return; pftrace("waiting AG %d prefetch to finish", args->agno); if (args->queuing_thread) pthread_join(args->queuing_thread, NULL); pftrace("AG %d prefetch done", args->agno); pthread_mutex_destroy(&args->lock); pthread_cond_destroy(&args->start_reading); pthread_cond_destroy(&args->start_processing); sem_destroy(&args->ra_count); btree_destroy(args->io_queue); free(args); } #ifdef XR_PF_TRACE static FILE *pf_trace_file; void pftrace_init(void) { pf_trace_file = fopen("/tmp/xfs_repair_prefetch.trace", "w"); setvbuf(pf_trace_file, NULL, _IOLBF, 1024); } void pftrace_done(void) { fclose(pf_trace_file); } void _pftrace(const char *func, const char *msg, ...) { char buf[200]; struct timeval tv; va_list args; gettimeofday(&tv, NULL); va_start(args, msg); vsnprintf(buf, sizeof(buf), msg, args); buf[sizeof(buf)-1] = '\0'; va_end(args); fprintf(pf_trace_file, "%lu.%06lu %s: %s\n", tv.tv_sec, tv.tv_usec, func, buf); } #endif xfsprogs-3.1.9ubuntu2/repair/sb.c0000664000000000000000000004762312062210562013656 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "agheader.h" #include "globals.h" #include "protos.h" #include "err_protos.h" #define BSIZE (1024 * 1024) #define XFS_AG_BYTES(bblog) ((long long)BBSIZE << (bblog)) #define XFS_AG_MIN_BYTES ((XFS_AG_BYTES(15))) /* 16 MB */ /* * copy the fields of a superblock that are present in primary and * secondaries -- preserve fields that are different in the primary. */ static void copy_sb(xfs_sb_t *source, xfs_sb_t *dest) { xfs_ino_t rootino; xfs_ino_t rbmino; xfs_ino_t rsumino; xfs_ino_t uquotino; xfs_ino_t gquotino; __uint16_t versionnum; rootino = dest->sb_rootino; rbmino = dest->sb_rbmino; rsumino = dest->sb_rsumino; uquotino = dest->sb_uquotino; gquotino = dest->sb_gquotino; versionnum = dest->sb_versionnum; *dest = *source; dest->sb_rootino = rootino; dest->sb_rbmino = rbmino; dest->sb_rsumino = rsumino; dest->sb_uquotino = uquotino; dest->sb_gquotino = gquotino; dest->sb_versionnum = versionnum; /* * copy over version bits that are stamped into all * secondaries and cannot be changed at run time in * the primary superblock */ if (xfs_sb_version_hasdalign(source)) dest->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT; if (xfs_sb_version_hasextflgbit(source)) dest->sb_versionnum |= XFS_SB_VERSION_EXTFLGBIT; /* * these are all supposed to be zero or will get reset anyway */ dest->sb_icount = 0; dest->sb_ifree = 0; dest->sb_fdblocks = 0; dest->sb_frextents = 0; memset(source->sb_fname, 0, 12); } /* * find a secondary superblock, copy it into the sb buffer */ int find_secondary_sb(xfs_sb_t *rsb) { xfs_off_t off; xfs_sb_t *sb; xfs_sb_t bufsb; char *c_bufsb; int done; int i; int dirty; int retval; int bsize; do_warn(_("\nattempting to find secondary superblock...\n")); sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE); if (!sb) { do_error( _("error finding secondary superblock -- failed to memalign buffer\n")); exit(1); } memset(&bufsb, 0, sizeof(xfs_sb_t)); retval = 0; dirty = 0; bsize = 0; /* * skip first sector since we know that's bad */ for (done = 0, off = XFS_AG_MIN_BYTES; !done ; off += bsize) { /* * read disk 1 MByte at a time. */ if (lseek64(x.dfd, off, SEEK_SET) != off) { done = 1; } if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) { done = 1; } do_warn("."); /* * check the buffer 512 bytes at a time since * we don't know how big the sectors really are. */ for (i = 0; !done && i < bsize; i += BBSIZE) { c_bufsb = (char *)sb + i; libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb); if (verify_sb(&bufsb, 0) != XR_OK) continue; do_warn(_("found candidate secondary superblock...\n")); /* * found one. now verify it by looking * for other secondaries. */ memmove(rsb, &bufsb, sizeof(xfs_sb_t)); rsb->sb_inprogress = 0; clear_sunit = 1; if (verify_set_primary_sb(rsb, 0, &dirty) == XR_OK) { do_warn( _("verified secondary superblock...\n")); done = 1; retval = 1; } else { do_warn( _("unable to verify superblock, continuing...\n")); } } } free(sb); return(retval); } /* * calculate what inode alignment field ought to be * based on internal superblock info */ static int calc_ino_align(xfs_sb_t *sb) { xfs_extlen_t align; align = XFS_INODE_BIG_CLUSTER_SIZE >> sb->sb_blocklog; return(align); } /* * verify a superblock -- does not verify root inode # * can only check that geometry info is internally * consistent. because of growfs, that's no guarantee * of correctness (e.g. geometry may have changed) * * fields verified or consistency checked: * * sb_magicnum * * sb_versionnum * * sb_inprogress * * sb_blocksize (as a group) * sb_blocklog * * geometry info - sb_dblocks (as a group) * sb_agcount * sb_agblocks * sb_agblklog * * inode info - sb_inodesize (x-checked with geo info) * sb_inopblock * * sector size info - * sb_sectsize * sb_sectlog * sb_logsectsize * sb_logsectlog * * not checked here - * sb_rootino * sb_fname * sb_fpack * sb_logstart * sb_uuid * * ALL real-time fields * final 4 summary counters */ int verify_sb(xfs_sb_t *sb, int is_primary_sb) { __uint32_t bsize; xfs_extlen_t align; int i; /* check magic number and version number */ if (sb->sb_magicnum != XFS_SB_MAGIC) return(XR_BAD_MAGIC); if (!xfs_sb_good_version(sb)) return(XR_BAD_VERSION); /* does sb think mkfs really finished ? */ if (is_primary_sb && sb->sb_inprogress == 1) return(XR_BAD_INPROGRESS); /* check to make sure blocksize is legal 2^N, 9 <= N <= 16 */ if (sb->sb_blocksize == 0) return(XR_BAD_BLOCKSIZE); bsize = 1; for (i = 0; bsize < sb->sb_blocksize && i < sizeof(sb->sb_blocksize) * NBBY; i++) bsize <<= 1; if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG) return(XR_BAD_BLOCKSIZE); /* check sb blocksize field against sb blocklog field */ if (i != sb->sb_blocklog) return(XR_BAD_BLOCKLOG); /* sanity check ag count, size fields against data size field */ if (sb->sb_dblocks == 0 || sb->sb_dblocks > ((__uint64_t)sb->sb_agcount * sb->sb_agblocks) || sb->sb_dblocks < ((__uint64_t)(sb->sb_agcount - 1) * sb->sb_agblocks + XFS_MIN_AG_BLOCKS)) return(XR_BAD_FS_SIZE_DATA); if (sb->sb_agblklog != (__uint8_t)libxfs_log2_roundup(sb->sb_agblocks)) return(XR_BAD_FS_SIZE_DATA); if (sb->sb_inodesize < XFS_DINODE_MIN_SIZE || sb->sb_inodesize > XFS_DINODE_MAX_SIZE || sb->sb_inopblock != howmany(sb->sb_blocksize,sb->sb_inodesize)) return(XR_BAD_INO_SIZE_DATA); /* check to make sure sectorsize is legal 2^N, 9 <= N <= 15 */ if (sb->sb_sectsize == 0) return(XR_BAD_SECT_SIZE_DATA); bsize = 1; for (i = 0; bsize < sb->sb_sectsize && i < sizeof(sb->sb_sectsize) * NBBY; i++) { bsize <<= 1; } if (i < XFS_MIN_SECTORSIZE_LOG || i > XFS_MAX_SECTORSIZE_LOG) return(XR_BAD_SECT_SIZE_DATA); /* check sb sectorsize field against sb sectlog field */ if (i != sb->sb_sectlog) return(XR_BAD_SECT_SIZE_DATA); if (xfs_sb_version_hassector(sb)) { /* check to make sure log sector is legal 2^N, 9 <= N <= 15 */ if (sb->sb_logsectsize == 0) return(XR_BAD_SECT_SIZE_DATA); bsize = 1; for (i = 0; bsize < sb->sb_logsectsize && i < sizeof(sb->sb_logsectsize) * NBBY; i++) { bsize <<= 1; } if (i < XFS_MIN_SECTORSIZE_LOG || i > XFS_MAX_SECTORSIZE_LOG) return(XR_BAD_SECT_SIZE_DATA); /* check sb log sectorsize field against sb log sectlog field */ if (i != sb->sb_logsectlog) return(XR_BAD_SECT_SIZE_DATA); } /* * real-time extent size is always set */ if (sb->sb_rextsize * sb->sb_blocksize > XFS_MAX_RTEXTSIZE) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rextsize * sb->sb_blocksize < XFS_MIN_RTEXTSIZE) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rblocks == 0) { if (sb->sb_rextents != 0) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rbmblocks != 0) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rextslog != 0) return(XR_BAD_RT_GEO_DATA); if (sb->sb_frextents != 0) return(XR_BAD_RT_GEO_DATA); } else { /* * if we have a real-time partition, sanity-check geometry */ if (sb->sb_rblocks / sb->sb_rextsize != sb->sb_rextents) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rextslog != libxfs_highbit32((unsigned int)sb->sb_rextents)) return(XR_BAD_RT_GEO_DATA); if (sb->sb_rbmblocks != (xfs_extlen_t) howmany(sb->sb_rextents, NBBY * sb->sb_blocksize)) return(XR_BAD_RT_GEO_DATA); } /* * verify correctness of inode alignment if it's there */ if (xfs_sb_version_hasalign(sb)) { align = calc_ino_align(sb); if (align != sb->sb_inoalignmt) return(XR_BAD_INO_ALIGN); } /* * verify max. % of inodes (sb_imax_pct) */ if (sb->sb_imax_pct > 100) return(XR_BAD_INO_MAX_PCT); /* * verify stripe alignment fields if present */ if (xfs_sb_version_hasdalign(sb)) { if ((!sb->sb_unit && sb->sb_width) || (sb->sb_unit && sb->sb_agblocks % sb->sb_unit)) return(XR_BAD_SB_UNIT); if ((sb->sb_unit && !sb->sb_width) || (sb->sb_width && sb->sb_unit && sb->sb_width % sb->sb_unit)) return(XR_BAD_SB_WIDTH); } /* * if shared bit is set, verify that the version number is sane */ if (xfs_sb_version_hasshared(sb)) { if (sb->sb_shared_vn > XFS_SB_MAX_SHARED_VN) return(XR_BAD_SVN); } /* * mkfs's that stamped a feature bit besides the ones in the * mask below could leave garbage in the secondary superblock * sectors. Anything stamping the shared fs bit or better into * the secondaries is ok and should generate clean secondary * superblock sectors. * * check primary and clean secondary superblocks more strictly */ if (is_primary_sb || sb->sb_versionnum & XR_PART_SECSB_VNMASK) { /* * return errors if shared vn or alignment fields * are set without their feature bits being set */ if ((!pre_65_beta && (sb->sb_versionnum & XR_PART_SECSB_VNMASK)) || (pre_65_beta && (sb->sb_versionnum & XR_ALPHA_SECSB_VNMASK))) { /* * shared version # and inode alignment fields * should be valid */ if (sb->sb_shared_vn && !xfs_sb_version_hasshared(sb)) return(XR_BAD_SVN); if (sb->sb_inoalignmt && !xfs_sb_version_hasalign(sb)) return(XR_BAD_INO_ALIGN); } if ((!pre_65_beta && (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK)) || (pre_65_beta && (sb->sb_versionnum & XFS_SB_VERSION_DALIGNBIT))) { /* * stripe alignment values should be valid */ if (sb->sb_unit && !xfs_sb_version_hasdalign(sb)) return(XR_BAD_SB_UNIT); if (sb->sb_width && !xfs_sb_version_hasdalign(sb)) return(XR_BAD_SB_WIDTH); } #if 0 /* * checks involving later superblock fields get added here... */ if (sb->sb_versionnum & XR_GOOD_SECSB_VNMASK) { } #endif } return(XR_OK); } void write_primary_sb(xfs_sb_t *sbp, int size) { xfs_dsb_t *buf; if (no_modify) return; buf = memalign(libxfs_device_alignment(), size); if (buf == NULL) { do_error(_("failed to memalign superblock buffer\n")); return; } memset(buf, 0, size); if (lseek64(x.dfd, 0LL, SEEK_SET) != 0LL) { free(buf); do_error(_("couldn't seek to offset 0 in filesystem\n")); } libxfs_sb_to_disk(buf, sbp, XFS_SB_ALL_BITS); if (write(x.dfd, buf, size) != size) { free(buf); do_error(_("primary superblock write failed!\n")); } free(buf); } /* * get a possible superblock -- don't check for internal consistency */ int get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) { int error, rval; xfs_dsb_t *buf; buf = memalign(libxfs_device_alignment(), size); if (buf == NULL) { do_error( _("error reading superblock %u -- failed to memalign buffer\n"), agno); exit(1); } memset(buf, 0, size); /* try and read it first */ if (lseek64(x.dfd, off, SEEK_SET) != off) { do_warn( _("error reading superblock %u -- seek to offset %" PRId64 " failed\n"), agno, off); return(XR_EOF); } if ((rval = read(x.dfd, buf, size)) != size) { error = errno; do_warn( _("superblock read failed, offset %" PRId64 ", size %d, ag %u, rval %d\n"), off, size, agno, rval); do_error("%s\n", strerror(error)); } libxfs_sb_from_disk(sbp, buf); free(buf); return (verify_sb(sbp, 0)); } /* returns element on list with highest reference count */ static fs_geo_list_t * get_best_geo(fs_geo_list_t *list) { int cnt = 0; fs_geo_list_t *current, *rval = NULL; current = list; while (current != NULL) { if (current->refs > cnt) { rval = current; cnt = current->refs; } current = current->next; } return(rval); } /* adds geometry info to linked list. returns (sometimes new) head of list */ static fs_geo_list_t * add_geo(fs_geo_list_t *list, fs_geometry_t *geo_p, int index) { fs_geo_list_t *current = list; while (current != NULL) { if (memcmp(geo_p, ¤t->geo, sizeof(fs_geometry_t)) == 0) { current->refs++; return(list); } current = current->next; } if ((current = malloc(sizeof(fs_geo_list_t))) == NULL) { do_error(_("couldn't malloc geometry structure\n")); exit(1); } current->geo = *geo_p; current->refs = 1; current->next = list; current->index = index; return(current); } static void free_geo(fs_geo_list_t *list) { fs_geo_list_t *next; fs_geo_list_t *current; current = list; for (current = list; current != NULL; current = next) { next = current->next; free(current); } } void get_sb_geometry(fs_geometry_t *geo, xfs_sb_t *sbp) { memset(geo, 0, sizeof(fs_geometry_t)); /* * blindly set fields that we know are always good */ geo->sb_blocksize = sbp->sb_blocksize; geo->sb_dblocks = sbp->sb_dblocks; geo->sb_rblocks = sbp->sb_rblocks; geo->sb_rextents = sbp->sb_rextents; geo->sb_logstart = sbp->sb_logstart; geo->sb_rextsize = sbp->sb_rextsize; geo->sb_agblocks = sbp->sb_agblocks; geo->sb_agcount = sbp->sb_agcount; geo->sb_rbmblocks = sbp->sb_rbmblocks; geo->sb_logblocks = sbp->sb_logblocks; geo->sb_sectsize = sbp->sb_sectsize; geo->sb_inodesize = sbp->sb_inodesize; if (xfs_sb_version_hasalign(sbp)) geo->sb_ialignbit = 1; if (xfs_sb_version_hasshared(sbp) || sbp->sb_versionnum & XR_PART_SECSB_VNMASK) geo->sb_sharedbit = 1; if (xfs_sb_version_hasdalign(sbp)) geo->sb_salignbit = 1; if (xfs_sb_version_hasextflgbit(sbp)) geo->sb_extflgbit = 1; /* * protect against pre-6.5 mkfs-generated garbaged * fields in the secondary superblocks. pay attention * to those fields if and only if their corresponding * feature bits are set in the feature bits of the * version number or we can deduce from the version bits * that are set that our field was properly initialized * because a field after the field we care about was * properly initialized as well. */ /* * inode alignment field lives before the data alignment field */ if ((!pre_65_beta && (sbp->sb_versionnum & XR_PART_SECSB_VNMASK)) || (pre_65_beta && (sbp->sb_versionnum & XR_ALPHA_SECSB_VNMASK))) geo->sb_inoalignmt = sbp->sb_inoalignmt; if ((!pre_65_beta && (sbp->sb_versionnum & XR_GOOD_SECSB_VNMASK)) || (pre_65_beta && xfs_sb_version_hasdalign(sbp))) { geo->sb_unit = sbp->sb_unit; geo->sb_width = sbp->sb_width; } /* * shared vn always set if either ino or data alignment is on * since that field lives between the quota and inode alignment * fields */ if (sbp->sb_versionnum & XR_PART_SECSB_VNMASK) geo->sb_shared_vn = sbp->sb_shared_vn; /* * superblock fields located after sb_widthfields get set * into the geometry structure only if we can determine * from the features enabled in this superblock whether * or not the sector was zero'd at mkfs time. */ if ((!pre_65_beta && (sbp->sb_versionnum & XR_GOOD_SECSB_VNMASK)) || (pre_65_beta && (sbp->sb_versionnum & XR_ALPHA_SECSB_VNMASK))) { geo->sb_fully_zeroed = 1; } } /* * the way to verify that a primary sb is consistent with the * filesystem is find the secondaries given the info in the * primary and compare the geometries in the secondaries against * the geometry indicated by the primary. * * returns 1 if bad, 0 if ok */ int verify_set_primary_sb(xfs_sb_t *rsb, int sb_index, int *sb_modified) { xfs_off_t off; fs_geometry_t geo; xfs_sb_t *sb; fs_geo_list_t *list; fs_geo_list_t *current; char *checked; xfs_agnumber_t agno; int num_sbs; int skip; int size; int num_ok; int retval; int round; /* * select the number of secondaries to try for */ num_sbs = MIN(NUM_SBS, rsb->sb_agcount); skip = howmany(num_sbs, rsb->sb_agcount); /* * We haven't been able to validate the sector size yet properly * (e.g. in the case of repairing an image in a file), so we need to * take into account sector mismatches and so use the maximum possible * sector size rather than the sector size in @rsb. */ size = NUM_AGH_SECTS * (1 << (XFS_MAX_SECTORSIZE_LOG)); retval = 0; list = NULL; num_ok = 0; *sb_modified = 0; sb = (xfs_sb_t *) alloc_ag_buf(size); checked = calloc(rsb->sb_agcount, sizeof(char)); if (!checked) { do_error(_("calloc failed in verify_set_primary_sb\n")); exit(1); } /* * put the primary sb geometry info onto the geometry list */ checked[sb_index] = 1; get_sb_geometry(&geo, rsb); list = add_geo(list, &geo, sb_index); /* * grab N secondaries. check them off as we get them * so we only process each one once */ for (round = 0; round < skip; round++) { for (agno = round; agno < rsb->sb_agcount; agno += skip) { if (checked[agno]) continue; off = (xfs_off_t)agno * rsb->sb_agblocks << rsb->sb_blocklog; checked[agno] = 1; if (get_sb(sb, off, size, agno) == XR_EOF) { retval = 1; goto out; } if (verify_sb(sb, 0) == XR_OK) { /* * save away geometry info. * don't bother checking the sb * against the agi/agf as the odds * of the sb being corrupted in a way * that it is internally consistent * but not consistent with the rest * of the filesystem is really really low. */ get_sb_geometry(&geo, sb); list = add_geo(list, &geo, agno); num_ok++; } } } /* * see if we have enough superblocks to bother with */ if (num_ok < num_sbs / 2) return(XR_INSUFF_SEC_SB); current = get_best_geo(list); /* * check that enough sbs agree that we're willing to * go with this geometry. if not, print out the * geometry and a message about the force option. */ switch (num_sbs) { case 2: /* * If we only have two allocation groups, and the superblock * in the second allocation group differs from the primary * superblock we can't verify the geometry information. * Warn the user about this situation and get out unless * explicitly overridden. */ if (current->refs != 2) { if (!force_geo) { do_warn( _("Only two AGs detected and they do not match - " "cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n")); exit(1); } } goto out_free_list; case 1: /* * If we only have a single allocation group there is no * secondary superblock that we can use to verify the geometry * information. Warn the user about this situation and get * out unless explicitly overridden. */ if (!force_geo) { do_warn( _("Only one AG detected - " "cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n")); exit(1); } goto out_free_list; default: /* * at least half of the probed superblocks have * to agree. if they don't, this fs is probably * too far gone anyway considering the fact that * XFS normally doesn't alter the secondary superblocks. */ if (current->refs < num_sbs / 2) { do_warn( _("Not enough matching superblocks - cannot proceed.\n")); exit(1); } } /* * set the geometry into primary superblock if necessary. */ if (current->index != sb_index) { *sb_modified = 1; off = (xfs_off_t)current->index * current->geo.sb_agblocks * current->geo.sb_blocksize; if (get_sb(sb, off, current->geo.sb_sectsize, current->index) != XR_OK) do_error(_("could not read superblock\n")); copy_sb(sb, rsb); /* * turn off inprogress bit since this is the primary. * also save away values that we need to ensure are * consistent in the other secondaries. */ rsb->sb_inprogress = 0; sb_inoalignmt = sb->sb_inoalignmt; sb_unit = sb->sb_unit; sb_width = sb->sb_width; } out_free_list: free_geo(list); out: free(sb); free(checked); return(retval); } xfsprogs-3.1.9ubuntu2/repair/threads.h0000664000000000000000000000151711140033220014667 0ustar #ifndef _XFS_REPAIR_THREADS_H_ #define _XFS_REPAIR_THREADS_H_ void thread_init(void); struct work_queue; typedef void work_func_t(struct work_queue *, xfs_agnumber_t, void *); typedef struct work_item { struct work_item *next; work_func_t *function; struct work_queue *queue; xfs_agnumber_t agno; void *arg; } work_item_t; typedef struct work_queue { work_item_t *next_item; work_item_t *last_item; int item_count; int thread_count; pthread_t *threads; xfs_mount_t *mp; pthread_mutex_t lock; pthread_cond_t wakeup; int terminate; } work_queue_t; void create_work_queue( work_queue_t *wq, xfs_mount_t *mp, int nworkers); void queue_work( work_queue_t *wq, work_func_t func, xfs_agnumber_t agno, void *arg); void destroy_work_queue( work_queue_t *wq); #endif /* _XFS_REPAIR_THREADS_H_ */ xfsprogs-3.1.9ubuntu2/repair/incore_bmc.c0000664000000000000000000000243511140033220015330 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "incore.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" void init_bm_cursor(bmap_cursor_t *cursor, int num_levels) { int i; memset(cursor, 0, sizeof(bmap_cursor_t)); cursor->ino = NULLFSINO; cursor->num_levels = num_levels; for (i = 0; i < XR_MAX_BMLEVELS; i++) { cursor->level[i].fsbno = NULLDFSBNO; cursor->level[i].right_fsbno = NULLDFSBNO; cursor->level[i].left_fsbno = NULLDFSBNO; cursor->level[i].first_key = NULLDFILOFF; cursor->level[i].last_key = NULLDFILOFF; } } xfsprogs-3.1.9ubuntu2/repair/dir2.h0000664000000000000000000000533312062210562014107 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_DIR2_H #define _XR_DIR2_H struct blkmap; struct bmap_ext; /* * the cursor gets passed up and down the da btree processing * routines. The interior block processing routines use the * cursor to determine if the pointers to and from the preceding * and succeeding sibling blocks are ok and whether the values in * the current block are consistent with the entries in the parent * nodes. When a block is traversed, a parent-verification routine * is called to verify if the next logical entry in the next level up * is consistent with the greatest hashval in the next block of the * current level. The verification routine is itself recursive and * calls itself if it has to traverse an interior block to get * the next logical entry. The routine recurses upwards through * the tree until it finds a block where it can simply step to * the next entry. The hashval in that entry should be equal to * the hashval being passed to it (the greatest hashval in the block * that the entry points to). If that isn't true, then the tree * is blown and we need to trash it, salvage and trash it, or fix it. * Currently, we just trash it. */ typedef struct dir2_level_state { xfs_dabuf_t *bp; /* block bp */ xfs_dablk_t bno; /* file block number */ xfs_dahash_t hashval; /* last verified hashval */ int index; /* current index in block */ int dirty; /* is buffer dirty ? (1 == yes) */ } dir2_level_state_t; typedef struct dir2_bt_cursor { int active; /* highest level in tree (# levels-1) */ int type; /* 0 if dir, 1 if attr */ xfs_ino_t ino; xfs_dablk_t greatest_bno; xfs_dinode_t *dip; dir2_level_state_t level[XFS_DA_NODE_MAXDEPTH]; struct blkmap *blkmap; } dir2_bt_cursor_t; int process_dir2( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dirty, char *dirname, xfs_ino_t *parent, struct blkmap *blkmap); void process_sf_dir2_fixi8( xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t **next_sfep); int dir2_is_badino( xfs_ino_t ino); #endif /* _XR_DIR2_H */ xfsprogs-3.1.9ubuntu2/repair/progress.h0000664000000000000000000000231111140033220015072 0ustar #ifndef _XFS_REPAIR_PROGRESS_RPT_H_ #define _XFS_REPAIR_PROGRESS_RPT_H_ #define PROG_RPT_DEFAULT (15*60) /* default 15 minute report interval */ #define PHASE_START 0 #define PHASE_END 1 #define PROG_FMT_SCAN_AG 0 /* Phase 2 */ #define PROG_FMT_AGI_UNLINKED 1 /* Phase 3 */ #define PROG_FMT_UNCERTAIN 2 #define PROG_FMT_PROCESS_INO 3 #define PROG_FMT_NEW_INODES 4 #define PROG_FMT_DUP_EXTENT 5 /* Phase 4 */ #define PROG_FMT_INIT_RTEXT 6 #define PROG_FMT_RESET_RTBM 7 #define PROG_FMT_DUP_BLOCKS 8 #define PROG_FMT_REBUILD_AG 9 /* Phase 5 */ #define PROG_FMT_TRAVERSAL 10 /* Phase 6 */ #define PROG_FMT_TRAVERSSUB 11 #define PROG_FMT_DISCONINODE 12 #define PROGRESS_FMT_CORR_LINK 13 /* Phase 7 */ #define PROGRESS_FMT_VRFY_LINK 14 #define DURATION_BUF_SIZE 512 extern void init_progress_rpt(void); extern void stop_progress_rpt(void); extern void summary_report(void); extern int set_progress_msg(int report, __uint64_t total); extern __uint64_t print_final_rpt(void); extern char *timestamp(int end, int phase, char *buf); extern char *duration(int val, char *buf); extern int do_parallel; #define PROG_RPT_INC(a,b) if (ag_stride && prog_rpt_done) (a) += (b) #endif /* _XFS_REPAIR_PROGRESS_RPT_H_ */ xfsprogs-3.1.9ubuntu2/repair/phase4.c0000664000000000000000000002112112062210562014417 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "dir.h" #include "bmap.h" #include "versions.h" #include "dir2.h" #include "threads.h" #include "progress.h" #include "prefetch.h" /* * null out quota inode fields in sb if they point to non-existent inodes. * this isn't as redundant as it looks since it's possible that the sb field * might be set but the imap and inode(s) agree that the inode is * free in which case they'd never be cleared so the fields wouldn't * be cleared by process_dinode(). */ static void quotino_check(xfs_mount_t *mp) { ino_tree_node_t *irec; if (mp->m_sb.sb_uquotino != NULLFSINO && mp->m_sb.sb_uquotino != 0) { if (verify_inum(mp, mp->m_sb.sb_uquotino)) irec = NULL; else irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_uquotino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino)); if (irec == NULL || is_inode_free(irec, mp->m_sb.sb_uquotino - irec->ino_startnum)) { mp->m_sb.sb_uquotino = NULLFSINO; lost_uquotino = 1; } else lost_uquotino = 0; } if (mp->m_sb.sb_gquotino != NULLFSINO && mp->m_sb.sb_gquotino != 0) { if (verify_inum(mp, mp->m_sb.sb_gquotino)) irec = NULL; else irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_gquotino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino)); if (irec == NULL || is_inode_free(irec, mp->m_sb.sb_gquotino - irec->ino_startnum)) { mp->m_sb.sb_gquotino = NULLFSINO; if (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) lost_gquotino = 1; else lost_pquotino = 1; } else lost_gquotino = lost_pquotino = 0; } } static void quota_sb_check(xfs_mount_t *mp) { /* * if the sb says we have quotas and we lost both, * signal a superblock downgrade. that will cause * the quota flags to get zeroed. (if we only lost * one quota inode, do nothing and complain later.) * * if the sb says we have quotas but we didn't start out * with any quota inodes, signal a superblock downgrade. * * The sb downgrades are so that older systems can mount * the filesystem. * * if the sb says we don't have quotas but it looks like * we do have quota inodes, then signal a superblock upgrade. * * if the sb says we don't have quotas and we have no * quota inodes, then leave will enough alone. */ if (fs_quotas && (mp->m_sb.sb_uquotino == NULLFSINO || mp->m_sb.sb_uquotino == 0) && (mp->m_sb.sb_gquotino == NULLFSINO || mp->m_sb.sb_gquotino == 0)) { lost_quotas = 1; fs_quotas = 0; } else if (!verify_inum(mp, mp->m_sb.sb_uquotino) && !verify_inum(mp, mp->m_sb.sb_gquotino)) { fs_quotas = 1; } } static void process_ag_func( work_queue_t *wq, xfs_agnumber_t agno, void *arg) { wait_for_inode_prefetch(arg); do_log(_(" - agno = %d\n"), agno); process_aginodes(wq->mp, arg, agno, 0, 1, 0); cleanup_inode_prefetch(arg); /* * now recycle the per-AG duplicate extent records */ release_dup_extent_tree(agno); } static void process_ags( xfs_mount_t *mp) { int i, j; xfs_agnumber_t agno; work_queue_t *queues; prefetch_args_t *pf_args[2]; queues = malloc(thread_count * sizeof(work_queue_t)); if (!libxfs_bcache_overflowed()) { queues[0].mp = mp; create_work_queue(&queues[0], mp, libxfs_nproc()); for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&queues[0], process_ag_func, i, NULL); destroy_work_queue(&queues[0]); } else { if (ag_stride) { /* * create one worker thread for each segment of the volume */ for (i = 0, agno = 0; i < thread_count; i++) { create_work_queue(&queues[i], mp, 1); pf_args[0] = NULL; for (j = 0; j < ag_stride && agno < mp->m_sb.sb_agcount; j++, agno++) { pf_args[0] = start_inode_prefetch(agno, 0, pf_args[0]); queue_work(&queues[i], process_ag_func, agno, pf_args[0]); } } /* * wait for workers to complete */ for (i = 0; i < thread_count; i++) destroy_work_queue(&queues[i]); } else { queues[0].mp = mp; pf_args[0] = start_inode_prefetch(0, 0, NULL); for (i = 0; i < mp->m_sb.sb_agcount; i++) { pf_args[(~i) & 1] = start_inode_prefetch(i + 1, 0, pf_args[i & 1]); process_ag_func(&queues[0], i, pf_args[i & 1]); } } } free(queues); } void phase4(xfs_mount_t *mp) { ino_tree_node_t *irec; xfs_drtbno_t bno; xfs_drtbno_t rt_start; xfs_extlen_t rt_len; xfs_agnumber_t i; xfs_agblock_t j; xfs_agblock_t ag_end; xfs_extlen_t blen; int ag_hdr_len = 4 * mp->m_sb.sb_sectsize; int ag_hdr_block; int bstate; ag_hdr_block = howmany(ag_hdr_len, mp->m_sb.sb_blocksize); do_log(_("Phase 4 - check for duplicate blocks...\n")); do_log(_(" - setting up duplicate extent list...\n")); set_progress_msg(PROG_FMT_DUP_EXTENT, (__uint64_t) glob_agcount); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); /* * we always have a root inode, even if it's free... * if the root is free, forget it, lost+found is already gone */ if (is_inode_free(irec, 0) || !inode_isadir(irec, 0)) { need_root_inode = 1; if (no_modify) do_warn(_("root inode would be lost\n")); else do_warn(_("root inode lost\n")); } for (i = 0; i < mp->m_sb.sb_agcount; i++) { ag_end = (i < mp->m_sb.sb_agcount - 1) ? mp->m_sb.sb_agblocks : mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * i; /* * set up duplicate extent list for this ag */ for (j = ag_hdr_block; j < ag_end; j += blen) { bstate = get_bmap_ext(i, j, ag_end, &blen); switch (bstate) { case XR_E_BAD_STATE: default: do_warn( _("unknown block state, ag %d, block %d\n"), i, j); /* fall through .. */ case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: case XR_E_INUSE: case XR_E_INUSE_FS: case XR_E_INO: case XR_E_FS_MAP: break; case XR_E_MULT: add_dup_extent(i, j, blen); break; } } PROG_RPT_INC(prog_rpt_done[i], 1); } print_final_rpt(); /* * initialize realtime bitmap */ rt_start = 0; rt_len = 0; for (bno = 0; bno < mp->m_sb.sb_rextents; bno++) { bstate = get_rtbmap(bno); switch (bstate) { case XR_E_BAD_STATE: default: do_warn( _("unknown rt extent state, extent %" PRIu64 "\n"), bno); /* fall through .. */ case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: case XR_E_INUSE: case XR_E_INUSE_FS: case XR_E_INO: case XR_E_FS_MAP: if (rt_start == 0) continue; else { /* * add extent and reset extent state */ add_rt_dup_extent(rt_start, rt_len); rt_start = 0; rt_len = 0; } break; case XR_E_MULT: if (rt_start == 0) { rt_start = bno; rt_len = 1; } else if (rt_len == MAXEXTLEN) { /* * large extent case */ add_rt_dup_extent(rt_start, rt_len); rt_start = bno; rt_len = 1; } else rt_len++; break; } } /* * catch tail-case, extent hitting the end of the ag */ if (rt_start != 0) add_rt_dup_extent(rt_start, rt_len); /* * initialize bitmaps for all AGs */ reset_bmaps(mp); do_log(_(" - check for inodes claiming duplicate blocks...\n")); set_progress_msg(PROG_FMT_DUP_BLOCKS, (__uint64_t) mp->m_sb.sb_icount); /* * ok, now process the inodes -- signal 2-pass check per inode. * first pass checks if the inode conflicts with a known * duplicate extent. if so, the inode is cleared and second * pass is skipped. second pass sets the block bitmap * for all blocks claimed by the inode. directory * and attribute processing is turned OFF since we did that * already in phase 3. */ process_ags(mp); print_final_rpt(); /* * free up memory used to track trealtime duplicate extents */ if (rt_start != 0) free_rt_dup_extent_tree(mp); /* * ensure consistency of quota inode pointers in superblock, * make sure they point to real inodes */ quotino_check(mp); quota_sb_check(mp); } xfsprogs-3.1.9ubuntu2/repair/avl.h0000664000000000000000000000626112062210562014032 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __SYS_AVL_H__ #define __SYS_AVL_H__ typedef struct avlnode { struct avlnode *avl_forw; /* pointer to right child (> parent) */ struct avlnode *avl_back; /* pointer to left child (< parent) */ struct avlnode *avl_parent; /* parent pointer */ struct avlnode *avl_nextino; /* next in-order; NULL terminated list*/ char avl_balance; /* tree balance */ } avlnode_t; /* * avl-tree operations */ typedef struct avlops { __psunsigned_t (*avl_start)(avlnode_t *); __psunsigned_t (*avl_end)(avlnode_t *); } avlops_t; #define AVL_START(tree, n) (*(tree)->avl_ops->avl_start)(n) #define AVL_END(tree, n) (*(tree)->avl_ops->avl_end)(n) /* * tree descriptor: * root points to the root of the tree. * firstino points to the first in the ordered list. */ typedef struct avltree_desc { avlnode_t *avl_root; avlnode_t *avl_firstino; avlops_t *avl_ops; short avl_flags; } avltree_desc_t; /* possible values for avl_balance */ #define AVL_BACK 1 #define AVL_BALANCE 0 #define AVL_FORW 2 /* possible values for avl_flags */ #define AVLF_DUPLICITY 0x0001 /* no warnings on insert dups */ /* * 'Exported' avl tree routines */ avlnode_t *avl_insert( avltree_desc_t *tree, avlnode_t *newnode); void avl_delete( avltree_desc_t *tree, avlnode_t *np); void avl_insert_immediate( avltree_desc_t *tree, avlnode_t *afterp, avlnode_t *newnode); void avl_init_tree( avltree_desc_t *tree, avlops_t *ops); static inline avlnode_t * avl_findrange( avltree_desc_t *tree, __psunsigned_t value) { register avlnode_t *np = tree->avl_root; while (np) { if (value < AVL_START(tree, np)) { np = np->avl_back; continue; } if (value >= AVL_END(tree, np)) { np = np->avl_forw; continue; } ASSERT(AVL_START(tree, np) <= value && value < AVL_END(tree, np)); return np; } return NULL; } avlnode_t * avl_find( avltree_desc_t *tree, __psunsigned_t value); avlnode_t * avl_findanyrange( avltree_desc_t *tree, __psunsigned_t start, __psunsigned_t end, int checklen); avlnode_t * avl_findadjacent( avltree_desc_t *tree, __psunsigned_t value, int dir); void avl_findranges( register avltree_desc_t *tree, register __psunsigned_t start, register __psunsigned_t end, avlnode_t **startp, avlnode_t **endp); avlnode_t * avl_firstino( avlnode_t *root); avlnode_t * avl_lastino( avlnode_t *root); #define AVL_PRECEED 0x1 #define AVL_SUCCEED 0x2 #define AVL_INCLUDE_ZEROLEN 0x0000 #define AVL_EXCLUDE_ZEROLEN 0x0001 #endif /* __SYS_AVL_H__ */ xfsprogs-3.1.9ubuntu2/repair/xfs_repair.c0000664000000000000000000005306012062210562015404 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "avl.h" #include "avl64.h" #include "globals.h" #include "versions.h" #include "agheader.h" #include "protos.h" #include "incore.h" #include "err_protos.h" #include "prefetch.h" #include "threads.h" #include "progress.h" #define rounddown(x, y) (((x)/(y))*(y)) #define XR_MAX_SECT_SIZE (64 * 1024) /* * option tables for getsubopt calls */ /* * -o: user-supplied override options */ static char *o_opts[] = { #define ASSUME_XFS 0 "assume_xfs", #define PRE_65_BETA 1 "fs_is_pre_65_beta", #define IHASH_SIZE 2 "ihash", #define BHASH_SIZE 3 "bhash", #define AG_STRIDE 4 "ag_stride", #define FORCE_GEO 5 "force_geometry", #define PHASE2_THREADS 6 "phase2_threads", NULL }; /* * -c: conversion options */ static char *c_opts[] = { #define CONVERT_LAZY_COUNT 0 "lazycount", NULL }; static int ihash_option_used; static int bhash_option_used; static long max_mem_specified; /* in megabytes */ static int phase2_threads = 32; static void usage(void) { do_warn(_( "Usage: %s [options] device\n" "\n" "Options:\n" " -f The device is a file\n" " -L Force log zeroing. Do this as a last resort.\n" " -l logdev Specifies the device where the external log resides.\n" " -m maxmem Maximum amount of memory to be used in megabytes.\n" " -n No modify mode, just checks the filesystem for damage.\n" " -P Disables prefetching.\n" " -r rtdev Specifies the device where the realtime section resides.\n" " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" " -t interval Reporting interval in minutes.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n"), progname); exit(1); } char * err_string(int err_code) { static char *err_message[XR_BAD_ERR_CODE]; static int done; if (!done) { err_message[XR_OK] = _("no error"); err_message[XR_BAD_MAGIC] = _("bad magic number"); err_message[XR_BAD_BLOCKSIZE] = _("bad blocksize field"); err_message[XR_BAD_BLOCKLOG] = _("bad blocksize log field"); err_message[XR_BAD_VERSION] = _("bad or unsupported version"); err_message[XR_BAD_INPROGRESS] = _("filesystem mkfs-in-progress bit set"); err_message[XR_BAD_FS_SIZE_DATA] = _("inconsistent filesystem geometry information"); err_message[XR_BAD_INO_SIZE_DATA] = _("bad inode size or inconsistent with number of inodes/block"), err_message[XR_BAD_SECT_SIZE_DATA] = _("bad sector size"); err_message[XR_AGF_GEO_MISMATCH] = _("AGF geometry info conflicts with filesystem geometry"); err_message[XR_AGI_GEO_MISMATCH] = _("AGI geometry info conflicts with filesystem geometry"); err_message[XR_SB_GEO_MISMATCH] = _("AG superblock geometry info conflicts with filesystem geometry"); err_message[XR_EOF] = _("attempted to perform I/O beyond EOF"); err_message[XR_BAD_RT_GEO_DATA] = _("inconsistent filesystem geometry in realtime filesystem component"); err_message[XR_BAD_INO_MAX_PCT] = _("maximum indicated percentage of inodes > 100%"); err_message[XR_BAD_INO_ALIGN] = _("inconsistent inode alignment value"); err_message[XR_INSUFF_SEC_SB] = _("not enough secondary superblocks with matching geometry"); err_message[XR_BAD_SB_UNIT] = _("bad stripe unit in superblock"); err_message[XR_BAD_SB_WIDTH] = _("bad stripe width in superblock"); err_message[XR_BAD_SVN] = _("bad shared version number in superblock"); done = 1; } if (err_code < XR_OK || err_code >= XR_BAD_ERR_CODE) do_abort(_("bad error code - %d\n"), err_code); return(err_message[err_code]); } static void noval(char opt, char *tbl[], int idx) { do_warn(_("-%c %s option cannot have a value\n"), opt, tbl[idx]); usage(); } static void respec(char opt, char *tbl[], int idx) { do_warn("-%c ", opt); if (tbl) do_warn("%s ", tbl[idx]); do_warn(_("option respecified\n")); usage(); } static void unknown(char opt, char *s) { do_warn(_("unknown option -%c %s\n"), opt, s); usage(); } /* * sets only the global argument flags and variables */ static void process_args(int argc, char **argv) { char *p; int c; log_spec = 0; fs_is_dirty = 0; verbose = 0; no_modify = 0; dangerously = 0; isa_file = 0; zap_log = 0; dumpcore = 0; full_ino_ex_data = 0; delete_attr_ok = 1; force_geo = 0; assume_xfs = 0; clear_sunit = 0; sb_inoalignmt = 0; sb_unit = 0; sb_width = 0; fs_attributes_allowed = 1; fs_attributes2_allowed = 1; fs_inode_nlink_allowed = 1; fs_quotas_allowed = 1; fs_aligned_inodes_allowed = 1; fs_sb_feature_bits_allowed = 1; fs_has_extflgbit_allowed = 1; pre_65_beta = 0; fs_shared_allowed = 1; ag_stride = 0; thread_count = 1; report_interval = PROG_RPT_DEFAULT; /* * XXX have to add suboption processing here * attributes, quotas, nlinks, aligned_inos, sb_fbits */ while ((c = getopt(argc, argv, "c:o:fl:m:r:LnDvVdPt:")) != EOF) { switch (c) { case 'D': dumpcore = 1; break; case 'o': p = optarg; while (*p != '\0') { char *val; switch (getsubopt(&p, (constpp)o_opts, &val)) { case ASSUME_XFS: if (val) noval('o', o_opts, ASSUME_XFS); if (assume_xfs) respec('o', o_opts, ASSUME_XFS); assume_xfs = 1; break; case PRE_65_BETA: if (val) noval('o', o_opts, PRE_65_BETA); if (pre_65_beta) respec('o', o_opts, PRE_65_BETA); pre_65_beta = 1; break; case IHASH_SIZE: libxfs_ihash_size = (int)strtol(val, NULL, 0); ihash_option_used = 1; break; case BHASH_SIZE: if (max_mem_specified) do_abort( _("-o bhash option cannot be used with -m option\n")); libxfs_bhash_size = (int)strtol(val, NULL, 0); bhash_option_used = 1; break; case AG_STRIDE: ag_stride = (int)strtol(val, NULL, 0); break; case FORCE_GEO: if (val) noval('o', o_opts, FORCE_GEO); if (force_geo) respec('o', o_opts, FORCE_GEO); force_geo = 1; break; case PHASE2_THREADS: phase2_threads = (int)strtol(val, NULL, 0); break; default: unknown('o', val); break; } } break; case 'c': p = optarg; while (*p) { char *val; switch (getsubopt(&p, (constpp)c_opts, &val)) { case CONVERT_LAZY_COUNT: lazy_count = (int)strtol(val, NULL, 0); convert_lazy_count = 1; break; default: unknown('c', val); break; } } break; case 'l': log_name = optarg; log_spec = 1; break; case 'r': rt_name = optarg; rt_spec = 1; break; case 'f': isa_file = 1; break; case 'm': if (bhash_option_used) do_abort(_("-m option cannot be used with " "-o bhash option\n")); max_mem_specified = strtol(optarg, NULL, 0); break; case 'L': zap_log = 1; break; case 'n': no_modify = 1; break; case 'd': dangerously = 1; break; case 'v': verbose++; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case 'P': do_prefetch = 0; break; case 't': report_interval = (int)strtol(optarg, NULL, 0); break; case '?': usage(); } } if (argc - optind != 1) usage(); if ((fs_name = argv[optind]) == NULL) usage(); } void __attribute__((noreturn)) do_error(char const *msg, ...) { va_list args; fprintf(stderr, _("\nfatal error -- ")); va_start(args, msg); vfprintf(stderr, msg, args); if (dumpcore) abort(); exit(1); } /* * like do_error, only the error is internal, no system * error so no oserror processing */ void __attribute__((noreturn)) do_abort(char const *msg, ...) { va_list args; va_start(args, msg); vfprintf(stderr, msg, args); if (dumpcore) abort(); exit(1); } void do_warn(char const *msg, ...) { va_list args; fs_is_dirty = 1; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } /* no formatting */ void do_log(char const *msg, ...) { va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } static void calc_mkfs(xfs_mount_t *mp) { xfs_agblock_t fino_bno; int do_inoalign; do_inoalign = mp->m_sinoalign; /* * pre-calculate geometry of ag 0. We know what it looks * like because we know what mkfs does -- 3 btree roots, * and some number of blocks to prefill the agfl. */ bnobt_root = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); bcntbt_root = bnobt_root + 1; inobt_root = bnobt_root + 2; fino_bno = inobt_root + XFS_MIN_FREELIST_RAW(1, 1, mp) + 1; /* * If the log is allocated in the first allocation group we need to * add the number of blocks used by the log to the above calculation. * * This can happens with filesystems that only have a single * allocation group, or very odd geometries created by old mkfs * versions on very small filesystems. */ if (mp->m_sb.sb_logstart && XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0) { /* * XXX(hch): verify that sb_logstart makes sense? */ fino_bno += mp->m_sb.sb_logblocks; } /* * ditto the location of the first inode chunks in the fs ('/') */ if (xfs_sb_version_hasdalign(&mp->m_sb) && do_inoalign) { first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, roundup(fino_bno, mp->m_sb.sb_unit), 0); } else if (xfs_sb_version_hasalign(&mp->m_sb) && mp->m_sb.sb_inoalignmt > 1) { first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, roundup(fino_bno, mp->m_sb.sb_inoalignmt), 0); } else { first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, fino_bno, 0); } ASSERT(XFS_IALLOC_BLOCKS(mp) > 0); if (XFS_IALLOC_BLOCKS(mp) > 1) last_prealloc_ino = first_prealloc_ino + XFS_INODES_PER_CHUNK; else last_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, fino_bno + 1, 0); /* * now the first 3 inodes in the system */ if (mp->m_sb.sb_rootino != first_prealloc_ino) { do_warn( _("sb root inode value %" PRIu64 " %sinconsistent with calculated value %u\n"), mp->m_sb.sb_rootino, (mp->m_sb.sb_rootino == NULLFSINO ? "(NULLFSINO) ":""), first_prealloc_ino); if (!no_modify) do_warn( _("resetting superblock root inode pointer to %u\n"), first_prealloc_ino); else do_warn( _("would reset superblock root inode pointer to %u\n"), first_prealloc_ino); /* * just set the value -- safe since the superblock * doesn't get flushed out if no_modify is set */ mp->m_sb.sb_rootino = first_prealloc_ino; } if (mp->m_sb.sb_rbmino != first_prealloc_ino + 1) { do_warn( _("sb realtime bitmap inode %" PRIu64 " %sinconsistent with calculated value %u\n"), mp->m_sb.sb_rbmino, (mp->m_sb.sb_rbmino == NULLFSINO ? "(NULLFSINO) ":""), first_prealloc_ino + 1); if (!no_modify) do_warn( _("resetting superblock realtime bitmap ino pointer to %u\n"), first_prealloc_ino + 1); else do_warn( _("would reset superblock realtime bitmap ino pointer to %u\n"), first_prealloc_ino + 1); /* * just set the value -- safe since the superblock * doesn't get flushed out if no_modify is set */ mp->m_sb.sb_rbmino = first_prealloc_ino + 1; } if (mp->m_sb.sb_rsumino != first_prealloc_ino + 2) { do_warn( _("sb realtime summary inode %" PRIu64 " %sinconsistent with calculated value %u\n"), mp->m_sb.sb_rsumino, (mp->m_sb.sb_rsumino == NULLFSINO ? "(NULLFSINO) ":""), first_prealloc_ino + 2); if (!no_modify) do_warn( _("resetting superblock realtime summary ino pointer to %u\n"), first_prealloc_ino + 2); else do_warn( _("would reset superblock realtime summary ino pointer to %u\n"), first_prealloc_ino + 2); /* * just set the value -- safe since the superblock * doesn't get flushed out if no_modify is set */ mp->m_sb.sb_rsumino = first_prealloc_ino + 2; } } int main(int argc, char **argv) { xfs_mount_t *temp_mp; xfs_mount_t *mp; xfs_dsb_t *dsb; xfs_buf_t *sbp; xfs_mount_t xfs_m; char *msgbuf; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); temp_mp = &xfs_m; setbuf(stdout, NULL); process_args(argc, argv); xfs_init(&x); msgbuf = malloc(DURATION_BUF_SIZE); timestamp(PHASE_START, 0, NULL); timestamp(PHASE_END, 0, NULL); /* do phase1 to make sure we have a superblock */ phase1(temp_mp); timestamp(PHASE_END, 1, NULL); if (no_modify && primary_sb_modified) { do_warn(_("Primary superblock would have been modified.\n" "Cannot proceed further in no_modify mode.\n" "Exiting now.\n")); exit(1); } /* prepare the mount structure */ sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR, 1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0); memset(&xfs_m, 0, sizeof(xfs_mount_t)); libxfs_sb_from_disk(&xfs_m.m_sb, XFS_BUF_TO_SBP(sbp)); /* * if the sector size of the filesystem we are trying to repair is * smaller than that of the underlying filesystem (i.e. we are repairing * an image), the we have to turn off direct IO because we cannot do IO * smaller than the host filesystem's sector size. */ if (isa_file) { int fd = libxfs_device_to_fd(x.ddev); struct xfs_fsop_geom_v1 geom = { 0 }; if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) { do_warn(_("Cannot get host filesystem geometry.\n" "Repair may fail if there is a sector size mismatch between\n" "the image and the host filesystem.\n")); geom.sectsize = BBSIZE; } if (xfs_m.m_sb.sb_sectsize < geom.sectsize) { long old_flags; old_flags = fcntl(fd, F_GETFL, 0); if (fcntl(fd, F_SETFL, old_flags & ~O_DIRECT) < 0) { do_warn(_( "Sector size on host filesystem larger than image sector size.\n" "Cannot turn off direct IO, so exiting.\n")); exit(1); } } } mp = libxfs_mount(&xfs_m, &xfs_m.m_sb, x.ddev, x.logdev, x.rtdev, 0); if (!mp) { fprintf(stderr, _("%s: cannot repair this filesystem. Sorry.\n"), progname); exit(1); } libxfs_putbuf(sbp); libxfs_purgebuf(sbp); /* * set XFS-independent status vars from the mount/sb structure */ glob_agcount = mp->m_sb.sb_agcount; chunks_pblock = mp->m_sb.sb_inopblock / XFS_INODES_PER_CHUNK; max_symlink_blocks = howmany(MAXPATHLEN - 1, mp->m_sb.sb_blocksize); inodes_per_cluster = MAX(mp->m_sb.sb_inopblock, XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); if (ag_stride) { thread_count = (glob_agcount + ag_stride - 1) / ag_stride; thread_init(); } if (ag_stride && report_interval) { init_progress_rpt(); if (msgbuf) { do_log(_(" - reporting progress in intervals of %s\n"), duration(report_interval, msgbuf)); } } /* * Adjust libxfs cache sizes based on system memory, * filesystem size and inode count. * * We'll set the cache size based on 3/4s the memory minus * space used by the inode AVL tree and block usage map. * * Inode AVL tree space is approximately 4 bytes per inode, * block usage map is currently 1 byte for 2 blocks. * * We assume most blocks will be inode clusters. * * Calculations are done in kilobyte units. */ if (!bhash_option_used || max_mem_specified) { unsigned long mem_used; unsigned long max_mem; struct rlimit rlim; libxfs_icache_purge(); libxfs_bcache_purge(); cache_destroy(libxfs_icache); cache_destroy(libxfs_bcache); mem_used = (mp->m_sb.sb_icount >> (10 - 2)) + (mp->m_sb.sb_dblocks >> (10 + 1)) + 50000; /* rough estimate of 50MB overhead */ max_mem = max_mem_specified ? max_mem_specified * 1024 : libxfs_physmem() * 3 / 4; if (getrlimit(RLIMIT_AS, &rlim) != -1 && rlim.rlim_cur != RLIM_INFINITY) { rlim.rlim_cur = rlim.rlim_max; setrlimit(RLIMIT_AS, &rlim); /* use approximately 80% of rlimit to avoid overrun */ max_mem = MIN(max_mem, rlim.rlim_cur / 1280); } else max_mem = MIN(max_mem, (LONG_MAX >> 10) + 1); if (verbose > 1) do_log( _(" - max_mem = %lu, icount = %" PRIu64 ", imem = %" PRIu64 ", dblock = %" PRIu64 ", dmem = %" PRIu64 "\n"), max_mem, mp->m_sb.sb_icount, mp->m_sb.sb_icount >> (10 - 2), mp->m_sb.sb_dblocks, mp->m_sb.sb_dblocks >> (10 + 1)); if (max_mem <= mem_used) { /* * Turn off prefetch and minimise libxfs cache if * physical memory is deemed insufficient */ if (max_mem_specified) { do_abort( _("Required memory for repair is greater that the maximum specified\n" "with the -m option. Please increase it to at least %lu.\n"), mem_used / 1024); } else { do_warn( _("Not enough RAM available for repair to enable prefetching.\n" "This will be _slow_.\n" "You need at least %luMB RAM to run with prefetching enabled.\n"), mem_used * 1280 / (1024 * 1024)); } do_prefetch = 0; libxfs_bhash_size = 64; } else { max_mem -= mem_used; if (max_mem >= (1 << 30)) max_mem = 1 << 30; libxfs_bhash_size = max_mem / (HASH_CACHE_RATIO * (mp->m_inode_cluster_size >> 10)); if (libxfs_bhash_size < 512) libxfs_bhash_size = 512; } if (verbose) do_log(_(" - block cache size set to %d entries\n"), libxfs_bhash_size * HASH_CACHE_RATIO); if (!ihash_option_used) libxfs_ihash_size = libxfs_bhash_size; libxfs_icache = cache_init(libxfs_ihash_size, &libxfs_icache_operations); libxfs_bcache = cache_init(libxfs_bhash_size, &libxfs_bcache_operations); } /* * calculate what mkfs would do to this filesystem */ calc_mkfs(mp); /* * initialize block alloc map */ init_bmaps(mp); incore_ino_init(mp); incore_ext_init(mp); /* initialize random globals now that we know the fs geometry */ inodes_per_block = mp->m_sb.sb_inopblock; if (parse_sb_version(&mp->m_sb)) { do_warn( _("Found unsupported filesystem features. Exiting now.\n")); return(1); } /* make sure the per-ag freespace maps are ok so we can mount the fs */ phase2(mp, phase2_threads); timestamp(PHASE_END, 2, NULL); if (do_prefetch) init_prefetch(mp); phase3(mp); timestamp(PHASE_END, 3, NULL); phase4(mp); timestamp(PHASE_END, 4, NULL); if (no_modify) printf(_("No modify flag set, skipping phase 5\n")); else { phase5(mp); } timestamp(PHASE_END, 5, NULL); /* * Done with the block usage maps, toss them... */ free_bmaps(mp); if (!bad_ino_btree) { phase6(mp); timestamp(PHASE_END, 6, NULL); phase7(mp); timestamp(PHASE_END, 7, NULL); } else { do_warn( _("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n")); } if (lost_quotas && !have_uquotino && !have_gquotino) { if (!no_modify) { do_warn( _("Warning: no quota inodes were found. Quotas disabled.\n")); } else { do_warn( _("Warning: no quota inodes were found. Quotas would be disabled.\n")); } } else if (lost_quotas) { if (!no_modify) { do_warn( _("Warning: quota inodes were cleared. Quotas disabled.\n")); } else { do_warn( _("Warning: quota inodes would be cleared. Quotas would be disabled.\n")); } } else { if (lost_uquotino) { if (!no_modify) { do_warn( _("Warning: user quota information was cleared.\n" "User quotas can not be enforced until limit information is recreated.\n")); } else { do_warn( _("Warning: user quota information would be cleared.\n" "User quotas could not be enforced until limit information was recreated.\n")); } } if (lost_gquotino) { if (!no_modify) { do_warn( _("Warning: group quota information was cleared.\n" "Group quotas can not be enforced until limit information is recreated.\n")); } else { do_warn( _("Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n")); } } if (lost_pquotino) { if (!no_modify) { do_warn( _("Warning: project quota information was cleared.\n" "Project quotas can not be enforced until limit information is recreated.\n")); } else { do_warn( _("Warning: project quota information would be cleared.\n" "Project quotas could not be enforced until limit information was recreated.\n")); } } } if (ag_stride && report_interval) stop_progress_rpt(); if (no_modify) { do_log( _("No modify flag set, skipping filesystem flush and exiting.\n")); if (verbose) summary_report(); if (fs_is_dirty) return(1); return(0); } /* * Clear the quota flags if they're on. */ sbp = libxfs_getsb(mp, 0); if (!sbp) do_error(_("couldn't get superblock\n")); dsb = XFS_BUF_TO_SBP(sbp); if (be16_to_cpu(dsb->sb_qflags) & (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)) { do_warn(_("Note - quota info will be regenerated on next " "quota mount.\n")); dsb->sb_qflags &= cpu_to_be16(~(XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)); } if (clear_sunit) { do_warn( _("Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n"), be32_to_cpu(dsb->sb_unit), be32_to_cpu(dsb->sb_width)); dsb->sb_unit = 0; dsb->sb_width = 0; } libxfs_writebuf(sbp, 0); /* * Done, flush all cached buffers and inodes. */ libxfs_bcache_flush(); libxfs_umount(mp); if (x.rtdev) libxfs_device_close(x.rtdev); if (x.logdev && x.logdev != x.ddev) libxfs_device_close(x.logdev); libxfs_device_close(x.ddev); if (verbose) summary_report(); do_log(_("done\n")); pftrace_done(); return (0); } xfsprogs-3.1.9ubuntu2/repair/README0000664000000000000000000006670711466226660014007 0ustar A living document. The basic algorithm. TODO: (D == DONE) 0) Need to bring some sanity into the case of flags that can be set in the secondaries at mkfs time but reset or cleared in the primary later in the filesystem's life. 0) Clear the persistent read-only bit if set. Clear the shared bit if set and the version number is zero. This brings the filesystem back to a known state. 0) make sure that superblock geometry code checks the logstart value against whether or not we have an internal log. If we have an internal log and a logdev, that's ok. (Maybe we just aren't using it). If we have an external log (logstart == 0) but no logdev, that's right out. 0) write secondary superblock search code. Rewrite initial superblock parsing code to be less complicated. Just use variables to indicate primary, secondary, etc., and use a function to get the SB given a specific location or something. 2) For inode alignment, if the SB bit is set and the inode alignment size field in the SB is set, then believe that the fs inodes MUST be aligned and disallow any non-aligned inodes. Likewise, if the SB bit isn't set (or earlier version) and the inode alignment size field is zero, then never set the bit even if the inodes are aligned. Note that the bits and alignment values are replicated in the secondary superblocks. 0) add feature specification options to parse_arguments 0) add logic to add_inode_ref(), add_inode_reached() to detect nlink overflows in cases where the fs (or user had indicated fs) doesn't support new nlinks. 6) check to make sure that the inodes containing btree blocks with # recs < minrecs aren't legit -- e.g. the only descendant of a root block. 7) inode di_size value sanity checking -- should always be less than the biggest filebno offset mentioned in the bmaps. Doesn't have to be equal though since we're allowed to overallocate (it just wastes a little space). This is for both regular files and directories (have to modify the existing directory check). Add tracking of largest offset in bmap scanning code. Compare value against di_size. Should be >= di_size. Alternatively, you could pass the inode into down through the extent record processing layer and make the checks there. Add knowledge of quota inodes. size of quota inode is always zero. We should maintain that. 8) Basic quota stuff. Invariants if quota feature bit is set, the quota inodes if set, should point to disconnected, 0 len inodes. D - if quota inodes exist, the quota bits must be turned on. It's ok for the quota flags to be zeroed but they should be in a legal state (see xfs_quota.h). D - if the quota flags are non-zero, the corresponding quota inodes must exist. quota inodes are never deleted, only their space is freed. if quotas are being downgraded, then check quota inodes at the end of phase 3. If they haven't been cleared yet, clear them. Regardless, then clear sb flags (quota inode fields, quota flags, and quota bit). 5) look at verify_inode_chunk(). it's probably really broken. 9) Complicated quota stuff. Add code to bmap scan code to track used blocks. Add another pair of AVL trees to track user and project quota limits. Set AVL trees up at the beginning of phase 3. Quota inodes can be rebuilt or corrected later if damaged. D - 0) fix directory processing. phase 3, if an entry references a free inode, *don't* mark it used. wait for the rest of phase 3 processing to hit that inode. If it looks like it's in use, we'll mark in use then. If not, we'll clear it and mark the inode map. then in phase 4, you can depend on the inode map. should probably set the parent info in phase 4. So we have a check_dups flag. Maybe we should change the name of check_dir to discover_inodes. During phase 3 (discover_inodes == 1), uncertain inodes are added to list. During phase 4 (discover_inodes == 0), they aren't. And we never mark inodes in use from the directory code. During phase 4, we shouldn't complain about names with a leading '/' since we made those names in phase 3. Have to change dino_chunks.c (parent setting), dinode.c and dir.c. D - 0) make sure we don't screw up filesystems with real-time inodes. remember to initialize real-time map with all blocks XR_E_FREE. D - 4) check contents of symlinks as well as lengths in process_symlinks() in dinode.c. Right now, we only check lengths. D - 1) Feature mismatches -- for quotas and attributes, if the stuff exists in the filesystem, set the superblock version bits. D - 0) rewrite directory leaf block holemap comparison code. probably should just check the leaf block hole info against our incore bitmap. If the hole flag is not set, then we know that there can only be one hole and it has to be between the entry table and the top of heap. If the hole flag is set, then it's ok if the on-disk holemap doesn't describe everything as long as what it does describe doesn't conflict with reality. D - 0) rewrite setting nlinks handling -- for version 1 inodes, set both nlinks and onlinks (zero projid_lo/hi and pad) if we have to change anything. For version 2, I think we're ok. D - 0) Put awareness of quota inode into mark_standalone_inodes. D - 8) redo handling of superblocks with bad version numbers. need to bail out (without harming) fs's that have sbs that are newer than we are. D - 0) How do we handle feature mismatches between fs and superblock? For nlink, check each inode after you know it's good. If onlinks is 0 and nlinks is > 0 and it's a version 2 inode, then it really is a version 2 inode and the nlinks flag in the SB needs to be set. If it's a version 2 inode and the SB agrees but onlink is non-zero, then clear onlink. D - 3) keep cumulative counts of freeblocks, inodes, etc. to set in the superblock at the end of phase 5. Remember that agf freeblock counters don't include blocks used by the non-root levels of the freespace trees but that the sb free block counters include those. D - 0) Do parent setting in directory code (called by phase 3). actually, I put it in process_inode_set and propagated the parent up to it from the process_dinode/process_dir routines. seemed cleaner than pushing the irec down and letting them bang on it. D - 0) If we clear a file in phase 4, make sure that if it's a directory that the parent info is cleared also. D - 0) put inode tree flashover (call to add_ino_backptrs) into phase 5. D - 0) do set/get_inode_parent functions in incore_ino.c. also do is/set/ inode_processed. D - 0) do a versions.c to extract feature info and set global vars from the superblock version number and possibly feature bits D - 0) change longform_dir_entry_check + shortform_dir_entry_check to return a count of how many illegal '/' entries exist. if > 0, then process_dirstack needs to call prune_dir_entry with a hash value of 0 to delete the entries. D - 0) add the "processed" bitfield to the backptrs_t struct that gets attached after phase 4. D- ) Phase 6 !!! D - 0) look at usage of XFS_MAKE_IPTR(). It does the right arithmetic assuming you count your offsets from the beginning of the buffer. D - 0) look at references to XFS_INODES_PER_CHUNK. change the ones that really mean sizeof(__uint64_t)*NBBY to something else (like that only defined as a constant INOS_PER_IREC. this isn't as important since XFS_INODES_PER_CHUNK will never chang D - 0) look at junk_zerolen_dir_leaf_entries() to make sure it isn't hosing the freemap since it assumed that bytes between the end of the table and firstused didn't show up in the freemap when they actually do. D - 0) track down XFS_INO_TO_OFFSET() usage. I don't think I'm using it right. (e.g. I think it gives you the offset of an inode into a block but on small block filesystems, I may be reading in inodes in multiblock buffers and working from the start of the buffer plus I'm using it to get offsets into my ino_rec's which may not be a good idea since I use 64-inode ino_rec's whereas the offset macro works off blocksize). D - 0.0) put buffer -> dirblock conversion macros into xfs kernel code D - 0.2) put in sibling pointer checking and path fixup into bmap (long form) scan routines in scan.c D - 0.3) find out if bmap btrees with only root blocks are legal. I'm betting that they're not because they'd be extent inodes instead. If that's the case, rip some code out of process_btinode() Algorithm (XXX means not done yet): Phase 1 -- get a superblock and zero log get a superblock -- either read in primary or find a secondary (ag header), check ag headers To find secondary: Go for brute force and read in the filesystem N meg at a time looking for a superblock. as a slight optimization, we could maybe skip ahead some number of blocks to try and get towards the end of the first ag. After you find a secondary, try and find at least other ags as a verification that the secondary is a good superblock. XXX - Ugh. Have to take growfs'ed filesystems into account. The root superblock geometry info may not be right if recovery hasn't run or it's been trashed. The old ag's may or may not be right since the system could have crashed during growfs or the bwrite() to the superblocks could have failed and the buffer been reused. So we need to check to see if another ag exists beyond the "last" ag to see if a growfs happened. If not, then we know that the geometry info is good and treat the fs as a non-growfs'ed fs. If we do have inconsistencies, then the smaller geometry is the old fs and the larger the new. We can check the new superblocks to see if they're good. If not, then we know the system crashed at or soon after the growfs and we can choose to either accept the new geometry info or trash it and truncate the fs back to the old geometry parameters. Cross-check geometry information in secondary sb's with primary to ensure that it's correct. Use sim code to allow mount filesystems *without* reading in root inode. This sets up the xfs_mount_t structure and allows us to use XFS_* macros that we wouldn't otherwise be able to use. Note, I split phase 1 and 2 into separate pieces because I want to initialize the xfs_repair incore data structures after phase 1. parse superblock version and feature flags and set appropriate global vars to reflect the flags (attributes, quotas, etc.) Workaround for the mkfs "not zeroing the superblock buffer" bug. Determine what field is the last valid non-zero field in the superblock. The trick here is to be able to differentiate the last valid non-zero field in the primary superblock and secondaries because they may not be the same. Fields in the primary can be set as the filesystem gets upgraded but the upgrades won't touch the secondaries. This means that we need to find some number of secondaries and check them. So we do the checking here and the setting in phase2. Phase 2 -- check integrity of allocation group allocation structures zero the log if in no modify mode sanity check ag headers -- superblocks match, agi isn't trashed -- the agf and agfl don't really matter because we can just recreate them later. Zero part of the superblock buffer if necessary Walk the freeblock trees to get an initial idea of what the fs thinks is free. Files that disagree (claim free'd blocks) can be salvaged or deleted. If the btree is internally inconsistent, when in doubt, mark blocks free. If they're used, they'll be stolen back later. don't have to check sibling pointers for each level since we're going to regenerate all the trees anyway. Walk the inode allocation trees and make sure they're ok, otherwise the sim inode routines will probably just barf. mark inode allocation tree blocks and ag header blocks as used blocks. If the trees are corrupted, this phase will generate "uncertain" inode chunks. Those chunks go on a list and will have to verified later. Record the blocks that are used to detect corruption and multiply claimed blocks. These trees will be regenerated later. Mark the blocks containing inodes referenced by uncorrupted inode trees as being used by inodes. The other blocks will get marked when/if the inodes are verified. calculate root and realtime inode numbers from the filesystem geometry, fix up mount structure's incore superblock if they're wrong. ASSUMPTION: at end of phase 2, we've got superblocks and ag headers that are not garbage (some data in them like counters and the freeblock and inode trees may be inconsistent but the header is readable and otherwise makes sense). XXX if in no_modify mode, check for blocks claimed by one freespace btree and not the other Phase 3 -- traverse inodes to make the inodes, bmaps and freespace maps consistent. For each ag, use either the incore inode map or scan the ag for inodes. Let's use the incore inode map, now that we've made one up in phase2. If we lose the maps, we'll locate inodes when we traverse the directory heirarchy. If we lose both, we could scan the disk. Ugh. Maybe make that a command-line option that we support later. ASSUMPTION: we know if the ag allocation btrees are intact (phase 2) First - Walk and clear the ag unlinked lists. We'll process the inodes later. Check and make sure that the unlinked lists reference known inodes. If not, add to the list of uncertain inodes. Second, check the uncertain inode list generated in phase2 and above and get them into the inode tree if they're good. The incore inode cluster tree *always* has good clusters (alignment, etc.) in it. Third, make sure that the root inode is known. If not, and we know the inode number from the superblock, discover that inode and its chunk. Then, walk the incore inode-cluster tree. Maintain an in-core bitmap over the entire fs for block allocation. traverse each inode, make sure inode mode field matches free/allocated bit in the incore inode allocation tree. If there's a mismatch, assume that the inode is in use. - for each in-use inode, traverse each bmap/dir/attribute map or tree. Maintain a map (extent list?) for the current inode. - For each block marked as used, check to see if already known (referenced by another file or directory) and sanity check the contents of the block as well if possible (in the case of meta-blocks). - if the inode claims already used blocks, mark the blocks as multiply claimed (duplicate) and go on. the inode will be cleared in phase 4. - if metablocks are garbaged, clear the inode after traversing what you can of the bmap and proceed to next inode. We don't have to worry about trashing the maps or trees in cleared inodes because the blocks will show up as free in the ag freespace trees that we set up in phase 5. - clear the di_next_unlinked pointer -- all unlinked but active files go bye-bye. - All blocks start out unknown. We need the last state in case we run into a case where we need to step on a block to store filesystem meta-data and it turns out later that it's referenced by some inode's bmap. In that case, the inode loses because we've already trashed the block. This shouldn't happen in the first version unless some inode has a bogus bmap referencing blocks in the ag header but the 4th state will keep us from inadvertently doing something stupid in that case. - If inode is allocated, mark all blocks allocated to the current inode as allocated in the incore freespace bitmap. - If inode is good and a directory, scan through it to find leaf entries and discover any unknown inodes. For shortform, we correct what we can. If the directory is corrupt, we try and fix it in place. If it has zero good entries, then we blast it. All unknown inodes get put onto the uncertain inode list. This is safe because we only put inodes onto the list when we're processing known inodes so the uncertain inode list isn't in use. We fix only one problem -- an entry that has a mathematically invalid inode numbers in them. If that's the case, we replace the inode number with NULLFSINO and we'll fix up the entry in phase 6. That info may conflict with the inode information, but we'll straighten out any inconsistencies there in phase4 when we process the inodes again. Errors involving bogus forward/back links, zero-length entries make the directory get trashed. if an entry references a free inode, ignore that fact for now. wait for the rest of phase 3 processing to hit that inode. If it looks like it's in use, we'll mark in use then. If not, we'll clear it and mark the inode map. then in phase 4, you can depend on the inode map. Entries that point to non-existent or free inodes, and extra blocks in the directory will get fixed in place in a later pass. Entries that point to a quota inode are marked TBD. If the directory internally points to the same block twice, the directory gets blown away. Note that processing uncertain inodes can add more inodes to the uncertain list if they're directories. So we loop until the uncertain list is empty. During inode verification, if the inode blocks are unknown, mark then as in-use by inodes. XXX HEURISTIC -- if we blow an inode away that has space, assume that the freespace btree is now out of wack. If it was ok earlier, it's certain to be wrong now. And the odds of this space free cancelling out the existing error is so small I'm willing to ignore it. Should probably do this via a global var and complain about this later. Assumption: All known inodes are now marked as in-use or free. Any inodes that we haven't found by now are hosed (lost) since we can't reach them via either the inode btrees or via directory entries. Directories are semi-clean. All '.' entries are good. Root '..' entry is good if root inode exists. All entries referencing non-existent inodes, free inodes, etc. XXX verify that either quota inode is 0 or NULLFSINO or if sb quota flag is non zero, verify that quota inode is NULLFSINO or is referencing a used, but disconnected inode. XXX if in no_modify mode, check for unclaimed blocks - Phase 4 - Check for inodes referencing duplicate blocks At this point, all known duplicate blocks are marked in the block map. However, some of the claimed blocks in the bmap may in fact be free because they belong to inodes that have to be cleared either due to being a trashed directory or because it's the first inode to claim a block that was then claimed later. There's a similar problem with meta-data blocks that are referenced by inode bmaps that are going to be freed once the inode (or directory) gets cleared. So at this point, we collect the duplicate blocks into extents and put them into the duplicate extent list. Mark the ag header blocks as in use. We then process each inode twice -- the first time we check to see if the inode claims a duplicate extent and we do NOT set the block bitmap. If the inode claims a duplicate extent, we clear the inode. Since the bitmap hasn't been set, that automatically frees all blocks associated with the cleared inode. If the inode is ok, process it a second time and set the bitmap since we know that this inode will live. The unlinked list gets cleared in every inode at this point as well. We no longer need to preserve it since we've discovered every inode we're going to find from it. verify existence of root inode. if it exists, check for existence of "lost+found". If it exists, mark the entry to be deleted, and clear the inode. All the inodes that were connected to the lost+found will be reconnected later. XXX HEURISTIC -- if we blow an inode away that has space, assume that the freespace btree is now out of wack. If it was ok earlier, it's certain to be wrong now. And the odds of this space free cancelling out the existing error is so small I'm willing to ignore it. Should probably do this via a global var and complain about this later. Clear the quota inodes if the inode btree says that they're not in use. The space freed will get picked up by phase 5. XXX Clear the quota inodes if the filesystem is being downgraded. - Phase 5 - Build inode allocation trees, freespace trees and agfl's for each ag. After this, we should be able to unmount the filesystem and remount it for real. For each ag: (if no in no_modify mode) scan bitmap first to figure out number of extents. calculate space required for all trees. Start with inode trees. Setup the btree cursor which includes the list of preallocated blocks. As a by-product, this will delete the extents required for the inode tree from the incore extent tree. Calculate how many extents will be required to represent the remaining free extent tree on disk (twice, one for bybno and one for bycnt). You have to iterate on this because consuming extents can alter the number of blocks required to represent the remaining extents. If there's slop left over, you can put it in the agfl though. Then, manually build the trees, agi, agfs, and agfls. XXX if in no_modify mode, scan the on-disk inode allocation trees and compare against the incore versions. Don't have to scan the freespace trees because we caught the problems there in phase2 and phase3. But if we cleared any inodes with space during phases 3 or 4, now is the time to complain. XXX - Free duplicate extent lists. ??? Assumptions: at this point, sim code having to do with inode creation/modification/deletion and space allocation work because the inode maps, space maps, and bmaps for all files in the filesystem are good. The only structures that are screwed up are the directory contents, which means that lookup may not work for beans, the root inode which exists but may be completely bogus and the link counts on all inodes which may also be bogus. Free the bitmap, the freespace tree. Flash the incore inode tree over from parent list to having full backpointers. realtime processing, if any -- (Skip to below if running in no_modify mode). Generate the realtime bitmap from the incore realtime extent map and slam the info into the realtime bitmap inode. Generate summary info from the realtime extent map. XXX if in no_modify mode, compare contents of realtime bitmap inode to the incore realtime extent map. generate the summary info from the incore realtime extent map. compare against the contents of the realtime summary inode. complain if bad. reset superblock counters, sync version numbers - Phase 6 - directory traversal -- check reference counts, attach disconnected inodes, fix up bogus directories Assumptions: all on-disk space and inode trees are structurally sound. Incore and on-disk inode trees agree on whether an inode is in use. Directories are structurally sound. All hashvalues are monotonically increasing and interior nodes are correct so lookups work. All legal directory entries point to inodes that are in use and exist. Shortform directories are fine except that the links haven't been checked for conflicts (cycles, ".." being correct, etc.). Longform directories haven't been checked for those problems either PLUS longform directories may still contain entries beginning with '/'. No zero-length entries exist (they've been deleted or converted to '/'). Root directory may or may not exist. orphange may or may not exist. Contents of either may be completely bogus. Entries may point to free or non-existent inodes. At this we point, we may need new incore structures and may be able to trash an old one (like the filesystem block map) If '/' is trashed, then reinitialize it. If no realtime inodes, make them and if necessary, slam the summary info into the realtime summary inode. Ditto with the realtime bitmap inode. Make orphanage (lost+found ???). Traverse each directory from '/' (unless it was created). Check directory structure and each directory entry. If the entry is bogus (points to a non-existent or free inode, for example), mark that entry TBD. Maintain link counts on all inodes. Currently, traversal is depth-first. Mark every inode reached as "reached" (includes bumping up link counts). If a entry points to a directory but the parent (..) disagrees, then blow away the entry. if the directory being pointed to winds up disconnected, it'll be moved to the orphanage (and the link count incremented to account for the link and the reached bit set then). If an entry points to a directory that we've already reached, then some entry is bad and should be blown away. It's easiest to blow away the current entry plus since presumably the parent entry in the reached directory points to another directory, then it's far more likely that the current entry is bogus (otherwise the parent should point at it). If an entry points to a non-existent of free inode, blow the entry away. Every time a good entry is encountered update the link count for the inode that the entry points to. After traversal, scan incore inode map for directories not reached. Go to first one and try and find its root by following .. entries. Once at root, run traversal algorithm. When algorithm terminates, move subtree root inode to the orphanage. Repeat as necessary until all disconnected directories are attached. Move all disconnected inodes to orphanage. - Phase 7: reset reference counts if required. Now traverse the on-disk inodes again, and make sure on-disk reference counts are correct. Reset if necessary. SKIP all unused inodes -- that also makes us skip the orphanage inode which we think is unused but is really used. However, the ref counts on that should be right so that's ok. --- multiple TB xfs_repair modify above to work in a couple of AGs at a time. The bitmaps should span only the current set of AGs. The key it scan the inode bmaps and keep a list of inodes that span multiple AG sets and keep the list in a data structure that's keyed off AG set # as well as inode # and also has a bit to indicate whether or not the inode will be cleared. Then in each AG set, when doing duplicate extent processing, you have to process all multi-AG-set inodes that claim blocks in the current AG set. If there's a conflict, you mark clear the inode in the current AG and you mark the multi-AG inode as "to be cleared". After going through all AGs, you can clear the to-be-cleared multi-AG-set inodes and pull them off the list. When building up the AG freespace trees, you walk the bmaps of all multi-AG-set inodes that are in the AG-set and include blocks claimed in the AG by the inode as used. This probably involves adding a phase 3-0 which would have to check all the inodes to see which ones are multi-AG-set inodes and set up the multi-AG-set inode data structure. Plus the process_dinode routines may have to be altered just a bit to do the right thing if running in tera-byte mode (call out to routines that check the multi-AG-set inodes when appropriate). To make things go faster, phase 3-0 could probably run in parallel. It should be possible to run phases 2-5 in parallel as well once the appropriate synchronization is added to the incore routines and the static directory leaf block bitmap is changed to be on the stack. Phase 7 probably can be in parallel as well. By in parallel, I mean that assuming that an AG-set contains 4 AGs, you could run 4 threads, 1 per AG in parallel to process the AG set. I don't see how phase 6 can be run in parallel though. And running Phase 8 in parallel is just silly. xfsprogs-3.1.9ubuntu2/repair/phase1.c0000664000000000000000000001010312062210562014412 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "globals.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" static void no_sb(void) { do_warn(_("Sorry, could not find valid secondary superblock\n")); do_warn(_("Exiting now.\n")); exit(1); } char * alloc_ag_buf(int size) { char *bp; bp = (char *)memalign(libxfs_device_alignment(), size); if (!bp) do_error(_("could not allocate ag header buffer (%d bytes)\n"), size); return(bp); } /* * this has got to be big enough to hold 4 sectors */ #define MAX_SECTSIZE (512 * 1024) /* ARGSUSED */ void phase1(xfs_mount_t *mp) { xfs_sb_t *sb; char *ag_bp; int rval; do_log(_("Phase 1 - find and verify superblock...\n")); primary_sb_modified = 0; need_root_inode = 0; need_root_dotdot = 0; need_rbmino = 0; need_rsumino = 0; lost_quotas = 0; /* * get AG 0 into ag header buf */ ag_bp = alloc_ag_buf(MAX_SECTSIZE); sb = (xfs_sb_t *) ag_bp; if (get_sb(sb, 0LL, MAX_SECTSIZE, 0) == XR_EOF) do_error(_("error reading primary superblock\n")); /* * is this really an sb, verify internal consistency */ if ((rval = verify_sb(sb, 1)) != XR_OK) { do_warn(_("bad primary superblock - %s !!!\n"), err_string(rval)); if (!find_secondary_sb(sb)) no_sb(); primary_sb_modified = 1; } else if ((rval = verify_set_primary_sb(sb, 0, &primary_sb_modified)) != XR_OK) { do_warn(_("couldn't verify primary superblock - %s !!!\n"), err_string(rval)); if (!find_secondary_sb(sb)) no_sb(); primary_sb_modified = 1; } /* * Check bad_features2 and make sure features2 the same as * bad_features (ORing the two together). Leave bad_features2 * set so older kernels can still use it and not mount unsupported * filesystems when it reads bad_features2. */ if (sb->sb_bad_features2 != 0 && sb->sb_bad_features2 != sb->sb_features2) { sb->sb_features2 |= sb->sb_bad_features2; sb->sb_bad_features2 = sb->sb_features2; primary_sb_modified = 1; do_warn(_("superblock has a features2 mismatch, correcting\n")); } /* * apply any version changes or conversions after the primary * superblock has been verified or repaired * * Send output to stdout as do_log and everything else in repair * is sent to stderr and there is no "quiet" option. xfs_admin * will filter stderr but not stdout. This situation must be improved. */ if (convert_lazy_count) { if (lazy_count && !xfs_sb_version_haslazysbcount(sb)) { sb->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; sb->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT; sb->sb_bad_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT; primary_sb_modified = 1; printf(_("Enabling lazy-counters\n")); } else if (!lazy_count && xfs_sb_version_haslazysbcount(sb)) { sb->sb_features2 &= ~XFS_SB_VERSION2_LAZYSBCOUNTBIT; sb->sb_bad_features2 &= ~XFS_SB_VERSION2_LAZYSBCOUNTBIT; printf(_("Disabling lazy-counters\n")); primary_sb_modified = 1; } else { printf(_("Lazy-counters are already %s\n"), lazy_count ? _("enabled") : _("disabled")); exit(0); /* no conversion required, exit */ } } if (primary_sb_modified) { if (!no_modify) { do_warn(_("writing modified primary superblock\n")); write_primary_sb(sb, sb->sb_sectsize); } else { do_warn(_("would write modified primary superblock\n")); } } /* * misc. global var initialization */ sb_ifree = sb_icount = sb_fdblocks = sb_frextents = 0; free(sb); } xfsprogs-3.1.9ubuntu2/repair/phase3.c0000664000000000000000000001064712062210562014431 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "threads.h" #include "progress.h" #include "prefetch.h" static void process_agi_unlinked( struct xfs_mount *mp, xfs_agnumber_t agno) { struct xfs_buf *bp; struct xfs_agi *agip; xfs_agnumber_t i; int agi_dirty = 0; bp = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), mp->m_sb.sb_sectsize/BBSIZE, 0); if (!bp) do_error(_("cannot read agi block %" PRId64 " for ag %u\n"), XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), agno); agip = XFS_BUF_TO_AGI(bp); ASSERT(be32_to_cpu(agip->agi_seqno) == agno); for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { if (agip->agi_unlinked[i] != cpu_to_be32(NULLAGINO)) { agip->agi_unlinked[i] = cpu_to_be32(NULLAGINO); agi_dirty = 1; } } if (agi_dirty) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); } static void process_ag_func( work_queue_t *wq, xfs_agnumber_t agno, void *arg) { /* * turn on directory processing (inode discovery) and * attribute processing (extra_attr_check) */ wait_for_inode_prefetch(arg); do_log(_(" - agno = %d\n"), agno); process_aginodes(wq->mp, arg, agno, 1, 0, 1); cleanup_inode_prefetch(arg); } static void process_ags( xfs_mount_t *mp) { int i, j; xfs_agnumber_t agno; work_queue_t *queues; prefetch_args_t *pf_args[2]; queues = malloc(thread_count * sizeof(work_queue_t)); if (ag_stride) { /* * create one worker thread for each segment of the volume */ for (i = 0, agno = 0; i < thread_count; i++) { create_work_queue(&queues[i], mp, 1); pf_args[0] = NULL; for (j = 0; j < ag_stride && agno < mp->m_sb.sb_agcount; j++, agno++) { pf_args[0] = start_inode_prefetch(agno, 0, pf_args[0]); queue_work(&queues[i], process_ag_func, agno, pf_args[0]); } } /* * wait for workers to complete */ for (i = 0; i < thread_count; i++) destroy_work_queue(&queues[i]); } else { queues[0].mp = mp; pf_args[0] = start_inode_prefetch(0, 0, NULL); for (i = 0; i < mp->m_sb.sb_agcount; i++) { pf_args[(~i) & 1] = start_inode_prefetch(i + 1, 0, pf_args[i & 1]); process_ag_func(&queues[0], i, pf_args[i & 1]); } } free(queues); } void phase3(xfs_mount_t *mp) { int i, j; do_log(_("Phase 3 - for each AG...\n")); if (!no_modify) do_log(_(" - scan and clear agi unlinked lists...\n")); else do_log(_(" - scan (but don't clear) agi unlinked lists...\n")); set_progress_msg(PROG_FMT_AGI_UNLINKED, (__uint64_t) glob_agcount); /* first clear the agi unlinked AGI list */ if (!no_modify) { for (i = 0; i < mp->m_sb.sb_agcount; i++) process_agi_unlinked(mp, i); } /* now look at possibly bogus inodes */ for (i = 0; i < mp->m_sb.sb_agcount; i++) { check_uncertain_aginodes(mp, i); PROG_RPT_INC(prog_rpt_done[i], 1); } print_final_rpt(); /* ok, now that the tree's ok, let's take a good look */ do_log(_( " - process known inodes and perform inode discovery...\n")); set_progress_msg(PROG_FMT_PROCESS_INO, (__uint64_t) mp->m_sb.sb_icount); process_ags(mp); print_final_rpt(); /* * process newly discovered inode chunks */ do_log(_(" - process newly discovered inodes...\n")); set_progress_msg(PROG_FMT_NEW_INODES, (__uint64_t) glob_agcount); do { /* * have to loop until no ag has any uncertain * inodes */ j = 0; for (i = 0; i < mp->m_sb.sb_agcount; i++) { j += process_uncertain_aginodes(mp, i); #ifdef XR_INODE_TRACE fprintf(stderr, "\t\t phase 3 - process_uncertain_inodes returns %d\n", j); #endif PROG_RPT_INC(prog_rpt_done[i], 1); } } while (j != 0); print_final_rpt(); } xfsprogs-3.1.9ubuntu2/repair/agheader.h0000664000000000000000000000652611140033220015002 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct fs_geometry { /* * these types should match the superblock types */ __uint32_t sb_blocksize; /* blocksize (bytes) */ xfs_drfsbno_t sb_dblocks; /* # data blocks */ xfs_drfsbno_t sb_rblocks; /* # realtime blocks */ xfs_drtbno_t sb_rextents; /* # realtime extents */ uuid_t sb_uuid; /* fs uuid */ xfs_dfsbno_t sb_logstart; /* starting log block # */ xfs_agblock_t sb_rextsize; /* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks; /* # of blocks per ag */ xfs_agnumber_t sb_agcount; /* # of ags */ xfs_extlen_t sb_rbmblocks; /* # of rt bitmap blocks */ xfs_extlen_t sb_logblocks; /* # of log blocks */ __uint16_t sb_sectsize; /* volume sector size (bytes) */ __uint16_t sb_inodesize; /* inode size (bytes) */ __uint8_t sb_imax_pct; /* max % of fs for inode space */ /* * these don't have to match the superblock types but are placed * before sb_shared_vn because these values don't have to be * checked manually. These variables will be set only on * filesystems with dependably good (fully initialized) * secondary superblock sectors, will be stamped in all * superblocks at mkfs time, and are features that cannot * be downgraded unless all superblocks in the filesystem * are rewritten. */ int sb_extflgbit; /* extent flag feature bit set */ /* * fields after this point have to be checked manually in compare_sb() */ __uint8_t sb_shared_vn; /* shared version number */ xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */ __uint32_t sb_unit; /* stripe or raid unit */ __uint32_t sb_width; /* stripe or width unit */ /* * these don't have to match, they track superblock properties * that could have been upgraded and/or downgraded during * run-time so that the primary superblock has them but the * secondaries do not. * Plus, they have associated data fields whose data fields may * be corrupt in cases where the filesystem was made on a * pre-6.5 campus alpha mkfs and the feature was enabled on * the filesystem later. */ int sb_ialignbit; /* sb has inode alignment bit set */ int sb_salignbit; /* sb has stripe alignment bit set */ int sb_sharedbit; /* sb has inode alignment bit set */ int sb_fully_zeroed; /* has zeroed secondary sb sectors */ } fs_geometry_t; typedef struct fs_geo_list { struct fs_geo_list *next; int refs; int index; fs_geometry_t geo; } fs_geo_list_t; /* * fields for sb_last_nonzero */ #define XR_SB_COUNTERS 0x0001 #define XR_SB_INOALIGN 0x0002 #define XR_SB_SALIGN 0x0004 /* * what got modified by verify_set_* routines */ #define XR_AG_SB 0x1 #define XR_AG_AGF 0x2 #define XR_AG_AGI 0x4 #define XR_AG_SB_SEC 0x8 xfsprogs-3.1.9ubuntu2/repair/avl.c0000664000000000000000000007404011146407622014034 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #define CERT ASSERT #ifdef AVL_DEBUG static void avl_checknode( register avltree_desc_t *tree, register avlnode_t *np) { register avlnode_t *back = np->avl_back; register avlnode_t *forw = np->avl_forw; register avlnode_t *nextino = np->avl_nextino; register int bal = np->avl_balance; ASSERT(bal != AVL_BALANCE || (!back && !forw) || (back && forw)); ASSERT(bal != AVL_FORW || forw); ASSERT(bal != AVL_BACK || back); if (forw) { ASSERT(AVL_START(tree, np) < AVL_START(tree, forw)); ASSERT(np->avl_forw->avl_parent == np); ASSERT(back || bal == AVL_FORW); } else { ASSERT(bal != AVL_FORW); ASSERT(bal == AVL_BALANCE || back); ASSERT(bal == AVL_BACK || !back); } if (back) { ASSERT(AVL_START(tree, np) > AVL_START(tree, back)); ASSERT(np->avl_back->avl_parent == np); ASSERT(forw || bal == AVL_BACK); } else { ASSERT(bal != AVL_BACK); ASSERT(bal == AVL_BALANCE || forw); ASSERT(bal == AVL_FORW || !forw); } if (nextino == NULL) ASSERT(forw == NULL); else ASSERT(AVL_END(tree, np) <= AVL_START(tree, nextino)); } static void avl_checktree( register avltree_desc_t *tree, register avlnode_t *root) { register avlnode_t *nlast, *nnext, *np; __psunsigned_t offset = 0; __psunsigned_t end; nlast = nnext = root; ASSERT(!nnext || nnext->avl_parent == NULL); while (nnext) { avl_checknode(tree, nnext); end = AVL_END(tree, nnext); if (end <= offset) { if ((np = nnext->avl_forw) && np != nlast) { nlast = nnext; nnext = np; } else { nlast = nnext; nnext = nnext->avl_parent; } continue; } nlast = nnext; if (np = nnext->avl_back) { if (AVL_END(tree, np) > offset) { nnext = np; continue; } } np = nnext; nnext = nnext->avl_forw; if (!nnext) nnext = np->avl_parent; offset = end; } } #else /* ! AVL_DEBUG */ #define avl_checktree(t,x) #endif /* AVL_DEBUG */ /* * Reset balance for np up through tree. * ``direction'' is the way that np's balance * is headed after the deletion of one of its children -- * e.g., deleting a avl_forw child sends avl_balance toward AVL_BACK. * Called only when deleting a node from the tree. */ static void retreat( avltree_desc_t *tree, register avlnode_t *np, register int direction) { register avlnode_t **rootp = &tree->avl_root; register avlnode_t *parent; register avlnode_t *child; register avlnode_t *tmp; register int bal; do { ASSERT(direction == AVL_BACK || direction == AVL_FORW); if (np->avl_balance == AVL_BALANCE) { np->avl_balance = direction; return; } parent = np->avl_parent; /* * If balance is being restored, no local node * reorganization is necessary, but may be at * a higher node. Reset direction and continue. */ if (direction != np->avl_balance) { np->avl_balance = AVL_BALANCE; if (parent) { if (parent->avl_forw == np) direction = AVL_BACK; else direction = AVL_FORW; np = parent; continue; } return; } /* * Imbalance. If a avl_forw node was removed, direction * (and, by reduction, np->avl_balance) is/was AVL_BACK. */ if (np->avl_balance == AVL_BACK) { ASSERT(direction == AVL_BACK); child = np->avl_back; bal = child->avl_balance; if (bal != AVL_FORW) /* single LL */ { /* * np gets pushed down to lesser child's * avl_forw branch. * * np-> -D +B * / \ / \ * child-> B deleted A -D * / \ / * A C C */ #ifdef AVL_PRINT if (!(tree->avl_flags & AVLF_DUPLICITY)) cmn_err(CE_CONT, "!LL delete b 0x%x c 0x%x\n", np, child); #endif np->avl_back = child->avl_forw; if (child->avl_forw) child->avl_forw->avl_parent = np; child->avl_forw = np; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = child; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = child; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = child; } np->avl_parent = child; child->avl_parent = parent; if (bal == AVL_BALANCE) { np->avl_balance = AVL_BACK; child->avl_balance = AVL_FORW; return; } else { np->avl_balance = AVL_BALANCE; child->avl_balance = AVL_BALANCE; np = parent; avl_checktree(tree, *rootp); continue; } } /* child->avl_balance == AVL_FORW double LR rotation * * child's avl_forw node gets promoted up, along with * its avl_forw subtree * * np-> -G C * / \ / \ * child-> +B H -B G * / \ \ / / \ * A +C deleted A D H * \ * D */ #ifdef AVL_PRINT if (!(tree->avl_flags & AVLF_DUPLICITY)) cmn_err(CE_CONT, "!LR delete b 0x%x c 0x%x t 0x%x\n", np, child, child->avl_forw); #endif tmp = child->avl_forw; bal = tmp->avl_balance; child->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = child; tmp->avl_back = child; child->avl_parent = tmp; np->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = np; tmp->avl_forw = np; if (bal == AVL_FORW) child->avl_balance = AVL_BACK; else child->avl_balance = AVL_BALANCE; if (bal == AVL_BACK) np->avl_balance = AVL_FORW; else np->avl_balance = AVL_BALANCE; goto next; } ASSERT(np->avl_balance == AVL_FORW && direction == AVL_FORW); child = np->avl_forw; bal = child->avl_balance; if (bal != AVL_BACK) /* single RR */ { /* * np gets pushed down to greater child's * avl_back branch. * * np-> +B -D * / \ / \ * deleted D <-child +B E * / \ \ * C E C */ #ifdef AVL_PRINT if (!(tree->avl_flags & AVLF_DUPLICITY)) cmn_err(CE_CONT, "!RR delete b 0x%x c 0x%x\n", np, child); #endif np->avl_forw = child->avl_back; if (child->avl_back) child->avl_back->avl_parent = np; child->avl_back = np; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = child; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = child; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = child; } np->avl_parent = child; child->avl_parent = parent; if (bal == AVL_BALANCE) { np->avl_balance = AVL_FORW; child->avl_balance = AVL_BACK; return; } else { np->avl_balance = AVL_BALANCE; child->avl_balance = AVL_BALANCE; np = parent; avl_checktree(tree, *rootp); continue; } } /* child->avl_balance == AVL_BACK double RL rotation */ #ifdef AVL_PRINT if (!(tree->avl_flags & AVLF_DUPLICITY)) cmn_err(CE_CONT, "!RL delete b 0x%x c 0x%x t 0x%x\n", np, child, child->avl_back); #endif tmp = child->avl_back; bal = tmp->avl_balance; child->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = child; tmp->avl_forw = child; child->avl_parent = tmp; np->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = np; tmp->avl_back = np; if (bal == AVL_BACK) child->avl_balance = AVL_FORW; else child->avl_balance = AVL_BALANCE; if (bal == AVL_FORW) np->avl_balance = AVL_BACK; else np->avl_balance = AVL_BALANCE; next: np->avl_parent = tmp; tmp->avl_balance = AVL_BALANCE; tmp->avl_parent = parent; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = tmp; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = tmp; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = tmp; return; } np = parent; avl_checktree(tree, *rootp); } while (np); } /* * Remove node from tree. * avl_delete does the local tree manipulations, * calls retreat() to rebalance tree up to its root. */ void avl_delete( register avltree_desc_t *tree, register avlnode_t *np) { register avlnode_t *forw = np->avl_forw; register avlnode_t *back = np->avl_back; register avlnode_t *parent = np->avl_parent; register avlnode_t *nnext; if (np->avl_back) { /* * a left child exits, then greatest left descendent's nextino * is pointing to np; make it point to np->nextino. */ nnext = np->avl_back; while (nnext) { if (!nnext->avl_forw) break; /* can't find anything bigger */ nnext = nnext->avl_forw; } } else if (np->avl_parent) { /* * find nearest ancestor with lesser value. That ancestor's * nextino is pointing to np; make it point to np->nextino */ nnext = np->avl_parent; while (nnext) { if (AVL_END(tree, nnext) <= AVL_END(tree, np)) break; nnext = nnext->avl_parent; } } else nnext = NULL; if (nnext) { ASSERT(nnext->avl_nextino == np); nnext->avl_nextino = np->avl_nextino; /* * Something preceeds np; np cannot be firstino. */ ASSERT(tree->avl_firstino != np); } else { /* * Nothing preceeding np; after deletion, np's nextino * is firstino of tree. */ ASSERT(tree->avl_firstino == np); tree->avl_firstino = np->avl_nextino; } /* * Degenerate cases... */ if (forw == NULL) { forw = back; goto attach; } if (back == NULL) { attach: if (forw) forw->avl_parent = parent; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = forw; retreat(tree, parent, AVL_BACK); } else { ASSERT(parent->avl_back == np); parent->avl_back = forw; retreat(tree, parent, AVL_FORW); } } else { ASSERT(tree->avl_root == np); tree->avl_root = forw; } avl_checktree(tree, tree->avl_root); return; } /* * Harder case: children on both sides. * If back's avl_forw pointer is null, just have back * inherit np's avl_forw tree, remove np from the tree * and adjust balance counters starting at back. * * np-> xI xH (befor retreat()) * / \ / \ * back-> H J G J * / / \ / \ * G ? ? ? ? * / \ * ? ? */ if ((forw = back->avl_forw) == NULL) { /* * AVL_FORW retreat below will set back's * balance to AVL_BACK. */ back->avl_balance = np->avl_balance; back->avl_forw = forw = np->avl_forw; forw->avl_parent = back; back->avl_parent = parent; if (parent) { if (parent->avl_forw == np) parent->avl_forw = back; else { ASSERT(parent->avl_back == np); parent->avl_back = back; } } else { ASSERT(tree->avl_root == np); tree->avl_root = back; } /* * back is taking np's place in the tree, and * has therefore lost a avl_back node (itself). */ retreat(tree, back, AVL_FORW); avl_checktree(tree, tree->avl_root); return; } /* * Hardest case: children on both sides, and back's * avl_forw pointer isn't null. Find the immediately * inferior buffer by following back's avl_forw line * to the end, then have it inherit np's avl_forw tree. * * np-> xI xH * / \ / \ * G J back-> G J (before retreat()) * / \ / \ * F ?... F ?1 * / \ * ? H <-forw * / * ?1 */ while ((back = forw->avl_forw)) forw = back; /* * Will be adjusted by retreat() below. */ forw->avl_balance = np->avl_balance; /* * forw inherits np's avl_forw... */ forw->avl_forw = np->avl_forw; np->avl_forw->avl_parent = forw; /* * ... forw's parent gets forw's avl_back... */ back = forw->avl_parent; back->avl_forw = forw->avl_back; if (forw->avl_back) forw->avl_back->avl_parent = back; /* * ... forw gets np's avl_back... */ forw->avl_back = np->avl_back; np->avl_back->avl_parent = forw; /* * ... and forw gets np's parent. */ forw->avl_parent = parent; if (parent) { if (parent->avl_forw == np) parent->avl_forw = forw; else parent->avl_back = forw; } else { ASSERT(tree->avl_root == np); tree->avl_root = forw; } /* * What used to be forw's parent is the starting * point for rebalancing. It has lost a avl_forw node. */ retreat(tree, back, AVL_BACK); avl_checktree(tree, tree->avl_root); } /* * avl_findanyrange: * * Given range r [start, end), find any range which is contained in r. * if checklen is non-zero, then only ranges of non-zero length are * considered in finding a match. */ avlnode_t * avl_findanyrange( register avltree_desc_t *tree, register __psunsigned_t start, register __psunsigned_t end, int checklen) { register avlnode_t *np = tree->avl_root; /* np = avl_findadjacent(tree, start, AVL_SUCCEED); */ while (np) { if (start < AVL_START(tree, np)) { if (np->avl_back) { np = np->avl_back; continue; } /* if we were to add node with start, would * have a growth of AVL_BACK */ /* if succeeding node is needed, this is it. */ break; } if (start >= AVL_END(tree, np)) { if (np->avl_forw) { np = np->avl_forw; continue; } /* if we were to add node with start, would * have a growth of AVL_FORW; */ /* we are looking for a succeeding node; * this is nextino. */ np = np->avl_nextino; break; } /* AVL_START(tree, np) <= start < AVL_END(tree, np) */ break; } if (np) { if (checklen == AVL_INCLUDE_ZEROLEN) { if (end <= AVL_START(tree, np)) { /* something follows start, but is * is entierly after the range (end) */ return(NULL); } /* np may stradle [start, end) */ return(np); } /* * find non-zero length region */ while (np && (AVL_END(tree, np) - AVL_START(tree, np) == 0) && (AVL_START(tree, np) < end)) np = np->avl_nextino; if ((np == NULL) || (AVL_START(tree, np) >= end)) return NULL; return(np); } /* * nothing succeeds start, all existing ranges are before start. */ return NULL; } /* * Returns a pointer to node which contains exact value. */ avlnode_t * avl_find( register avltree_desc_t *tree, register __psunsigned_t value) { register avlnode_t *np = tree->avl_root; register __psunsigned_t nvalue; while (np) { nvalue = AVL_START(tree, np); if (value < nvalue) { np = np->avl_back; continue; } if (value == nvalue) { return np; } np = np->avl_forw; } return NULL; } /* * Balance buffer AVL tree after attaching a new node to root. * Called only by avl_insert. */ static void avl_balance( register avlnode_t **rootp, register avlnode_t *np, register int growth) { /* * At this point, np points to the node to which * a new node has been attached. All that remains is to * propagate avl_balance up the tree. */ for ( ; ; ) { register avlnode_t *parent = np->avl_parent; register avlnode_t *child; CERT(growth == AVL_BACK || growth == AVL_FORW); /* * If the buffer was already balanced, set avl_balance * to the new direction. Continue if there is a * parent after setting growth to reflect np's * relation to its parent. */ if (np->avl_balance == AVL_BALANCE) { np->avl_balance = growth; if (parent) { if (parent->avl_forw == np) growth = AVL_FORW; else { ASSERT(parent->avl_back == np); growth = AVL_BACK; } np = parent; continue; } break; } if (growth != np->avl_balance) { /* * Subtree is now balanced -- no net effect * in the size of the subtree, so leave. */ np->avl_balance = AVL_BALANCE; break; } if (growth == AVL_BACK) { child = np->avl_back; CERT(np->avl_balance == AVL_BACK && child); if (child->avl_balance == AVL_BACK) { /* single LL */ /* * ``A'' just got inserted; * np points to ``E'', child to ``C'', * and it is already AVL_BACK -- * child will get promoted to top of subtree. np-> -E C / \ / \ child-> -C F -B E / \ / / \ -B D A D F / A Note that child->avl_parent and avl_balance get set in common code. */ np->avl_parent = child; np->avl_balance = AVL_BALANCE; np->avl_back = child->avl_forw; if (child->avl_forw) child->avl_forw->avl_parent = np; child->avl_forw = np; } else { /* * double LR * * child's avl_forw node gets promoted to * the top of the subtree. np-> -E C / \ / \ child-> +B F -B E / \ / / \ A +C A D F \ D */ register avlnode_t *tmp = child->avl_forw; CERT(child->avl_balance == AVL_FORW && tmp); child->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = child; tmp->avl_back = child; child->avl_parent = tmp; np->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = np; tmp->avl_forw = np; np->avl_parent = tmp; if (tmp->avl_balance == AVL_BACK) np->avl_balance = AVL_FORW; else np->avl_balance = AVL_BALANCE; if (tmp->avl_balance == AVL_FORW) child->avl_balance = AVL_BACK; else child->avl_balance = AVL_BALANCE; /* * Set child to point to tmp since it is * now the top of the subtree, and will * get attached to the subtree parent in * the common code below. */ child = tmp; } } else /* growth == AVL_BACK */ { /* * This code is the mirror image of AVL_FORW above. */ child = np->avl_forw; CERT(np->avl_balance == AVL_FORW && child); if (child->avl_balance == AVL_FORW) { /* single RR */ np->avl_parent = child; np->avl_balance = AVL_BALANCE; np->avl_forw = child->avl_back; if (child->avl_back) child->avl_back->avl_parent = np; child->avl_back = np; } else { /* * double RL */ register avlnode_t *tmp = child->avl_back; ASSERT(child->avl_balance == AVL_BACK && tmp); child->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = child; tmp->avl_forw = child; child->avl_parent = tmp; np->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = np; tmp->avl_back = np; np->avl_parent = tmp; if (tmp->avl_balance == AVL_FORW) np->avl_balance = AVL_BACK; else np->avl_balance = AVL_BALANCE; if (tmp->avl_balance == AVL_BACK) child->avl_balance = AVL_FORW; else child->avl_balance = AVL_BALANCE; child = tmp; } } child->avl_parent = parent; child->avl_balance = AVL_BALANCE; if (parent) { if (parent->avl_back == np) parent->avl_back = child; else parent->avl_forw = child; } else { ASSERT(*rootp == np); *rootp = child; } break; } } static avlnode_t * avl_insert_find_growth( register avltree_desc_t *tree, register __psunsigned_t start, /* range start at start, */ register __psunsigned_t end, /* exclusive */ register int *growthp) /* OUT */ { avlnode_t *root = tree->avl_root; register avlnode_t *np; np = root; ASSERT(np); /* caller ensures that there is atleast one node in tree */ for ( ; ; ) { CERT(np->avl_parent || root == np); CERT(!np->avl_parent || root != np); CERT(!(np->avl_back) || np->avl_back->avl_parent == np); CERT(!(np->avl_forw) || np->avl_forw->avl_parent == np); CERT(np->avl_balance != AVL_FORW || np->avl_forw); CERT(np->avl_balance != AVL_BACK || np->avl_back); CERT(np->avl_balance != AVL_BALANCE || np->avl_back == NULL || np->avl_forw); CERT(np->avl_balance != AVL_BALANCE || np->avl_forw == NULL || np->avl_back); if (AVL_START(tree, np) >= end) { if (np->avl_back) { np = np->avl_back; continue; } *growthp = AVL_BACK; break; } if (AVL_END(tree, np) <= start) { if (np->avl_forw) { np = np->avl_forw; continue; } *growthp = AVL_FORW; break; } /* found exact match -- let caller decide if it is an error */ return(NULL); } return(np); } static void avl_insert_grow( register avltree_desc_t *tree, register avlnode_t *parent, register avlnode_t *newnode, register int growth) { register avlnode_t *nnext; register __psunsigned_t start = AVL_START(tree, newnode); if (growth == AVL_BACK) { parent->avl_back = newnode; /* * we are growing to the left; previous in-order to newnode is * closest ancestor with lesser value. Before this * insertion, this ancestor will be pointing to * newnode's parent. After insertion, next in-order to newnode * is the parent. */ newnode->avl_nextino = parent; nnext = parent; while (nnext) { if (AVL_END(tree, nnext) <= start) break; nnext = nnext->avl_parent; } if (nnext) { /* * nnext will be null if newnode is * the least element, and hence very first in the list. */ ASSERT(nnext->avl_nextino == parent); nnext->avl_nextino = newnode; } } else { parent->avl_forw = newnode; newnode->avl_nextino = parent->avl_nextino; parent->avl_nextino = newnode; } } avlnode_t * avl_insert( register avltree_desc_t *tree, register avlnode_t *newnode) { register avlnode_t *np; register __psunsigned_t start = AVL_START(tree, newnode); register __psunsigned_t end = AVL_END(tree, newnode); int growth; ASSERT(newnode); ASSERT(start <= end); /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if ((np = tree->avl_root) == NULL) { /* degenerate case... */ tree->avl_root = newnode; tree->avl_firstino = newnode; return newnode; } if ((np = avl_insert_find_growth(tree, start, end, &growth)) == NULL) { if (start != end) { /* non-zero length range */ fprintf(stderr, _("avl_insert: Warning! duplicate range [%llu,%llu]\n"), (unsigned long long)start, (unsigned long long)end); } return(NULL); } avl_insert_grow(tree, np, newnode, growth); if (growth == AVL_BACK) { /* * Growing to left. if np was firstino, newnode will be firstino */ if (tree->avl_firstino == np) tree->avl_firstino = newnode; } #ifdef notneeded else if (growth == AVL_FORW) /* * Cannot possibly be firstino; there is somebody to our left. */ ; #endif newnode->avl_parent = np; CERT(np->avl_forw == newnode || np->avl_back == newnode); avl_balance(&tree->avl_root, np, growth); avl_checktree(tree, tree->avl_root); return newnode; } /* * * avl_insert_immediate(tree, afterp, newnode): * insert newnode immediately into tree immediately after afterp. * after insertion, newnode is right child of afterp. */ void avl_insert_immediate( avltree_desc_t *tree, avlnode_t *afterp, avlnode_t *newnode) { /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if (afterp == NULL) { tree->avl_root = newnode; tree->avl_firstino = newnode; return; } ASSERT(afterp->avl_forw == NULL); avl_insert_grow(tree, afterp, newnode, AVL_FORW); /* grow to right */ CERT(afterp->avl_forw == newnode); avl_balance(&tree->avl_root, afterp, AVL_FORW); avl_checktree(tree, tree->avl_root); } /* * Returns first in order node */ avlnode_t * avl_firstino(register avlnode_t *root) { register avlnode_t *np; if ((np = root) == NULL) return NULL; while (np->avl_back) np = np->avl_back; return np; } /* * Returns last in order node */ avlnode_t * avl_lastino(register avlnode_t *root) { register avlnode_t *np; if ((np = root) == NULL) return NULL; while (np->avl_forw) np = np->avl_forw; return np; } void avl_init_tree(avltree_desc_t *tree, avlops_t *ops) { tree->avl_root = NULL; tree->avl_firstino = NULL; tree->avl_ops = ops; } #ifdef AVL_DEBUG static void avl_printnode(avltree_desc_t *tree, avlnode_t *np, int nl) { printf("[%d-%d]%c", AVL_START(tree, np), (AVL_END(tree, np) - 1), nl ? '\n' : ' '); } #endif #ifdef STAND_ALONE_DEBUG struct avl_debug_node { avlnode_t avl_node; xfs_off_t avl_start; unsigned int avl_size; } avlops_t avl_debug_ops = { avl_debug_start, avl_debug_end, } static __psunsigned_t avl_debug_start(avlnode_t *node) { return (__psunsigned_t)(struct avl_debug_node *)node->avl_start; } static __psunsigned_t avl_debug_end(avlnode_t *node) { return (__psunsigned_t) ((struct avl_debug_node *)node->avl_start + (struct avl_debug_node *)node->avl_size); } avl_debug_node freenodes[100]; avl_debug_node *freehead = &freenodes[0]; static avlnode_t * alloc_avl_debug_node() { freehead->avl_balance = AVL_BALANCE; freehead->avl_parent = freehead->avl_forw = freehead->avl_back = NULL; return(freehead++); } static void avl_print(avltree_desc_t *tree, avlnode_t *root, int depth) { int i; if (!root) return; if (root->avl_forw) avl_print(tree, root->avl_forw, depth+5); for (i = 0; i < depth; i++) putchar((int) ' '); avl_printnode(tree, root,1); if (root->avl_back) avl_print(tree, root->avl_back, depth+5); } main() { int i, j; avlnode_t *np; avltree_desc_t tree; char linebuf[256], cmd[256]; avl_init_tree(&tree, &avl_debug_ops); for (i = 100; i > 0; i = i - 10) { np = alloc__debug_avlnode(); ASSERT(np); np->avl_start = i; np->avl_size = 10; avl_insert(&tree, np); } avl_print(&tree, tree.avl_root, 0); for (np = tree.avl_firstino; np != NULL; np = np->avl_nextino) avl_printnode(&tree, np, 0); printf("\n"); while (1) { printf(_("Command [fpdir] : ")); fgets(linebuf, 256, stdin); if (feof(stdin)) break; cmd[0] = NULL; if (sscanf(linebuf, "%[fpdir]%d", cmd, &i) != 2) continue; switch (cmd[0]) { case 'd': case 'f': printf(_("end of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); if (i == j) j = i+1; np = avl_findinrange(&tree,i,j); if (np) { avl_printnode(&tree, np, 1); if (cmd[0] == 'd') avl_delete(&tree, np); } else printf(_("Cannot find %d\n"), i); break; case 'p': avl_print(&tree, tree.avl_root, 0); for (np = tree.avl_firstino; np != NULL; np = np->avl_nextino) avl_printnode(&tree, np, 0); printf("\n"); break; case 'i': np = alloc_avlnode(); ASSERT(np); np->avl_start = i; printf(_("size of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); np->avl_size = j; avl_insert(&tree, np); break; case 'r': { avlnode_t *b, *e, *t; int checklen; printf(_("End of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); printf(_("checklen 0/1 ? ")); fgets(linebuf, 256, stdin); checklen = atoi(linebuf); b = avl_findanyrange(&tree, i, j, checklen); if (b) { printf(_("Found something\n")); t = b; while (t) { if (t != b && AVL_START(&tree, t) >= j) break; avl_printnode(&tree, t, 0); t = t->avl_nextino; } printf("\n"); } } } } } #endif /* * Given a tree, find value; will find return range enclosing value, * or range immediately succeeding value, * or range immediately preceeding value. */ avlnode_t * avl_findadjacent( register avltree_desc_t *tree, register __psunsigned_t value, register int dir) { register avlnode_t *np = tree->avl_root; while (np) { if (value < AVL_START(tree, np)) { if (np->avl_back) { np = np->avl_back; continue; } /* if we were to add node with value, would * have a growth of AVL_BACK */ if (dir == AVL_SUCCEED) { /* if succeeding node is needed, this is it. */ return(np); } if (dir == AVL_PRECEED) { /* * find nearest ancestor with lesser value. */ np = np->avl_parent; while (np) { if (AVL_END(tree, np) <= value) break; np = np->avl_parent; } return(np); } ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED); break; } if (value >= AVL_END(tree, np)) { if (np->avl_forw) { np = np->avl_forw; continue; } /* if we were to add node with value, would * have a growth of AVL_FORW; */ if (dir == AVL_SUCCEED) { /* we are looking for a succeeding node; * this is nextino. */ return(np->avl_nextino); } if (dir == AVL_PRECEED) { /* looking for a preceeding node; this is it. */ return(np); } ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED); } /* AVL_START(tree, np) <= value < AVL_END(tree, np) */ return(np); } return NULL; } /* * avl_findranges: * * Given range r [start, end), find all ranges in tree which are contained * in r. At return, startp and endp point to first and last of * a chain of elements which describe the contained ranges. Elements * in startp ... endp are in sort order, and can be accessed by * using avl_nextino. */ void avl_findranges( register avltree_desc_t *tree, register __psunsigned_t start, register __psunsigned_t end, avlnode_t **startp, avlnode_t **endp) { register avlnode_t *np; np = avl_findadjacent(tree, start, AVL_SUCCEED); if (np == NULL /* nothing succeding start */ || (np && (end <= AVL_START(tree, np)))) /* something follows start, but... is entirely after end */ { *startp = NULL; *endp = NULL; return; } *startp = np; /* see if end is in this region itself */ if (end <= AVL_END(tree, np) || np->avl_nextino == NULL || (np->avl_nextino && (end <= AVL_START(tree, np->avl_nextino)))) { *endp = np; return; } /* have to munge for end */ /* * note: have to look for (end - 1), since * findadjacent will look for exact value, and does not * care about the fact that end is actually one more * than the value actually being looked for; thus feed it one less. */ *endp = avl_findadjacent(tree, (end-1), AVL_PRECEED); ASSERT(*endp); } xfsprogs-3.1.9ubuntu2/repair/dinode.h0000664000000000000000000000532612062210562014513 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_DINODE_H #define _XR_DINODE_H #include "prefetch.h" struct blkmap; int verify_agbno(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno); int verify_dfsbno(xfs_mount_t *mp, xfs_dfsbno_t fsbno); void convert_extent( xfs_bmbt_rec_t *rp, xfs_dfiloff_t *op, /* starting offset (blockno in file) */ xfs_dfsbno_t *sp, /* starting block (fs blockno) */ xfs_dfilblks_t *cp, /* blockcount */ int *fp); /* extent flag */ int process_bmbt_reclist(xfs_mount_t *mp, xfs_bmbt_rec_t *rp, int *numrecs, int type, xfs_ino_t ino, xfs_drfsbno_t *tot, struct blkmap **blkmapp, __uint64_t *first_key, __uint64_t *last_key, int whichfork); int scan_bmbt_reclist( xfs_mount_t *mp, xfs_bmbt_rec_t *rp, int *numrecs, int type, xfs_ino_t ino, xfs_drfsbno_t *tot, int whichfork); void update_rootino(xfs_mount_t *mp); int process_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino, int was_free, int *dirty, int *used, int check_dirs, int check_dups, int extra_attr_check, int *isa_dir, xfs_ino_t *parent); int verify_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino); int verify_uncertain_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino); int verify_inum(xfs_mount_t *mp, xfs_ino_t ino); int verify_aginum(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino); int process_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno); void process_aginodes(xfs_mount_t *mp, prefetch_args_t *pf_args, xfs_agnumber_t agno, int check_dirs, int check_dups, int extra_attr_check); void check_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno); xfs_buf_t * get_agino_buf(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino, xfs_dinode_t **dipp); xfs_dfsbno_t get_bmapi(xfs_mount_t *mp, xfs_dinode_t *dip, xfs_ino_t ino_num, xfs_dfiloff_t bno, int whichfork ); #endif /* _XR_DINODE_H */ xfsprogs-3.1.9ubuntu2/repair/bmap.h0000664000000000000000000000424212062210562014164 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XFS_REPAIR_BMAP_H #define _XFS_REPAIR_BMAP_H /* * Extent descriptor. */ typedef struct bmap_ext { xfs_dfiloff_t startoff; xfs_dfsbno_t startblock; xfs_dfilblks_t blockcount; } bmap_ext_t; /* * Block map. */ typedef struct blkmap { int naexts; int nexts; bmap_ext_t exts[1]; } blkmap_t; #define BLKMAP_SIZE(n) \ (offsetof(blkmap_t, exts) + (sizeof(bmap_ext_t) * (n))) /* * For 32 bit platforms, we are limited to extent arrays of 2^31 bytes, which * limits the number of extents in an inode we can check. If we don't limit the * valid range, we can overflow the BLKMAP_SIZE() calculation and allocate less * memory than we think we needed, and hence walk off the end of the array and * corrupt memory. */ #if BITS_PER_LONG == 32 #define BLKMAP_NEXTS_MAX ((INT_MAX / sizeof(bmap_ext_t)) - 1) #else #define BLKMAP_NEXTS_MAX INT_MAX #endif extern pthread_key_t dblkmap_key; extern pthread_key_t ablkmap_key; blkmap_t *blkmap_alloc(xfs_extnum_t nex, int whichfork); void blkmap_free(blkmap_t *blkmap); int blkmap_set_ext(blkmap_t **blkmapp, xfs_dfiloff_t o, xfs_dfsbno_t b, xfs_dfilblks_t c); xfs_dfsbno_t blkmap_get(blkmap_t *blkmap, xfs_dfiloff_t o); int blkmap_getn(blkmap_t *blkmap, xfs_dfiloff_t o, xfs_dfilblks_t nb, bmap_ext_t **bmpp, bmap_ext_t *bmpp_single); xfs_dfiloff_t blkmap_last_off(blkmap_t *blkmap); xfs_dfiloff_t blkmap_next_off(blkmap_t *blkmap, xfs_dfiloff_t o, int *t); #endif /* _XFS_REPAIR_BMAP_H */ xfsprogs-3.1.9ubuntu2/repair/phase2.c0000664000000000000000000001334411650373061014433 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" #include "incore.h" #include "progress.h" #include "scan.h" void set_mp(xfs_mount_t *mpp); /* workaround craziness in the xlog routines */ int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } static void zero_log(xfs_mount_t *mp) { int error; xlog_t log; xfs_daddr_t head_blk, tail_blk; dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; memset(&log, 0, sizeof(log)); if (!x.logdev) x.logdev = x.ddev; x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); log.l_dev = logdev; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; log.l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; ASSERT(log.l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ ASSERT(log.l_sectbb_log == 0 || log.l_logBBstart == 0 || xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1; if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) { do_warn(_("zero_log: cannot find log head/tail " "(xlog_find_tail=%d), zeroing it anyway\n"), error); } else { if (verbose) { do_warn( _("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"), head_blk, tail_blk); } if (head_blk != tail_blk) { if (zap_log) { do_warn(_( "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n")); } else { do_warn(_( "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n")); exit(2); } } } libxfs_log_clear(logdev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT); } /* * ok, at this point, the fs is mounted but the root inode may be * trashed and the ag headers haven't been checked. So we have * a valid xfs_mount_t and superblock but that's about it. That * means we can use macros that use mount/sb fields in calculations * but I/O or btree routines that depend on space maps or inode maps * being correct are verboten. */ void phase2( struct xfs_mount *mp, int scan_threads) { int j; ino_tree_node_t *ino_rec; /* now we can start using the buffer cache routines */ set_mp(mp); /* Check whether this fs has internal or external log */ if (mp->m_sb.sb_logstart == 0) { if (!x.logname) do_error(_("This filesystem has an external log. " "Specify log device with the -l option.\n")); do_log(_("Phase 2 - using external log on %s\n"), x.logname); } else do_log(_("Phase 2 - using internal log\n")); /* Zero log if applicable */ if (!no_modify) { do_log(_(" - zero log...\n")); zero_log(mp); } do_log(_(" - scan filesystem freespace and inode maps...\n")); bad_ino_btree = 0; set_progress_msg(PROG_FMT_SCAN_AG, (__uint64_t) glob_agcount); scan_ags(mp, scan_threads); print_final_rpt(); /* * make sure we know about the root inode chunk */ if ((ino_rec = find_inode_rec(mp, 0, mp->m_sb.sb_rootino)) == NULL) { ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 && mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2); do_warn(_("root inode chunk not found\n")); /* * mark the first 3 used, the rest are free */ ino_rec = set_inode_used_alloc(mp, 0, (xfs_agino_t) mp->m_sb.sb_rootino); set_inode_used(ino_rec, 1); set_inode_used(ino_rec, 2); for (j = 3; j < XFS_INODES_PER_CHUNK; j++) set_inode_free(ino_rec, j); /* * also mark blocks */ set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino), mp->m_ialloc_blks, XR_E_INO); } else { do_log(_(" - found root inode chunk\n")); /* * blocks are marked, just make sure they're in use */ if (is_inode_free(ino_rec, 0)) { do_warn(_("root inode marked free, ")); set_inode_used(ino_rec, 0); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } if (is_inode_free(ino_rec, 1)) { do_warn(_("realtime bitmap inode marked free, ")); set_inode_used(ino_rec, 1); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } if (is_inode_free(ino_rec, 2)) { do_warn(_("realtime summary inode marked free, ")); set_inode_used(ino_rec, 2); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } } } xfsprogs-3.1.9ubuntu2/repair/threads.c0000664000000000000000000000542011140033220014657 0ustar #include #include #include #include "threads.h" #include "err_protos.h" #include "protos.h" #include "globals.h" static void * worker_thread(void *arg) { work_queue_t *wq; work_item_t *wi; wq = (work_queue_t*)arg; /* * Loop pulling work from the passed in work queue. * Check for notification to exit after every chunk of work. */ while (1) { pthread_mutex_lock(&wq->lock); /* * Wait for work. */ while (wq->next_item == NULL && !wq->terminate) { ASSERT(wq->item_count == 0); pthread_cond_wait(&wq->wakeup, &wq->lock); } if (wq->next_item == NULL && wq->terminate) { pthread_mutex_unlock(&wq->lock); break; } /* * Dequeue work from the head of the list. */ ASSERT(wq->item_count > 0); wi = wq->next_item; wq->next_item = wi->next; wq->item_count--; pthread_mutex_unlock(&wq->lock); (wi->function)(wi->queue, wi->agno, wi->arg); free(wi); } return NULL; } void thread_init(void) { sigset_t blocked; /* * block delivery of progress report signal to all threads */ sigemptyset(&blocked); sigaddset(&blocked, SIGHUP); sigaddset(&blocked, SIGALRM); pthread_sigmask(SIG_BLOCK, &blocked, NULL); } void create_work_queue( work_queue_t *wq, xfs_mount_t *mp, int nworkers) { int err; int i; memset(wq, 0, sizeof(work_queue_t)); pthread_cond_init(&wq->wakeup, NULL); pthread_mutex_init(&wq->lock, NULL); wq->mp = mp; wq->thread_count = nworkers; wq->threads = malloc(nworkers * sizeof(pthread_t)); wq->terminate = 0; for (i = 0; i < nworkers; i++) { err = pthread_create(&wq->threads[i], NULL, worker_thread, wq); if (err != 0) { do_error(_("cannot create worker threads, error = [%d] %s\n"), err, strerror(err)); } } } void queue_work( work_queue_t *wq, work_func_t func, xfs_agnumber_t agno, void *arg) { work_item_t *wi; wi = (work_item_t *)malloc(sizeof(work_item_t)); if (wi == NULL) do_error(_("cannot allocate worker item, error = [%d] %s\n"), errno, strerror(errno)); wi->function = func; wi->agno = agno; wi->arg = arg; wi->queue = wq; wi->next = NULL; /* * Now queue the new work structure to the work queue. */ pthread_mutex_lock(&wq->lock); if (wq->next_item == NULL) { wq->next_item = wi; ASSERT(wq->item_count == 0); pthread_cond_signal(&wq->wakeup); } else { wq->last_item->next = wi; } wq->last_item = wi; wq->item_count++; pthread_mutex_unlock(&wq->lock); } void destroy_work_queue( work_queue_t *wq) { int i; pthread_mutex_lock(&wq->lock); wq->terminate = 1; pthread_mutex_unlock(&wq->lock); pthread_cond_broadcast(&wq->wakeup); for (i = 0; i < wq->thread_count; i++) pthread_join(wq->threads[i], NULL); free(wq->threads); pthread_mutex_destroy(&wq->lock); pthread_cond_destroy(&wq->wakeup); } xfsprogs-3.1.9ubuntu2/repair/avl64.h0000664000000000000000000000574011140033220014173 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XR_AVL64_H__ #define __XR_AVL64_H__ #include typedef struct avl64node { struct avl64node *avl_forw; /* pointer to right child (> parent) */ struct avl64node *avl_back; /* pointer to left child (< parent) */ struct avl64node *avl_parent; /* parent pointer */ struct avl64node *avl_nextino; /* next in-order; NULL terminated list*/ char avl_balance; /* tree balance */ } avl64node_t; /* * avl-tree operations */ typedef struct avl64ops { __uint64_t (*avl_start)(avl64node_t *); __uint64_t (*avl_end)(avl64node_t *); } avl64ops_t; /* * avoid complaints about multiple def's since these are only used by * the avl code internally */ #ifndef AVL_START #define AVL_START(tree, n) (*(tree)->avl_ops->avl_start)(n) #define AVL_END(tree, n) (*(tree)->avl_ops->avl_end)(n) #endif /* * tree descriptor: * root points to the root of the tree. * firstino points to the first in the ordered list. */ typedef struct avl64tree_desc { avl64node_t *avl_root; avl64node_t *avl_firstino; avl64ops_t *avl_ops; } avl64tree_desc_t; /* possible values for avl_balance */ #define AVL_BACK 1 #define AVL_BALANCE 0 #define AVL_FORW 2 /* * 'Exported' avl tree routines */ avl64node_t *avl64_insert( avl64tree_desc_t *tree, avl64node_t *newnode); void avl64_delete( avl64tree_desc_t *tree, avl64node_t *np); void avl64_insert_immediate( avl64tree_desc_t *tree, avl64node_t *afterp, avl64node_t *newnode); void avl64_init_tree( avl64tree_desc_t *tree, avl64ops_t *ops); avl64node_t * avl64_findrange( avl64tree_desc_t *tree, __uint64_t value); avl64node_t * avl64_find( avl64tree_desc_t *tree, __uint64_t value); avl64node_t * avl64_findanyrange( avl64tree_desc_t *tree, __uint64_t start, __uint64_t end, int checklen); avl64node_t * avl64_findadjacent( avl64tree_desc_t *tree, __uint64_t value, int dir); void avl64_findranges( register avl64tree_desc_t *tree, register __uint64_t start, register __uint64_t end, avl64node_t **startp, avl64node_t **endp); /* * avoid complaints about multiple def's since these are only used by * the avl code internally */ #ifndef AVL_PRECEED #define AVL_PRECEED 0x1 #define AVL_SUCCEED 0x2 #define AVL_INCLUDE_ZEROLEN 0x0000 #define AVL_EXCLUDE_ZEROLEN 0x0001 #endif #endif /* __XR_AVL64_H__ */ xfsprogs-3.1.9ubuntu2/repair/incore_ext.c0000664000000000000000000005150112062210562015377 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "btree.h" #include "globals.h" #include "incore.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" #include "avl64.h" #include "threads.h" /* * note: there are 4 sets of incore things handled here: * block bitmaps, extent trees, uncertain inode list, * and inode tree. The tree-based code uses the AVL * tree package used by the IRIX kernel VM code * (sys/avl.h). The inode list code uses the same records * as the inode tree code for convenience. The bitmaps * and bitmap operators are mostly macros defined in incore.h. * There are one of everything per AG except for extent * trees. There's one duplicate extent tree, one bno and * one bcnt extent tree per AG. Not all of the above exist * through all phases. The duplicate extent tree gets trashed * at the end of phase 4. The bno/bcnt trees don't appear until * phase 5. The uncertain inode list goes away at the end of * phase 3. The inode tree and bno/bnct trees go away after phase 5. */ static avl64tree_desc_t *rt_ext_tree_ptr; /* dup extent tree for rt */ static pthread_mutex_t rt_ext_tree_lock; static struct btree_root **dup_extent_trees; /* per ag dup extent trees */ static pthread_mutex_t *dup_extent_tree_locks; static avltree_desc_t **extent_bno_ptrs; /* * array of extent tree ptrs * one per ag for free extents * sorted by starting block * number */ static avltree_desc_t **extent_bcnt_ptrs; /* * array of extent tree ptrs * one per ag for free extents * sorted by size */ /* * duplicate extent tree functions */ void release_dup_extent_tree( xfs_agnumber_t agno) { pthread_mutex_lock(&dup_extent_tree_locks[agno]); btree_clear(dup_extent_trees[agno]); pthread_mutex_unlock(&dup_extent_tree_locks[agno]); } int add_dup_extent( xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount) { int ret; #ifdef XR_DUP_TRACE fprintf(stderr, "Adding dup extent - %d/%d %d\n", agno, startblock, blockcount); #endif pthread_mutex_lock(&dup_extent_tree_locks[agno]); ret = btree_insert(dup_extent_trees[agno], startblock, (void *)(uintptr_t)(startblock + blockcount)); pthread_mutex_unlock(&dup_extent_tree_locks[agno]); return ret; } int search_dup_extent( xfs_agnumber_t agno, xfs_agblock_t start_agbno, xfs_agblock_t end_agbno) { unsigned long bno; int ret; pthread_mutex_lock(&dup_extent_tree_locks[agno]); if (!btree_find(dup_extent_trees[agno], start_agbno, &bno)) { ret = 0; goto out; /* this really shouldn't happen */ } if (bno < end_agbno) { ret = 1; goto out; } ret = (uintptr_t)btree_peek_prev(dup_extent_trees[agno], NULL) > start_agbno; out: pthread_mutex_unlock(&dup_extent_tree_locks[agno]); return ret; } /* * extent tree stuff is avl trees of duplicate extents, * sorted in order by block number. there is one tree per ag. */ static extent_tree_node_t * mk_extent_tree_nodes(xfs_agblock_t new_startblock, xfs_extlen_t new_blockcount, extent_state_t new_state) { extent_tree_node_t *new; new = malloc(sizeof(*new)); if (!new) do_error(_("couldn't allocate new extent descriptor.\n")); new->avl_node.avl_nextino = NULL; new->ex_startblock = new_startblock; new->ex_blockcount = new_blockcount; new->ex_state = new_state; new->next = NULL; new->last = NULL; return new; } void release_extent_tree_node(extent_tree_node_t *node) { free(node); } /* * routines to recycle all nodes in a tree. it walks the tree * and puts all nodes back on the free list so the nodes can be * reused. the duplicate and bno/bcnt extent trees for each AG * are recycled after they're no longer needed to save memory */ void release_extent_tree(avltree_desc_t *tree) { extent_tree_node_t *ext; extent_tree_node_t *tmp; extent_tree_node_t *lext; extent_tree_node_t *ltmp; if (tree->avl_firstino == NULL) return; ext = (extent_tree_node_t *) tree->avl_firstino; while (ext != NULL) { tmp = (extent_tree_node_t *) ext->avl_node.avl_nextino; /* * ext->next is guaranteed to be set only in bcnt trees */ if (ext->next != NULL) { lext = ext->next; while (lext != NULL) { ltmp = lext->next; release_extent_tree_node(lext); lext = ltmp; } } release_extent_tree_node(ext); ext = tmp; } tree->avl_root = tree->avl_firstino = NULL; return; } /* * top-level (visible) routines */ void release_agbno_extent_tree(xfs_agnumber_t agno) { release_extent_tree(extent_bno_ptrs[agno]); return; } void release_agbcnt_extent_tree(xfs_agnumber_t agno) { release_extent_tree(extent_bcnt_ptrs[agno]); return; } /* * the next 4 routines manage the trees of free extents -- 2 trees * per AG. The first tree is sorted by block number. The second * tree is sorted by extent size. This is the bno tree. */ void add_bno_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount) { extent_tree_node_t *ext; ASSERT(extent_bno_ptrs != NULL); ASSERT(extent_bno_ptrs[agno] != NULL); ext = mk_extent_tree_nodes(startblock, blockcount, XR_E_FREE); if (avl_insert(extent_bno_ptrs[agno], (avlnode_t *) ext) == NULL) { do_error(_("duplicate bno extent range\n")); } } extent_tree_node_t * findfirst_bno_extent(xfs_agnumber_t agno) { ASSERT(extent_bno_ptrs != NULL); ASSERT(extent_bno_ptrs[agno] != NULL); return((extent_tree_node_t *) extent_bno_ptrs[agno]->avl_firstino); } extent_tree_node_t * find_bno_extent(xfs_agnumber_t agno, xfs_agblock_t startblock) { ASSERT(extent_bno_ptrs != NULL); ASSERT(extent_bno_ptrs[agno] != NULL); return((extent_tree_node_t *) avl_find(extent_bno_ptrs[agno], startblock)); } /* * delete a node that's in the tree (pointer obtained by a find routine) */ void get_bno_extent(xfs_agnumber_t agno, extent_tree_node_t *ext) { ASSERT(extent_bno_ptrs != NULL); ASSERT(extent_bno_ptrs[agno] != NULL); avl_delete(extent_bno_ptrs[agno], &ext->avl_node); return; } /* * normalizing constant for bcnt size -> address conversion (see avl ops) * used by the AVL tree code to convert sizes and must be used when * doing an AVL search in the tree (e.g. avl_findrange(s)) */ #define MAXBCNT 0xFFFFFFFF #define BCNT_ADDR(cnt) ((unsigned int) MAXBCNT - (cnt)) /* * the next 4 routines manage the trees of free extents -- 2 trees * per AG. The first tree is sorted by block number. The second * tree is sorted by extent size. This is the bcnt tree. */ void add_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount) { extent_tree_node_t *ext, *prev, *current, *top; xfs_agblock_t tmp_startblock; xfs_extlen_t tmp_blockcount; extent_state_t tmp_state; ASSERT(extent_bcnt_ptrs != NULL); ASSERT(extent_bcnt_ptrs[agno] != NULL); ext = mk_extent_tree_nodes(startblock, blockcount, XR_E_FREE); ASSERT(ext->next == NULL); #ifdef XR_BCNT_TRACE fprintf(stderr, "adding bcnt: agno = %d, start = %u, count = %u\n", agno, startblock, blockcount); #endif if ((current = (extent_tree_node_t *) avl_find(extent_bcnt_ptrs[agno], blockcount)) != NULL) { /* * avl tree code doesn't handle dups so insert * onto linked list in increasing startblock order * * when called from mk_incore_fstree, * startblock is in increasing order. * current is an "anchor" node. * quick check if the new ext goes to the end. * if so, append at the end, using the last field * of the "anchor". */ ASSERT(current->last != NULL); if (startblock > current->last->ex_startblock) { current->last->next = ext; current->last = ext; return; } /* * scan, to find the proper location for new entry. * this scan is *very* expensive and gets worse with * with increasing entries. */ top = prev = current; while (current != NULL && startblock > current->ex_startblock) { prev = current; current = current->next; } if (top == current) { ASSERT(top == prev); /* * new entry should be ahead of current. * to keep the avl tree intact, * swap the values of to-be-inserted element * and the values of the head of the list. * then insert as the 2nd element on the list. * * see the comment in get_bcnt_extent() * as to why we have to do this. */ tmp_startblock = top->ex_startblock; tmp_blockcount = top->ex_blockcount; tmp_state = top->ex_state; top->ex_startblock = ext->ex_startblock; top->ex_blockcount = ext->ex_blockcount; top->ex_state = ext->ex_state; ext->ex_startblock = tmp_startblock; ext->ex_blockcount = tmp_blockcount; ext->ex_state = tmp_state; current = top->next; prev = top; } prev->next = ext; ext->next = current; return; } if (avl_insert(extent_bcnt_ptrs[agno], (avlnode_t *) ext) == NULL) { do_error(_(": duplicate bno extent range\n")); } ext->last = ext; /* ext is an "anchor" node */ return; } extent_tree_node_t * findfirst_bcnt_extent(xfs_agnumber_t agno) { ASSERT(extent_bcnt_ptrs != NULL); ASSERT(extent_bcnt_ptrs[agno] != NULL); return((extent_tree_node_t *) extent_bcnt_ptrs[agno]->avl_firstino); } extent_tree_node_t * findbiggest_bcnt_extent(xfs_agnumber_t agno) { ASSERT(extent_bcnt_ptrs != NULL); ASSERT(extent_bcnt_ptrs[agno] != NULL); return((extent_tree_node_t *) avl_lastino(extent_bcnt_ptrs[agno]->avl_root)); } extent_tree_node_t * findnext_bcnt_extent(xfs_agnumber_t agno, extent_tree_node_t *ext) { avlnode_t *nextino; if (ext->next != NULL) { ASSERT(ext->ex_blockcount == ext->next->ex_blockcount); ASSERT(ext->ex_startblock < ext->next->ex_startblock); return(ext->next); } else { /* * have to look at the top of the list to get the * correct avl_nextino pointer since that pointer * is maintained and altered by the AVL code. */ nextino = avl_find(extent_bcnt_ptrs[agno], ext->ex_blockcount); ASSERT(nextino != NULL); if (nextino->avl_nextino != NULL) { ASSERT(ext->ex_blockcount < ((extent_tree_node_t *) nextino->avl_nextino)->ex_blockcount); } return((extent_tree_node_t *) nextino->avl_nextino); } } /* * this is meant to be called after you walk the bno tree to * determine exactly which extent you want (so you'll know the * desired value for startblock when you call this routine). */ extent_tree_node_t * get_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, xfs_extlen_t blockcount) { extent_tree_node_t *ext, *prev, *top; xfs_agblock_t tmp_startblock; xfs_extlen_t tmp_blockcount; extent_state_t tmp_state; prev = NULL; ASSERT(extent_bcnt_ptrs != NULL); ASSERT(extent_bcnt_ptrs[agno] != NULL); if ((ext = (extent_tree_node_t *) avl_find(extent_bcnt_ptrs[agno], blockcount)) == NULL) return(NULL); top = ext; if (ext->next != NULL) { /* * pull it off the list */ while (ext != NULL && startblock != ext->ex_startblock) { prev = ext; ext = ext->next; } ASSERT(ext != NULL); if (ext == top) { /* * this node is linked into the tree so we * swap the core values so we can delete * the next item on the list instead of * the head of the list. This is because * the rest of the tree undoubtedly has * pointers to the piece of memory that * is the head of the list so pulling * the item out of the list and hence * the avl tree would be a bad idea. * * (cheaper than the alternative, a tree * delete of this node followed by a tree * insert of the next node on the list). */ tmp_startblock = ext->next->ex_startblock; tmp_blockcount = ext->next->ex_blockcount; tmp_state = ext->next->ex_state; ext->next->ex_startblock = ext->ex_startblock; ext->next->ex_blockcount = ext->ex_blockcount; ext->next->ex_state = ext->ex_state; ext->ex_startblock = tmp_startblock; ext->ex_blockcount = tmp_blockcount; ext->ex_state = tmp_state; ext = ext->next; prev = top; } /* * now, a simple list deletion */ prev->next = ext->next; ext->next = NULL; } else { /* * no list, just one node. simply delete */ avl_delete(extent_bcnt_ptrs[agno], &ext->avl_node); } ASSERT(ext->ex_startblock == startblock); ASSERT(ext->ex_blockcount == blockcount); return(ext); } static __psunsigned_t avl_ext_start(avlnode_t *node) { return((__psunsigned_t) ((extent_tree_node_t *) node)->ex_startblock); } static __psunsigned_t avl_ext_end(avlnode_t *node) { return((__psunsigned_t) ( ((extent_tree_node_t *) node)->ex_startblock + ((extent_tree_node_t *) node)->ex_blockcount)); } /* * convert size to an address for the AVL tree code -- the bigger the size, * the lower the address so the biggest extent will be first in the tree */ static __psunsigned_t avl_ext_bcnt_start(avlnode_t *node) { /* return((__psunsigned_t) (BCNT_ADDR(((extent_tree_node_t *) node)->ex_blockcount))); */ return((__psunsigned_t) ((extent_tree_node_t *)node)->ex_blockcount); } static __psunsigned_t avl_ext_bcnt_end(avlnode_t *node) { /* return((__psunsigned_t) (BCNT_ADDR(((extent_tree_node_t *) node)->ex_blockcount))); */ return((__psunsigned_t) ((extent_tree_node_t *)node)->ex_blockcount); } avlops_t avl_extent_bcnt_tree_ops = { avl_ext_bcnt_start, avl_ext_bcnt_end }; avlops_t avl_extent_tree_ops = { avl_ext_start, avl_ext_end }; /* * for real-time extents -- have to dup code since realtime extent * startblocks can be 64-bit values. */ static rt_extent_tree_node_t * mk_rt_extent_tree_nodes(xfs_drtbno_t new_startblock, xfs_extlen_t new_blockcount, extent_state_t new_state) { rt_extent_tree_node_t *new; new = malloc(sizeof(*new)); if (!new) do_error(_("couldn't allocate new extent descriptor.\n")); new->avl_node.avl_nextino = NULL; new->rt_startblock = new_startblock; new->rt_blockcount = new_blockcount; new->rt_state = new_state; return new; } #if 0 void release_rt_extent_tree_node(rt_extent_tree_node_t *node) { free(node); } void release_rt_extent_tree() { extent_tree_node_t *ext; extent_tree_node_t *tmp; extent_tree_node_t *lext; extent_tree_node_t *ltmp; avl64tree_desc_t *tree; tree = rt_extent_tree_ptr; if (tree->avl_firstino == NULL) return; ext = (extent_tree_node_t *) tree->avl_firstino; while (ext != NULL) { tmp = (extent_tree_node_t *) ext->avl_node.avl_nextino; release_rt_extent_tree_node(ext); ext = tmp; } tree->avl_root = tree->avl_firstino = NULL; return; } #endif /* * don't need release functions for realtime tree teardown * since we only have one tree, not one per AG */ /* ARGSUSED */ void free_rt_dup_extent_tree(xfs_mount_t *mp) { ASSERT(mp->m_sb.sb_rblocks != 0); free(rt_ext_tree_ptr); rt_ext_tree_ptr = NULL; } /* * add a duplicate real-time extent */ void add_rt_dup_extent(xfs_drtbno_t startblock, xfs_extlen_t blockcount) { rt_extent_tree_node_t *first, *last, *ext, *next_ext; xfs_drtbno_t new_startblock; xfs_extlen_t new_blockcount; pthread_mutex_lock(&rt_ext_tree_lock); avl64_findranges(rt_ext_tree_ptr, startblock - 1, startblock + blockcount + 1, (avl64node_t **) &first, (avl64node_t **) &last); /* * find adjacent and overlapping extent blocks */ if (first == NULL && last == NULL) { /* nothing, just make and insert new extent */ ext = mk_rt_extent_tree_nodes(startblock, blockcount, XR_E_MULT); if (avl64_insert(rt_ext_tree_ptr, (avl64node_t *) ext) == NULL) { do_error(_("duplicate extent range\n")); } pthread_mutex_unlock(&rt_ext_tree_lock); return; } ASSERT(first != NULL && last != NULL); /* * find the new composite range, delete old extent nodes * as we go */ new_startblock = startblock; new_blockcount = blockcount; for (ext = first; ext != (rt_extent_tree_node_t *) last->avl_node.avl_nextino; ext = next_ext) { /* * preserve the next inorder node */ next_ext = (rt_extent_tree_node_t *) ext->avl_node.avl_nextino; /* * just bail if the new extent is contained within an old one */ if (ext->rt_startblock <= startblock && ext->rt_blockcount >= blockcount) { pthread_mutex_unlock(&rt_ext_tree_lock); return; } /* * now check for overlaps and adjacent extents */ if (ext->rt_startblock + ext->rt_blockcount >= startblock || ext->rt_startblock <= startblock + blockcount) { if (ext->rt_startblock < new_startblock) new_startblock = ext->rt_startblock; if (ext->rt_startblock + ext->rt_blockcount > new_startblock + new_blockcount) new_blockcount = ext->rt_startblock + ext->rt_blockcount - new_startblock; avl64_delete(rt_ext_tree_ptr, (avl64node_t *) ext); continue; } } ext = mk_rt_extent_tree_nodes(new_startblock, new_blockcount, XR_E_MULT); if (avl64_insert(rt_ext_tree_ptr, (avl64node_t *) ext) == NULL) { do_error(_("duplicate extent range\n")); } pthread_mutex_unlock(&rt_ext_tree_lock); return; } /* * returns 1 if block is a dup, 0 if not */ /* ARGSUSED */ int search_rt_dup_extent(xfs_mount_t *mp, xfs_drtbno_t bno) { int ret; pthread_mutex_lock(&rt_ext_tree_lock); if (avl64_findrange(rt_ext_tree_ptr, bno) != NULL) ret = 1; else ret = 0; pthread_mutex_unlock(&rt_ext_tree_lock); return(ret); } static __uint64_t avl64_rt_ext_start(avl64node_t *node) { return(((rt_extent_tree_node_t *) node)->rt_startblock); } static __uint64_t avl64_ext_end(avl64node_t *node) { return(((rt_extent_tree_node_t *) node)->rt_startblock + ((rt_extent_tree_node_t *) node)->rt_blockcount); } avl64ops_t avl64_extent_tree_ops = { avl64_rt_ext_start, avl64_ext_end }; void incore_ext_init(xfs_mount_t *mp) { int i; xfs_agnumber_t agcount = mp->m_sb.sb_agcount; pthread_mutex_init(&rt_ext_tree_lock, NULL); dup_extent_trees = calloc(agcount, sizeof(struct btree_root *)); if (!dup_extent_trees) do_error(_("couldn't malloc dup extent tree descriptor table\n")); dup_extent_tree_locks = calloc(agcount, sizeof(pthread_mutex_t)); if (!dup_extent_tree_locks) do_error(_("couldn't malloc dup extent tree descriptor table\n")); if ((extent_bno_ptrs = malloc(agcount * sizeof(avltree_desc_t *))) == NULL) do_error( _("couldn't malloc free by-bno extent tree descriptor table\n")); if ((extent_bcnt_ptrs = malloc(agcount * sizeof(avltree_desc_t *))) == NULL) do_error( _("couldn't malloc free by-bcnt extent tree descriptor table\n")); for (i = 0; i < agcount; i++) { if ((extent_bno_ptrs[i] = malloc(sizeof(avltree_desc_t))) == NULL) do_error( _("couldn't malloc bno extent tree descriptor\n")); if ((extent_bcnt_ptrs[i] = malloc(sizeof(avltree_desc_t))) == NULL) do_error( _("couldn't malloc bcnt extent tree descriptor\n")); } for (i = 0; i < agcount; i++) { btree_init(&dup_extent_trees[i]); pthread_mutex_init(&dup_extent_tree_locks[i], NULL); avl_init_tree(extent_bno_ptrs[i], &avl_extent_tree_ops); avl_init_tree(extent_bcnt_ptrs[i], &avl_extent_bcnt_tree_ops); } if ((rt_ext_tree_ptr = malloc(sizeof(avltree_desc_t))) == NULL) do_error(_("couldn't malloc dup rt extent tree descriptor\n")); avl64_init_tree(rt_ext_tree_ptr, &avl64_extent_tree_ops); } /* * this routine actually frees all the memory used to track per-AG trees */ void incore_ext_teardown(xfs_mount_t *mp) { xfs_agnumber_t i; for (i = 0; i < mp->m_sb.sb_agcount; i++) { btree_destroy(dup_extent_trees[i]); free(extent_bno_ptrs[i]); free(extent_bcnt_ptrs[i]); } free(dup_extent_trees); free(extent_bcnt_ptrs); free(extent_bno_ptrs); dup_extent_trees = NULL; extent_bcnt_ptrs = NULL; extent_bno_ptrs = NULL; } int count_extents(xfs_agnumber_t agno, avltree_desc_t *tree, int whichtree) { extent_tree_node_t *node; int i = 0; node = (extent_tree_node_t *) tree->avl_firstino; while (node != NULL) { i++; if (whichtree) node = findnext_bcnt_extent(agno, node); else node = findnext_bno_extent(node); } return(i); } int count_bno_extents_blocks(xfs_agnumber_t agno, uint *numblocks) { __uint64_t nblocks; extent_tree_node_t *node; int i = 0; ASSERT(agno < glob_agcount); nblocks = 0; node = (extent_tree_node_t *) extent_bno_ptrs[agno]->avl_firstino; while (node != NULL) { nblocks += node->ex_blockcount; i++; node = findnext_bno_extent(node); } *numblocks = nblocks; return(i); } int count_bno_extents(xfs_agnumber_t agno) { ASSERT(agno < glob_agcount); return(count_extents(agno, extent_bno_ptrs[agno], 0)); } int count_bcnt_extents(xfs_agnumber_t agno) { ASSERT(agno < glob_agcount); return(count_extents(agno, extent_bcnt_ptrs[agno], 1)); } xfsprogs-3.1.9ubuntu2/repair/btree.c0000664000000000000000000006412111604735741014357 0ustar /* * Copyright (c) 2007, Silicon Graphics, Inc. Barry Naujok * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "btree.h" /* * Maximum number of keys per node. Must be greater than 2 for the code * to work. */ #define BTREE_KEY_MAX 7 #define BTREE_KEY_MIN (BTREE_KEY_MAX / 2) #define BTREE_PTR_MAX (BTREE_KEY_MAX + 1) struct btree_node { unsigned long num_keys; unsigned long keys[BTREE_KEY_MAX]; struct btree_node *ptrs[BTREE_PTR_MAX]; }; struct btree_cursor { struct btree_node *node; int index; }; struct btree_root { struct btree_node *root_node; struct btree_cursor *cursor; /* track path to end leaf */ int height; /* lookup cache */ int keys_valid; /* set if the cache is valid */ unsigned long cur_key; unsigned long next_key; void *next_value; unsigned long prev_key; void *prev_value; #ifdef BTREE_STATS struct btree_stats { unsigned long num_items; unsigned long max_items; int alloced; int cache_hits; int cache_misses; int lookup; int find; int key_update; int value_update; int insert; int delete; int inc_height; int dec_height; int shift_prev; int shift_next; int split; int merge_prev; int merge_next; int balance_prev; int balance_next; } stats; #endif }; static struct btree_node * btree_node_alloc(void) { return calloc(1, sizeof(struct btree_node)); } static void btree_node_free( struct btree_node *node) { free(node); } static void btree_free_nodes( struct btree_node *node, int level) { int i; if (level) for (i = 0; i <= node->num_keys; i++) btree_free_nodes(node->ptrs[i], level - 1); btree_node_free(node); } static void __btree_init( struct btree_root *root) { memset(root, 0, sizeof(struct btree_root)); root->height = 1; root->cursor = calloc(1, sizeof(struct btree_cursor)); root->root_node = btree_node_alloc(); ASSERT(root->root_node); #ifdef BTREE_STATS root->stats.max_items = 1; root->stats.alloced += 1; #endif } static void __btree_free( struct btree_root *root) { btree_free_nodes(root->root_node, root->height - 1); free(root->cursor); root->height = 0; root->cursor = NULL; root->root_node = NULL; } void btree_init( struct btree_root **root) { *root = calloc(1, sizeof(struct btree_root)); __btree_init(*root); } void btree_clear( struct btree_root *root) { __btree_free(root); __btree_init(root); } void btree_destroy( struct btree_root *root) { __btree_free(root); free(root); } int btree_is_empty( struct btree_root *root) { return root->root_node->num_keys == 0; } static inline void btree_invalidate_cursor( struct btree_root *root) { root->cursor[0].node = NULL; root->keys_valid = 0; } static inline unsigned long btree_key_of_cursor( struct btree_cursor *cursor, int height) { while (cursor->node->num_keys == cursor->index && --height > 0) cursor++; return cursor->node->keys[cursor->index]; } static void * btree_get_prev( struct btree_root *root, unsigned long *key) { struct btree_cursor *cur = root->cursor; int level = 0; struct btree_node *node; if (cur->index > 0) { if (key) *key = cur->node->keys[cur->index - 1]; return cur->node->ptrs[cur->index - 1]; } /* else need to go up and back down the tree to find the previous */ do { if (cur->index) break; cur++; } while (++level < root->height); if (level == root->height) return NULL; /* the key is in the current level */ if (key) *key = cur->node->keys[cur->index - 1]; /* descend back down the right side to get the pointer */ node = cur->node->ptrs[cur->index - 1]; while (level--) node = node->ptrs[node->num_keys]; return node; } static void * btree_get_next( struct btree_root *root, unsigned long *key) { struct btree_cursor *cur = root->cursor; int level = 0; struct btree_node *node; while (cur->index == cur->node->num_keys) { if (++level == root->height) return NULL; cur++; } if (level == 0) { if (key) { cur->index++; *key = btree_key_of_cursor(cur, root->height); cur->index--; } return cur->node->ptrs[cur->index + 1]; } node = cur->node->ptrs[cur->index + 1]; while (--level > 0) node = node->ptrs[0]; if (key) *key = node->keys[0]; return node->ptrs[0]; } /* * Lookup/Search functions */ static int btree_do_search( struct btree_root *root, unsigned long key) { unsigned long k = 0; struct btree_cursor *cur = root->cursor + root->height; struct btree_node *node = root->root_node; int height = root->height; int key_found = 0; int i; while (--height >= 0) { cur--; for (i = 0; i < node->num_keys; i++) if (node->keys[i] >= key) { k = node->keys[i]; key_found = 1; break; } cur->node = node; cur->index = i; node = node->ptrs[i]; } root->keys_valid = key_found; if (!key_found) return 0; root->cur_key = k; root->next_value = NULL; /* do on-demand next value lookup */ root->prev_value = btree_get_prev(root, &root->prev_key); return 1; } static int btree_search( struct btree_root *root, unsigned long key) { if (root->keys_valid && key <= root->cur_key && (!root->prev_value || key > root->prev_key)) { #ifdef BTREE_STATS root->stats.cache_hits++; #endif return 1; } #ifdef BTREE_STATS root->stats.cache_misses++; #endif return btree_do_search(root, key); } void * btree_find( struct btree_root *root, unsigned long key, unsigned long *actual_key) { #ifdef BTREE_STATS root->stats.find += 1; #endif if (!btree_search(root, key)) return NULL; if (actual_key) *actual_key = root->cur_key; return root->cursor->node->ptrs[root->cursor->index]; } void * btree_lookup( struct btree_root *root, unsigned long key) { #ifdef BTREE_STATS root->stats.lookup += 1; #endif if (!btree_search(root, key) || root->cur_key != key) return NULL; return root->cursor->node->ptrs[root->cursor->index]; } void * btree_peek_prev( struct btree_root *root, unsigned long *key) { if (!root->keys_valid) return NULL; if (key) *key = root->prev_key; return root->prev_value; } void * btree_peek_next( struct btree_root *root, unsigned long *key) { if (!root->keys_valid) return NULL; if (!root->next_value) root->next_value = btree_get_next(root, &root->next_key); if (key) *key = root->next_key; return root->next_value; } static void * btree_move_cursor_to_next( struct btree_root *root, unsigned long *key) { struct btree_cursor *cur = root->cursor; int level = 0; while (cur->index == cur->node->num_keys) { if (++level == root->height) return NULL; cur++; } cur->index++; if (level == 0) { if (key) *key = btree_key_of_cursor(cur, root->height); return cur->node->ptrs[cur->index]; } while (--level >= 0) { root->cursor[level].node = cur->node->ptrs[cur->index]; root->cursor[level].index = 0; cur--; } if (key) *key = cur->node->keys[0]; return cur->node->ptrs[0]; } void * btree_lookup_next( struct btree_root *root, unsigned long *key) { void *value; if (!root->keys_valid) return NULL; root->prev_key = root->cur_key; root->prev_value = root->cursor->node->ptrs[root->cursor->index]; value = btree_move_cursor_to_next(root, &root->cur_key); if (!value) { btree_invalidate_cursor(root); return NULL; } root->next_value = NULL; /* on-demand next value fetch */ if (key) *key = root->cur_key; return value; } static void * btree_move_cursor_to_prev( struct btree_root *root, unsigned long *key) { struct btree_cursor *cur = root->cursor; int level = 0; while (cur->index == 0) { if (++level == root->height) return NULL; cur++; } cur->index--; if (key) /* the key is in the current level */ *key = cur->node->keys[cur->index]; while (level > 0) { level--; root->cursor[level].node = cur->node->ptrs[cur->index]; root->cursor[level].index = root->cursor[level].node->num_keys; cur--; } return cur->node->ptrs[cur->index]; } void * btree_lookup_prev( struct btree_root *root, unsigned long *key) { void *value; if (!root->keys_valid) return NULL; value = btree_move_cursor_to_prev(root, &root->cur_key); if (!value) return NULL; root->prev_value = btree_get_prev(root, &root->prev_key); root->next_value = NULL; /* on-demand next value fetch */ if (key) *key = root->cur_key; return value; } void * btree_uncached_lookup( struct btree_root *root, unsigned long key) { /* cursor-less (ie. uncached) lookup */ int height = root->height - 1; struct btree_node *node = root->root_node; int i; int key_found = 0; while (height >= 0) { for (i = 0; i < node->num_keys; i++) if (node->keys[i] >= key) { key_found = node->keys[i] == key; break; } node = node->ptrs[i]; height--; } return key_found ? node : NULL; } /* Update functions */ static inline void btree_update_node_key( struct btree_root *root, struct btree_cursor *cursor, int level, unsigned long new_key) { int i; #ifdef BTREE_STATS root->stats.key_update += 1; #endif cursor += level; for (i = level; i < root->height; i++) { if (cursor->index < cursor->node->num_keys) { cursor->node->keys[cursor->index] = new_key; break; } cursor++; } } int btree_update_key( struct btree_root *root, unsigned long old_key, unsigned long new_key) { if (!btree_search(root, old_key) || root->cur_key != old_key) return ENOENT; if (root->next_value && new_key >= root->next_key) return EINVAL; if (root->prev_value && new_key <= root->prev_key) return EINVAL; btree_update_node_key(root, root->cursor, 0, new_key); root->cur_key = new_key; return 0; } int btree_update_value( struct btree_root *root, unsigned long key, void *new_value) { if (!new_value) return EINVAL; if (!btree_search(root, key) || root->cur_key != key) return ENOENT; #ifdef BTREE_STATS root->stats.value_update += 1; #endif root->cursor->node->ptrs[root->cursor->index] = new_value; return 0; } /* * Cursor modification functions - used for inserting and deleting */ static struct btree_cursor * btree_copy_cursor_prev( struct btree_root *root, struct btree_cursor *dest_cursor, int level) { struct btree_cursor *src_cur = root->cursor + level; struct btree_cursor *dst_cur; int l = level; int i; if (level >= root->height) return NULL; while (src_cur->index == 0) { if (++l >= root->height) return NULL; src_cur++; } for (i = l; i < root->height; i++) dest_cursor[i] = *src_cur++; dst_cur = dest_cursor + l; dst_cur->index--; while (l-- >= level) { dest_cursor[l].node = dst_cur->node->ptrs[dst_cur->index]; dest_cursor[l].index = dest_cursor[l].node->num_keys; dst_cur--; } return dest_cursor; } static struct btree_cursor * btree_copy_cursor_next( struct btree_root *root, struct btree_cursor *dest_cursor, int level) { struct btree_cursor *src_cur = root->cursor + level; struct btree_cursor *dst_cur; int l = level; int i; if (level >= root->height) return NULL; while (src_cur->index == src_cur->node->num_keys) { if (++l >= root->height) return NULL; src_cur++; } for (i = l; i < root->height; i++) dest_cursor[i] = *src_cur++; dst_cur = dest_cursor + l; dst_cur->index++; while (l-- >= level) { dest_cursor[l].node = dst_cur->node->ptrs[dst_cur->index]; dest_cursor[l].index = 0; dst_cur--; } return dest_cursor; } /* * Shift functions * * Tries to move items in the current leaf to its sibling if it has space. * Used in both insert and delete functions. * Returns the number of items shifted. */ static int btree_shift_to_prev( struct btree_root *root, int level, struct btree_cursor *prev_cursor, int num_children) { struct btree_node *node; struct btree_node *prev_node; int num_remain; /* # of keys left in "node" */ unsigned long key; int i; if (!prev_cursor || !num_children) return 0; prev_node = prev_cursor[level].node; node = root->cursor[level].node; ASSERT(num_children > 0 && num_children <= node->num_keys + 1); if ((prev_node->num_keys + num_children) > BTREE_KEY_MAX) return 0; #ifdef BTREE_STATS root->stats.shift_prev += 1; #endif num_remain = node->num_keys - num_children; ASSERT(num_remain == -1 || num_remain >= BTREE_KEY_MIN); /* shift parent keys around */ level++; if (num_remain > 0) key = node->keys[num_children - 1]; else key = btree_key_of_cursor(root->cursor + level, root->height - level); while (prev_cursor[level].index == prev_cursor[level].node->num_keys) { level++; ASSERT(level < root->height); } prev_node->keys[prev_node->num_keys] = prev_cursor[level].node->keys[prev_cursor[level].index]; prev_cursor[level].node->keys[prev_cursor[level].index] = key; /* copy pointers and keys to the end of the prev node */ for (i = 0; i < num_children - 1; i++) { prev_node->keys[prev_node->num_keys + 1 + i] = node->keys[i]; prev_node->ptrs[prev_node->num_keys + 1 + i] = node->ptrs[i]; } prev_node->ptrs[prev_node->num_keys + 1 + i] = node->ptrs[i]; prev_node->num_keys += num_children; /* move remaining pointers/keys to start of node */ if (num_remain >= 0) { for (i = 0; i < num_remain; i++) { node->keys[i] = node->keys[num_children + i]; node->ptrs[i] = node->ptrs[num_children + i]; } node->ptrs[i] = node->ptrs[num_children + i]; node->num_keys = num_remain; } else node->num_keys = 0; return num_children; } static int btree_shift_to_next( struct btree_root *root, int level, struct btree_cursor *next_cursor, int num_children) { struct btree_node *node; struct btree_node *next_node; int num_remain; /* # of children left in node */ int i; if (!next_cursor || !num_children) return 0; node = root->cursor[level].node; next_node = next_cursor[level].node; ASSERT(num_children > 0 && num_children <= node->num_keys + 1); if ((next_node->num_keys + num_children) > BTREE_KEY_MAX) return 0; num_remain = node->num_keys + 1 - num_children; ASSERT(num_remain == 0 || num_remain > BTREE_KEY_MIN); #ifdef BTREE_STATS root->stats.shift_next += 1; #endif /* make space for "num_children" items at beginning of next-leaf */ i = next_node->num_keys; next_node->ptrs[num_children + i] = next_node->ptrs[i]; while (--i >= 0) { next_node->keys[num_children + i] = next_node->keys[i]; next_node->ptrs[num_children + i] = next_node->ptrs[i]; } /* update keys in parent and next node from parent */ do { level++; ASSERT(level < root->height); } while (root->cursor[level].index == root->cursor[level].node->num_keys); next_node->keys[num_children - 1] = root->cursor[level].node->keys[root->cursor[level].index]; root->cursor[level].node->keys[root->cursor[level].index] = node->keys[node->num_keys - num_children]; /* copy last "num_children" items from node into start of next-node */ for (i = 0; i < num_children - 1; i++) { next_node->keys[i] = node->keys[num_remain + i]; next_node->ptrs[i] = node->ptrs[num_remain + i]; } next_node->ptrs[i] = node->ptrs[num_remain + i]; next_node->num_keys += num_children; if (num_remain > 0) node->num_keys -= num_children; else node->num_keys = 0; return num_children; } /* * Insertion functions */ static struct btree_node * btree_increase_height( struct btree_root *root) { struct btree_node *new_root; struct btree_cursor *new_cursor; new_cursor = realloc(root->cursor, (root->height + 1) * sizeof(struct btree_cursor)); if (!new_cursor) return NULL; root->cursor = new_cursor; new_root = btree_node_alloc(); if (!new_root) return NULL; #ifdef BTREE_STATS root->stats.alloced += 1; root->stats.inc_height += 1; root->stats.max_items *= BTREE_PTR_MAX; #endif new_root->ptrs[0] = root->root_node; root->root_node = new_root; root->cursor[root->height].node = new_root; root->cursor[root->height].index = 0; root->height++; return new_root; } static int btree_insert_item( struct btree_root *root, int level, unsigned long key, void *value); static struct btree_node * btree_split( struct btree_root *root, int level, unsigned long key, int *index) { struct btree_node *node = root->cursor[level].node; struct btree_node *new_node; int i; new_node = btree_node_alloc(); if (!new_node) return NULL; if (btree_insert_item(root, level + 1, node->keys[BTREE_KEY_MIN], new_node) != 0) { btree_node_free(new_node); return NULL; } #ifdef BTREE_STATS root->stats.alloced += 1; root->stats.split += 1; #endif for (i = 0; i < BTREE_KEY_MAX - BTREE_KEY_MIN - 1; i++) { new_node->keys[i] = node->keys[BTREE_KEY_MIN + 1 + i]; new_node->ptrs[i] = node->ptrs[BTREE_KEY_MIN + 1 + i]; } new_node->ptrs[i] = node->ptrs[BTREE_KEY_MIN + 1 + i]; new_node->num_keys = BTREE_KEY_MAX - BTREE_KEY_MIN - 1; node->num_keys = BTREE_KEY_MIN; if (key < node->keys[BTREE_KEY_MIN]) return node; /* index doesn't change */ /* insertion point is in new node... */ *index -= BTREE_KEY_MIN + 1; return new_node; } static int btree_insert_shift_to_prev( struct btree_root *root, int level, int *index) { struct btree_cursor tmp_cursor[root->height]; int n; if (*index <= 0) return -1; if (!btree_copy_cursor_prev(root, tmp_cursor, level + 1)) return -1; n = MIN(*index, (BTREE_PTR_MAX - tmp_cursor[level].node->num_keys) / 2); if (!n || !btree_shift_to_prev(root, level, tmp_cursor, n)) return -1; *index -= n; return 0; } static int btree_insert_shift_to_next( struct btree_root *root, int level, int *index) { struct btree_cursor tmp_cursor[root->height]; int n; if (*index >= BTREE_KEY_MAX) return -1; if (!btree_copy_cursor_next(root, tmp_cursor, level + 1)) return -1; n = MIN(BTREE_KEY_MAX - *index, (BTREE_PTR_MAX - tmp_cursor[level].node->num_keys) / 2); if (!n || !btree_shift_to_next(root, level, tmp_cursor, n)) return -1; return 0; } static int btree_insert_item( struct btree_root *root, int level, unsigned long key, void *value) { struct btree_node *node = root->cursor[level].node; int index = root->cursor[level].index; int i; if (node->num_keys == BTREE_KEY_MAX) { if (btree_insert_shift_to_prev(root, level, &index) == 0) goto insert; if (btree_insert_shift_to_next(root, level, &index) == 0) goto insert; if (level == root->height - 1) { if (!btree_increase_height(root)) return ENOMEM; } node = btree_split(root, level, key, &index); if (!node) return ENOMEM; } insert: ASSERT(index <= node->num_keys); i = node->num_keys; node->ptrs[i + 1] = node->ptrs[i]; while (--i >= index) { node->keys[i + 1] = node->keys[i]; node->ptrs[i + 1] = node->ptrs[i]; } node->num_keys++; node->keys[index] = key; if (level == 0) node->ptrs[index] = value; else node->ptrs[index + 1] = value; return 0; } int btree_insert( struct btree_root *root, unsigned long key, void *value) { int result; if (!value) return EINVAL; if (btree_search(root, key) && root->cur_key == key) return EEXIST; #ifdef BTREE_STATS root->stats.insert += 1; root->stats.num_items += 1; #endif result = btree_insert_item(root, 0, key, value); btree_invalidate_cursor(root); return result; } /* * Deletion functions * * Rather more complicated as deletions has 4 ways to go once a node * ends up with less than the minimum number of keys: * - move remainder to previous node * - move remainder to next node * (both will involve a parent deletion which may recurse) * - balance by moving some items from previous node * - balance by moving some items from next node */ static void btree_decrease_height( struct btree_root *root) { struct btree_node *old_root = root->root_node; ASSERT(old_root->num_keys == 0); #ifdef BTREE_STATS root->stats.alloced -= 1; root->stats.dec_height += 1; root->stats.max_items /= BTREE_PTR_MAX; #endif root->root_node = old_root->ptrs[0]; btree_node_free(old_root); root->height--; } static int btree_merge_with_prev( struct btree_root *root, int level, struct btree_cursor *prev_cursor) { if (!prev_cursor) return 0; if (!btree_shift_to_prev(root, level, prev_cursor, root->cursor[level].node->num_keys + 1)) return 0; #ifdef BTREE_STATS root->stats.merge_prev += 1; #endif return 1; } static int btree_merge_with_next( struct btree_root *root, int level, struct btree_cursor *next_cursor) { if (!next_cursor) return 0; if (!btree_shift_to_next(root, level, next_cursor, root->cursor[level].node->num_keys + 1)) return 0; #ifdef BTREE_STATS root->stats.merge_next += 1; #endif return 1; } static int btree_balance_with_prev( struct btree_root *root, int level, struct btree_cursor *prev_cursor) { struct btree_cursor *root_cursor = root->cursor; if (!prev_cursor) return 0; ASSERT(prev_cursor[level].node->num_keys > BTREE_KEY_MIN); #ifdef BTREE_STATS root->stats.balance_prev += 1; #endif /* * Move some nodes from the prev node into the current node. * As the shift operation is a right shift and is relative to * the root cursor, make the root cursor the prev cursor and * pass in the root cursor as the next cursor. */ root->cursor = prev_cursor; if (!btree_shift_to_next(root, level, root_cursor, (prev_cursor[level].node->num_keys + 1 - BTREE_KEY_MIN) / 2)) abort(); root->cursor = root_cursor; return 1; } static int btree_balance_with_next( struct btree_root *root, int level, struct btree_cursor *next_cursor) { struct btree_cursor *root_cursor = root->cursor; if (!next_cursor) return 0; assert(next_cursor[level].node->num_keys > BTREE_KEY_MIN); #ifdef btree_stats root->stats.balance_next += 1; #endif /* * move some nodes from the next node into the current node. * as the shift operation is a left shift and is relative to * the root cursor, make the root cursor the next cursor and * pass in the root cursor as the prev cursor. */ root->cursor = next_cursor; if (!btree_shift_to_prev(root, level, root_cursor, (next_cursor[level].node->num_keys + 1 - BTREE_KEY_MIN) / 2)) abort(); root->cursor = root_cursor; return 1; } static void btree_delete_key( struct btree_root *root, int level); /* * btree_delete_node: * * Return 0 if it's done or 1 if the next level needs to be collapsed */ static void btree_delete_node( struct btree_root *root, int level) { struct btree_cursor prev_cursor[root->height]; struct btree_cursor next_cursor[root->height]; struct btree_cursor *pc; struct btree_cursor *nc; /* * the node has underflowed, grab or merge keys/items from a * neighbouring node. */ if (level == root->height - 1) { if (level > 0 && root->root_node->num_keys == 0) btree_decrease_height(root); return; } pc = btree_copy_cursor_prev(root, prev_cursor, level + 1); if (!btree_merge_with_prev(root, level, pc)) { nc = btree_copy_cursor_next(root, next_cursor, level + 1); if (!btree_merge_with_next(root, level, nc)) { /* merging failed, try redistrubution */ if (!btree_balance_with_prev(root, level, pc) && !btree_balance_with_next(root, level, nc)) abort(); return; /* when balancing, then the node isn't freed */ } } #ifdef BTREE_STATS root->stats.alloced -= 1; #endif btree_node_free(root->cursor[level].node); btree_delete_key(root, level + 1); } static void btree_delete_key( struct btree_root *root, int level) { struct btree_node *node = root->cursor[level].node; int index = root->cursor[level].index; node->num_keys--; if (index <= node->num_keys) { /* * if not deleting the last item, shift higher items down * to cover the item being deleted */ while (index < node->num_keys) { node->keys[index] = node->keys[index + 1]; node->ptrs[index] = node->ptrs[index + 1]; index++; } node->ptrs[index] = node->ptrs[index + 1]; } else { /* * else update the associated parent key as the last key * in the leaf has changed */ btree_update_node_key(root, root->cursor, level + 1, node->keys[node->num_keys]); } /* * if node underflows, either merge with sibling or rebalance * with sibling. */ if (node->num_keys < BTREE_KEY_MIN) btree_delete_node(root, level); } void * btree_delete( struct btree_root *root, unsigned long key) { void *value; value = btree_lookup(root, key); if (!value) return NULL; #ifdef BTREE_STATS root->stats.delete += 1; root->stats.num_items -= 1; #endif btree_delete_key(root, 0); btree_invalidate_cursor(root); return value; } #ifdef BTREE_STATS void btree_print_stats( struct btree_root *root, FILE *f) { unsigned long max_items = root->stats.max_items * (root->root_node->num_keys + 1); fprintf(f, "\tnum_items = %lu, max_items = %lu (%lu%%)\n", root->stats.num_items, max_items, root->stats.num_items * 100 / max_items); fprintf(f, "\talloced = %d nodes, %lu bytes, %lu bytes per item\n", root->stats.alloced, root->stats.alloced * sizeof(struct btree_node), root->stats.alloced * sizeof(struct btree_node) / root->stats.num_items); fprintf(f, "\tlookup = %d\n", root->stats.lookup); fprintf(f, "\tfind = %d\n", root->stats.find); fprintf(f, "\tcache_hits = %d\n", root->stats.cache_hits); fprintf(f, "\tcache_misses = %d\n", root->stats.cache_misses); fprintf(f, "\tkey_update = %d\n", root->stats.key_update); fprintf(f, "\tvalue_update = %d\n", root->stats.value_update); fprintf(f, "\tinsert = %d\n", root->stats.insert); fprintf(f, "\tshift_prev = %d\n", root->stats.shift_prev); fprintf(f, "\tshift_next = %d\n", root->stats.shift_next); fprintf(f, "\tsplit = %d\n", root->stats.split); fprintf(f, "\tinc_height = %d\n", root->stats.inc_height); fprintf(f, "\tdelete = %d\n", root->stats.delete); fprintf(f, "\tmerge_prev = %d\n", root->stats.merge_prev); fprintf(f, "\tmerge_next = %d\n", root->stats.merge_next); fprintf(f, "\tbalance_prev = %d\n", root->stats.balance_prev); fprintf(f, "\tbalance_next = %d\n", root->stats.balance_next); fprintf(f, "\tdec_height = %d\n", root->stats.dec_height); } #endif xfsprogs-3.1.9ubuntu2/repair/avl64.c0000664000000000000000000007465311146407622014220 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "avl64.h" #define CERT ASSERT #ifdef AVL_DEBUG static void avl64_checknode( register avl64tree_desc_t *tree, register avl64node_t *np) { register avl64node_t *back = np->avl_back; register avl64node_t *forw = np->avl_forw; register avl64node_t *nextino = np->avl_nextino; register int bal = np->avl_balance; ASSERT(bal != AVL_BALANCE || (!back && !forw) || (back && forw)); ASSERT(bal != AVL_FORW || forw); ASSERT(bal != AVL_BACK || back); if (forw) { ASSERT(AVL_START(tree, np) < AVL_START(tree, forw)); ASSERT(np->avl_forw->avl_parent == np); ASSERT(back || bal == AVL_FORW); } else { ASSERT(bal != AVL_FORW); ASSERT(bal == AVL_BALANCE || back); ASSERT(bal == AVL_BACK || !back); } if (back) { ASSERT(AVL_START(tree, np) > AVL_START(tree, back)); ASSERT(np->avl_back->avl_parent == np); ASSERT(forw || bal == AVL_BACK); } else { ASSERT(bal != AVL_BACK); ASSERT(bal == AVL_BALANCE || forw); ASSERT(bal == AVL_FORW || !forw); } if (nextino == NULL) ASSERT(forw == NULL); else ASSERT(AVL_END(tree, np) <= AVL_START(tree, nextino)); } static void avl64_checktree( register avl64tree_desc_t *tree, register avl64node_t *root) { register avl64node_t *nlast, *nnext, *np; __uint64_t offset = 0; __uint64_t end; nlast = nnext = root; ASSERT(!nnext || nnext->avl_parent == NULL); while (nnext) { avl64_checknode(tree, nnext); end = AVL_END(tree, nnext); if (end <= offset) { if ((np = nnext->avl_forw) && np != nlast) { nlast = nnext; nnext = np; } else { nlast = nnext; nnext = nnext->avl_parent; } continue; } nlast = nnext; if (np = nnext->avl_back) { if (AVL_END(tree, np) > offset) { nnext = np; continue; } } np = nnext; nnext = nnext->avl_forw; if (!nnext) nnext = np->avl_parent; offset = end; } } #else /* ! AVL_DEBUG */ #define avl64_checktree(t,x) #endif /* AVL_DEBUG */ /* * Reset balance for np up through tree. * ``direction'' is the way that np's balance * is headed after the deletion of one of its children -- * e.g., deleting a avl_forw child sends avl_balance toward AVL_BACK. * Called only when deleting a node from the tree. */ static void retreat( avl64tree_desc_t *tree, register avl64node_t *np, register int direction) { register avl64node_t **rootp = &tree->avl_root; register avl64node_t *parent; register avl64node_t *child; register avl64node_t *tmp; register int bal; do { ASSERT(direction == AVL_BACK || direction == AVL_FORW); if (np->avl_balance == AVL_BALANCE) { np->avl_balance = direction; return; } parent = np->avl_parent; /* * If balance is being restored, no local node * reorganization is necessary, but may be at * a higher node. Reset direction and continue. */ if (direction != np->avl_balance) { np->avl_balance = AVL_BALANCE; if (parent) { if (parent->avl_forw == np) direction = AVL_BACK; else direction = AVL_FORW; np = parent; continue; } return; } /* * Imbalance. If a avl_forw node was removed, direction * (and, by reduction, np->avl_balance) is/was AVL_BACK. */ if (np->avl_balance == AVL_BACK) { ASSERT(direction == AVL_BACK); child = np->avl_back; bal = child->avl_balance; if (bal != AVL_FORW) /* single LL */ { /* * np gets pushed down to lesser child's * avl_forw branch. * * np-> -D +B * / \ / \ * child-> B deleted A -D * / \ / * A C C cmn_err(CE_CONT, "!LL delete b 0x%x c 0x%x\n", np, child); */ np->avl_back = child->avl_forw; if (child->avl_forw) child->avl_forw->avl_parent = np; child->avl_forw = np; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = child; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = child; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = child; } np->avl_parent = child; child->avl_parent = parent; if (bal == AVL_BALANCE) { np->avl_balance = AVL_BACK; child->avl_balance = AVL_FORW; return; } else { np->avl_balance = AVL_BALANCE; child->avl_balance = AVL_BALANCE; np = parent; avl64_checktree(tree, *rootp); continue; } } /* child->avl_balance == AVL_FORW double LR rotation * * child's avl_forw node gets promoted up, along with * its avl_forw subtree * * np-> -G C * / \ / \ * child-> +B H -B G * / \ \ / / \ * A +C deleted A D H * \ * D cmn_err(CE_CONT, "!LR delete b 0x%x c 0x%x t 0x%x\n", np, child, child->avl_forw); */ tmp = child->avl_forw; bal = tmp->avl_balance; child->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = child; tmp->avl_back = child; child->avl_parent = tmp; np->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = np; tmp->avl_forw = np; if (bal == AVL_FORW) child->avl_balance = AVL_BACK; else child->avl_balance = AVL_BALANCE; if (bal == AVL_BACK) np->avl_balance = AVL_FORW; else np->avl_balance = AVL_BALANCE; goto next; } ASSERT(np->avl_balance == AVL_FORW && direction == AVL_FORW); child = np->avl_forw; bal = child->avl_balance; if (bal != AVL_BACK) /* single RR */ { /* * np gets pushed down to greater child's * avl_back branch. * * np-> +B -D * / \ / \ * deleted D <-child +B E * / \ \ * C E C cmn_err(CE_CONT, "!RR delete b 0x%x c 0x%x\n", np, child); */ np->avl_forw = child->avl_back; if (child->avl_back) child->avl_back->avl_parent = np; child->avl_back = np; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = child; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = child; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = child; } np->avl_parent = child; child->avl_parent = parent; if (bal == AVL_BALANCE) { np->avl_balance = AVL_FORW; child->avl_balance = AVL_BACK; return; } else { np->avl_balance = AVL_BALANCE; child->avl_balance = AVL_BALANCE; np = parent; avl64_checktree(tree, *rootp); continue; } } /* child->avl_balance == AVL_BACK double RL rotation cmn_err(CE_CONT, "!RL delete b 0x%x c 0x%x t 0x%x\n", np, child, child->avl_back); */ tmp = child->avl_back; bal = tmp->avl_balance; child->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = child; tmp->avl_forw = child; child->avl_parent = tmp; np->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = np; tmp->avl_back = np; if (bal == AVL_BACK) child->avl_balance = AVL_FORW; else child->avl_balance = AVL_BALANCE; if (bal == AVL_FORW) np->avl_balance = AVL_BACK; else np->avl_balance = AVL_BALANCE; next: np->avl_parent = tmp; tmp->avl_balance = AVL_BALANCE; tmp->avl_parent = parent; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = tmp; direction = AVL_BACK; } else { ASSERT(parent->avl_back == np); parent->avl_back = tmp; direction = AVL_FORW; } } else { ASSERT(*rootp == np); *rootp = tmp; return; } np = parent; avl64_checktree(tree, *rootp); } while (np); } /* * Remove node from tree. * avl_delete does the local tree manipulations, * calls retreat() to rebalance tree up to its root. */ void avl64_delete( register avl64tree_desc_t *tree, register avl64node_t *np) { register avl64node_t *forw = np->avl_forw; register avl64node_t *back = np->avl_back; register avl64node_t *parent = np->avl_parent; register avl64node_t *nnext; if (np->avl_back) { /* * a left child exits, then greatest left descendent's nextino * is pointing to np; make it point to np->nextino. */ nnext = np->avl_back; while (nnext) { if (!nnext->avl_forw) break; /* can't find anything bigger */ nnext = nnext->avl_forw; } } else if (np->avl_parent) { /* * find nearest ancestor with lesser value. That ancestor's * nextino is pointing to np; make it point to np->nextino */ nnext = np->avl_parent; while (nnext) { if (AVL_END(tree, nnext) <= AVL_END(tree, np)) break; nnext = nnext->avl_parent; } } else nnext = NULL; if (nnext) { ASSERT(nnext->avl_nextino == np); nnext->avl_nextino = np->avl_nextino; /* * Something preceeds np; np cannot be firstino. */ ASSERT(tree->avl_firstino != np); } else { /* * Nothing preceeding np; after deletion, np's nextino * is firstino of tree. */ ASSERT(tree->avl_firstino == np); tree->avl_firstino = np->avl_nextino; } /* * Degenerate cases... */ if (forw == NULL) { forw = back; goto attach; } if (back == NULL) { attach: if (forw) forw->avl_parent = parent; if (parent) { if (parent->avl_forw == np) { parent->avl_forw = forw; retreat(tree, parent, AVL_BACK); } else { ASSERT(parent->avl_back == np); parent->avl_back = forw; retreat(tree, parent, AVL_FORW); } } else { ASSERT(tree->avl_root == np); tree->avl_root = forw; } avl64_checktree(tree, tree->avl_root); return; } /* * Harder case: children on both sides. * If back's avl_forw pointer is null, just have back * inherit np's avl_forw tree, remove np from the tree * and adjust balance counters starting at back. * * np-> xI xH (befor retreat()) * / \ / \ * back-> H J G J * / / \ / \ * G ? ? ? ? * / \ * ? ? */ if ((forw = back->avl_forw) == NULL) { /* * AVL_FORW retreat below will set back's * balance to AVL_BACK. */ back->avl_balance = np->avl_balance; back->avl_forw = forw = np->avl_forw; forw->avl_parent = back; back->avl_parent = parent; if (parent) { if (parent->avl_forw == np) parent->avl_forw = back; else { ASSERT(parent->avl_back == np); parent->avl_back = back; } } else { ASSERT(tree->avl_root == np); tree->avl_root = back; } /* * back is taking np's place in the tree, and * has therefore lost a avl_back node (itself). */ retreat(tree, back, AVL_FORW); avl64_checktree(tree, tree->avl_root); return; } /* * Hardest case: children on both sides, and back's * avl_forw pointer isn't null. Find the immediately * inferior buffer by following back's avl_forw line * to the end, then have it inherit np's avl_forw tree. * * np-> xI xH * / \ / \ * G J back-> G J (before retreat()) * / \ / \ * F ?... F ?1 * / \ * ? H <-forw * / * ?1 */ while ((back = forw->avl_forw)) forw = back; /* * Will be adjusted by retreat() below. */ forw->avl_balance = np->avl_balance; /* * forw inherits np's avl_forw... */ forw->avl_forw = np->avl_forw; np->avl_forw->avl_parent = forw; /* * ... forw's parent gets forw's avl_back... */ back = forw->avl_parent; back->avl_forw = forw->avl_back; if (forw->avl_back) forw->avl_back->avl_parent = back; /* * ... forw gets np's avl_back... */ forw->avl_back = np->avl_back; np->avl_back->avl_parent = forw; /* * ... and forw gets np's parent. */ forw->avl_parent = parent; if (parent) { if (parent->avl_forw == np) parent->avl_forw = forw; else parent->avl_back = forw; } else { ASSERT(tree->avl_root == np); tree->avl_root = forw; } /* * What used to be forw's parent is the starting * point for rebalancing. It has lost a avl_forw node. */ retreat(tree, back, AVL_BACK); avl64_checktree(tree, tree->avl_root); } /* * avl_findanyrange: * * Given range r [start, end), find any range which is contained in r. * if checklen is non-zero, then only ranges of non-zero length are * considered in finding a match. */ avl64node_t * avl64_findanyrange( register avl64tree_desc_t *tree, register __uint64_t start, register __uint64_t end, int checklen) { register avl64node_t *np = tree->avl_root; /* np = avl64_findadjacent(tree, start, AVL_SUCCEED); */ while (np) { if (start < AVL_START(tree, np)) { if (np->avl_back) { np = np->avl_back; continue; } /* if we were to add node with start, would * have a growth of AVL_BACK */ /* if succeeding node is needed, this is it. */ break; } if (start >= AVL_END(tree, np)) { if (np->avl_forw) { np = np->avl_forw; continue; } /* if we were to add node with start, would * have a growth of AVL_FORW; */ /* we are looking for a succeeding node; * this is nextino. */ np = np->avl_nextino; break; } /* AVL_START(tree, np) <= start < AVL_END(tree, np) */ break; } if (np) { if (checklen == AVL_INCLUDE_ZEROLEN) { if (end <= AVL_START(tree, np)) { /* something follows start, but is * is entierly after the range (end) */ return(NULL); } /* np may stradle [start, end) */ return(np); } /* * find non-zero length region */ while (np && (AVL_END(tree, np) - AVL_START(tree, np) == 0) && (AVL_START(tree, np) < end)) np = np->avl_nextino; if ((np == NULL) || (AVL_START(tree, np) >= end)) return NULL; return(np); } /* * nothing succeeds start, all existing ranges are before start. */ return NULL; } /* * Returns a pointer to range which contains value. */ avl64node_t * avl64_findrange( register avl64tree_desc_t *tree, register __uint64_t value) { register avl64node_t *np = tree->avl_root; while (np) { if (value < AVL_START(tree, np)) { np = np->avl_back; continue; } if (value >= AVL_END(tree, np)) { np = np->avl_forw; continue; } ASSERT(AVL_START(tree, np) <= value && value < AVL_END(tree, np)); return np; } return NULL; } /* * Returns a pointer to node which contains exact value. */ avl64node_t * avl64_find( register avl64tree_desc_t *tree, register __uint64_t value) { register avl64node_t *np = tree->avl_root; register __uint64_t nvalue; while (np) { nvalue = AVL_START(tree, np); if (value < nvalue) { np = np->avl_back; continue; } if (value == nvalue) { return np; } np = np->avl_forw; } return NULL; } /* * Balance buffer AVL tree after attaching a new node to root. * Called only by avl_insert. */ static void avl64_balance( register avl64node_t **rootp, register avl64node_t *np, register int growth) { /* * At this point, np points to the node to which * a new node has been attached. All that remains is to * propagate avl_balance up the tree. */ for ( ; ; ) { register avl64node_t *parent = np->avl_parent; register avl64node_t *child; CERT(growth == AVL_BACK || growth == AVL_FORW); /* * If the buffer was already balanced, set avl_balance * to the new direction. Continue if there is a * parent after setting growth to reflect np's * relation to its parent. */ if (np->avl_balance == AVL_BALANCE) { np->avl_balance = growth; if (parent) { if (parent->avl_forw == np) growth = AVL_FORW; else { ASSERT(parent->avl_back == np); growth = AVL_BACK; } np = parent; continue; } break; } if (growth != np->avl_balance) { /* * Subtree is now balanced -- no net effect * in the size of the subtree, so leave. */ np->avl_balance = AVL_BALANCE; break; } if (growth == AVL_BACK) { child = np->avl_back; CERT(np->avl_balance == AVL_BACK && child); if (child->avl_balance == AVL_BACK) { /* single LL */ /* * ``A'' just got inserted; * np points to ``E'', child to ``C'', * and it is already AVL_BACK -- * child will get promoted to top of subtree. np-> -E C / \ / \ child-> -C F -B E / \ / / \ -B D A D F / A Note that child->avl_parent and avl_balance get set in common code. */ np->avl_parent = child; np->avl_balance = AVL_BALANCE; np->avl_back = child->avl_forw; if (child->avl_forw) child->avl_forw->avl_parent = np; child->avl_forw = np; } else { /* * double LR * * child's avl_forw node gets promoted to * the top of the subtree. np-> -E C / \ / \ child-> +B F -B E / \ / / \ A +C A D F \ D */ register avl64node_t *tmp = child->avl_forw; CERT(child->avl_balance == AVL_FORW && tmp); child->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = child; tmp->avl_back = child; child->avl_parent = tmp; np->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = np; tmp->avl_forw = np; np->avl_parent = tmp; if (tmp->avl_balance == AVL_BACK) np->avl_balance = AVL_FORW; else np->avl_balance = AVL_BALANCE; if (tmp->avl_balance == AVL_FORW) child->avl_balance = AVL_BACK; else child->avl_balance = AVL_BALANCE; /* * Set child to point to tmp since it is * now the top of the subtree, and will * get attached to the subtree parent in * the common code below. */ child = tmp; } } else /* growth == AVL_BACK */ { /* * This code is the mirror image of AVL_FORW above. */ child = np->avl_forw; CERT(np->avl_balance == AVL_FORW && child); if (child->avl_balance == AVL_FORW) { /* single RR */ np->avl_parent = child; np->avl_balance = AVL_BALANCE; np->avl_forw = child->avl_back; if (child->avl_back) child->avl_back->avl_parent = np; child->avl_back = np; } else { /* * double RL */ register avl64node_t *tmp = child->avl_back; ASSERT(child->avl_balance == AVL_BACK && tmp); child->avl_back = tmp->avl_forw; if (tmp->avl_forw) tmp->avl_forw->avl_parent = child; tmp->avl_forw = child; child->avl_parent = tmp; np->avl_forw = tmp->avl_back; if (tmp->avl_back) tmp->avl_back->avl_parent = np; tmp->avl_back = np; np->avl_parent = tmp; if (tmp->avl_balance == AVL_FORW) np->avl_balance = AVL_BACK; else np->avl_balance = AVL_BALANCE; if (tmp->avl_balance == AVL_BACK) child->avl_balance = AVL_FORW; else child->avl_balance = AVL_BALANCE; child = tmp; } } child->avl_parent = parent; child->avl_balance = AVL_BALANCE; if (parent) { if (parent->avl_back == np) parent->avl_back = child; else parent->avl_forw = child; } else { ASSERT(*rootp == np); *rootp = child; } break; } } static avl64node_t * avl64_insert_find_growth( register avl64tree_desc_t *tree, register __uint64_t start, /* range start at start, */ register __uint64_t end, /* exclusive */ register int *growthp) /* OUT */ { avl64node_t *root = tree->avl_root; register avl64node_t *np; np = root; ASSERT(np); /* caller ensures that there is atleast one node in tree */ for ( ; ; ) { CERT(np->avl_parent || root == np); CERT(!np->avl_parent || root != np); CERT(!(np->avl_back) || np->avl_back->avl_parent == np); CERT(!(np->avl_forw) || np->avl_forw->avl_parent == np); CERT(np->avl_balance != AVL_FORW || np->avl_forw); CERT(np->avl_balance != AVL_BACK || np->avl_back); CERT(np->avl_balance != AVL_BALANCE || np->avl_back == NULL || np->avl_forw); CERT(np->avl_balance != AVL_BALANCE || np->avl_forw == NULL || np->avl_back); if (AVL_START(tree, np) >= end) { if (np->avl_back) { np = np->avl_back; continue; } *growthp = AVL_BACK; break; } if (AVL_END(tree, np) <= start) { if (np->avl_forw) { np = np->avl_forw; continue; } *growthp = AVL_FORW; break; } /* found exact match -- let caller decide if it is an error */ return(NULL); } return(np); } static void avl64_insert_grow( register avl64tree_desc_t *tree, register avl64node_t *parent, register avl64node_t *newnode, register int growth) { register avl64node_t *nnext; register __uint64_t start = AVL_START(tree, newnode); if (growth == AVL_BACK) { parent->avl_back = newnode; /* * we are growing to the left; previous in-order to newnode is * closest ancestor with lesser value. Before this * insertion, this ancestor will be pointing to * newnode's parent. After insertion, next in-order to newnode * is the parent. */ newnode->avl_nextino = parent; nnext = parent; while (nnext) { if (AVL_END(tree, nnext) <= start) break; nnext = nnext->avl_parent; } if (nnext) { /* * nnext will be null if newnode is * the least element, and hence very first in the list. */ ASSERT(nnext->avl_nextino == parent); nnext->avl_nextino = newnode; } } else { parent->avl_forw = newnode; newnode->avl_nextino = parent->avl_nextino; parent->avl_nextino = newnode; } } avl64node_t * avl64_insert( register avl64tree_desc_t *tree, register avl64node_t *newnode) { register avl64node_t *np; register __uint64_t start = AVL_START(tree, newnode); register __uint64_t end = AVL_END(tree, newnode); int growth; ASSERT(newnode); /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if ((np = tree->avl_root) == NULL) { /* degenerate case... */ tree->avl_root = newnode; tree->avl_firstino = newnode; return newnode; } if ((np = avl64_insert_find_growth(tree, start, end, &growth)) == NULL) { if (start != end) { /* non-zero length range */ fprintf(stderr, _("avl_insert: Warning! duplicate range [%llu,%llu]\n"), (unsigned long long)start, (unsigned long long)end); } return(NULL); } avl64_insert_grow(tree, np, newnode, growth); if (growth == AVL_BACK) { /* * Growing to left. if np was firstino, newnode will be firstino */ if (tree->avl_firstino == np) tree->avl_firstino = newnode; } #ifdef notneeded else if (growth == AVL_FORW) /* * Cannot possibly be firstino; there is somebody to our left. */ ; #endif newnode->avl_parent = np; CERT(np->avl_forw == newnode || np->avl_back == newnode); avl64_balance(&tree->avl_root, np, growth); avl64_checktree(tree, tree->avl_root); return newnode; } /* * * avl64_insert_immediate(tree, afterp, newnode): * insert newnode immediately into tree immediately after afterp. * after insertion, newnode is right child of afterp. */ void avl64_insert_immediate( avl64tree_desc_t *tree, avl64node_t *afterp, avl64node_t *newnode) { /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if (afterp == NULL) { tree->avl_root = newnode; tree->avl_firstino = newnode; return; } ASSERT(afterp->avl_forw == NULL); avl64_insert_grow(tree, afterp, newnode, AVL_FORW); /* grow to right */ CERT(afterp->avl_forw == newnode); avl64_balance(&tree->avl_root, afterp, AVL_FORW); avl64_checktree(tree, tree->avl_root); } /* * Returns first in order node */ avl64node_t * avl64_firstino(register avl64node_t *root) { register avl64node_t *np; if ((np = root) == NULL) return NULL; while (np->avl_back) np = np->avl_back; return np; } /* * Returns last in order node */ avl64node_t * avl64_lastino(register avl64node_t *root) { register avl64node_t *np; if ((np = root) == NULL) return NULL; while (np->avl_forw) np = np->avl_forw; return np; } void avl64_init_tree(avl64tree_desc_t *tree, avl64ops_t *ops) { tree->avl_root = NULL; tree->avl_firstino = NULL; tree->avl_ops = ops; } #ifdef AVL_DEBUG static void avl64_printnode(avl64tree_desc_t *tree, avl64node_t *np, int nl) { printf("[%d-%d]%c", AVL_START(tree, np), (AVL_END(tree, np) - 1), nl ? '\n' : ' '); } #endif #ifdef STAND_ALONE_DEBUG struct avl_debug_node { avl64node_t avl_node; xfs_off_t avl_start; unsigned int avl_size; } avl64ops_t avl_debug_ops = { avl_debug_start, avl_debug_end, } static __uint64_t avl64_debug_start(avl64node_t *node) { return (__uint64_t)(struct avl_debug_node *)node->avl_start; } static __uint64_t avl64_debug_end(avl64node_t *node) { return (__uint64_t) ((struct avl_debug_node *)node->avl_start + (struct avl_debug_node *)node->avl_size); } avl_debug_node freenodes[100]; avl_debug_node *freehead = &freenodes[0]; static avl64node_t * alloc_avl64_debug_node() { freehead->avl_balance = AVL_BALANCE; freehead->avl_parent = freehead->avl_forw = freehead->avl_back = NULL; return(freehead++); } static void avl64_print(avl64tree_desc_t *tree, avl64node_t *root, int depth) { int i; if (!root) return; if (root->avl_forw) avl64_print(tree, root->avl_forw, depth+5); for (i = 0; i < depth; i++) putchar((int) ' '); avl64_printnode(tree, root,1); if (root->avl_back) avl64_print(tree, root->avl_back, depth+5); } main() { int i, j; avl64node_t *np; avl64tree_desc_t tree; char linebuf[256], cmd[256]; avl64_init_tree(&tree, &avl_debug_ops); for (i = 100; i > 0; i = i - 10) { np = alloc__debug_avlnode(); ASSERT(np); np->avl_start = i; np->avl_size = 10; avl64_insert(&tree, np); } avl64_print(&tree, tree.avl_root, 0); for (np = tree.avl_firstino; np != NULL; np = np->avl_nextino) avl64_printnode(&tree, np, 0); printf("\n"); while (1) { printf(_("Command [fpdir] : ")); fgets(linebuf, 256, stdin); if (feof(stdin)) break; cmd[0] = NULL; if (sscanf(linebuf, "%[fpdir]%d", cmd, &i) != 2) continue; switch (cmd[0]) { case 'd': case 'f': printf(_("end of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); if (i == j) j = i+1; np = avl64_findinrange(&tree,i,j); if (np) { avl64_printnode(&tree, np, 1); if (cmd[0] == 'd') avl64_delete(&tree, np); } else printf(_("Cannot find %d\n"), i); break; case 'p': avl64_print(&tree, tree.avl_root, 0); for (np = tree.avl_firstino; np != NULL; np = np->avl_nextino) avl64_printnode(&tree, np, 0); printf("\n"); break; case 'i': np = alloc_avlnode(); ASSERT(np); np->avl_start = i; printf(_("size of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); np->avl_size = j; avl64_insert(&tree, np); break; case 'r': { avl64node_t *b, *e, *t; int checklen; printf(_("End of range ? ")); fgets(linebuf, 256, stdin); j = atoi(linebuf); printf(_("checklen 0/1 ? ")); fgets(linebuf, 256, stdin); checklen = atoi(linebuf); b = avl64_findanyrange(&tree, i, j, checklen); if (b) { printf(_("Found something\n")); t = b; while (t) { if (t != b && AVL_START(&tree, t) >= j) break; avl64_printnode(&tree, t, 0); t = t->avl_nextino; } printf("\n"); } } } } } #endif /* * Given a tree, find value; will find return range enclosing value, * or range immediately succeeding value, * or range immediately preceeding value. */ avl64node_t * avl64_findadjacent( register avl64tree_desc_t *tree, register __uint64_t value, register int dir) { register avl64node_t *np = tree->avl_root; while (np) { if (value < AVL_START(tree, np)) { if (np->avl_back) { np = np->avl_back; continue; } /* if we were to add node with value, would * have a growth of AVL_BACK */ if (dir == AVL_SUCCEED) { /* if succeeding node is needed, this is it. */ return(np); } if (dir == AVL_PRECEED) { /* * find nearest ancestor with lesser value. */ np = np->avl_parent; while (np) { if (AVL_END(tree, np) <= value) break; np = np->avl_parent; } return(np); } ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED); break; } if (value >= AVL_END(tree, np)) { if (np->avl_forw) { np = np->avl_forw; continue; } /* if we were to add node with value, would * have a growth of AVL_FORW; */ if (dir == AVL_SUCCEED) { /* we are looking for a succeeding node; * this is nextino. */ return(np->avl_nextino); } if (dir == AVL_PRECEED) { /* looking for a preceeding node; this is it. */ return(np); } ASSERT(dir == AVL_SUCCEED || dir == AVL_PRECEED); } /* AVL_START(tree, np) <= value < AVL_END(tree, np) */ return(np); } return NULL; } /* * avl_findranges: * * Given range r [start, end), find all ranges in tree which are contained * in r. At return, startp and endp point to first and last of * a chain of elements which describe the contained ranges. Elements * in startp ... endp are in sort order, and can be accessed by * using avl_nextino. */ void avl64_findranges( register avl64tree_desc_t *tree, register __uint64_t start, register __uint64_t end, avl64node_t **startp, avl64node_t **endp) { register avl64node_t *np; np = avl64_findadjacent(tree, start, AVL_SUCCEED); if (np == NULL /* nothing succeding start */ || (np && (end <= AVL_START(tree, np)))) /* something follows start, but... is entirely after end */ { *startp = NULL; *endp = NULL; return; } *startp = np; /* see if end is in this region itself */ if (end <= AVL_END(tree, np) || np->avl_nextino == NULL || (np->avl_nextino && (end <= AVL_START(tree, np->avl_nextino)))) { *endp = np; return; } /* have to munge for end */ /* * note: have to look for (end - 1), since * findadjacent will look for exact value, and does not * care about the fact that end is actually one more * than the value actually being looked for; thus feed it one less. */ *endp = avl64_findadjacent(tree, (end-1), AVL_PRECEED); ASSERT(*endp); } xfsprogs-3.1.9ubuntu2/repair/incore_ino.c0000664000000000000000000004512412062210562015370 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "incore.h" #include "agheader.h" #include "protos.h" #include "threads.h" #include "err_protos.h" /* * array of inode tree ptrs, one per ag */ avltree_desc_t **inode_tree_ptrs; /* * ditto for uncertain inodes */ static avltree_desc_t **inode_uncertain_tree_ptrs; /* memory optimised nlink counting for all inodes */ static void * alloc_nlink_array(__uint8_t nlink_size) { void *ptr; ptr = calloc(XFS_INODES_PER_CHUNK, nlink_size); if (!ptr) do_error(_("could not allocate nlink array\n")); return ptr; } static void nlink_grow_8_to_16(ino_tree_node_t *irec) { __uint16_t *new_nlinks; int i; irec->nlink_size = sizeof(__uint16_t); new_nlinks = alloc_nlink_array(irec->nlink_size); for (i = 0; i < XFS_INODES_PER_CHUNK; i++) new_nlinks[i] = irec->disk_nlinks.un8[i]; free(irec->disk_nlinks.un8); irec->disk_nlinks.un16 = new_nlinks; if (full_ino_ex_data) { new_nlinks = alloc_nlink_array(irec->nlink_size); for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { new_nlinks[i] = irec->ino_un.ex_data->counted_nlinks.un8[i]; } free(irec->ino_un.ex_data->counted_nlinks.un8); irec->ino_un.ex_data->counted_nlinks.un16 = new_nlinks; } } static void nlink_grow_16_to_32(ino_tree_node_t *irec) { __uint32_t *new_nlinks; int i; irec->nlink_size = sizeof(__uint32_t); new_nlinks = alloc_nlink_array(irec->nlink_size); for (i = 0; i < XFS_INODES_PER_CHUNK; i++) new_nlinks[i] = irec->disk_nlinks.un16[i]; free(irec->disk_nlinks.un16); irec->disk_nlinks.un32 = new_nlinks; if (full_ino_ex_data) { new_nlinks = alloc_nlink_array(irec->nlink_size); for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { new_nlinks[i] = irec->ino_un.ex_data->counted_nlinks.un16[i]; } free(irec->ino_un.ex_data->counted_nlinks.un16); irec->ino_un.ex_data->counted_nlinks.un32 = new_nlinks; } } void add_inode_ref(struct ino_tree_node *irec, int ino_offset) { ASSERT(irec->ino_un.ex_data != NULL); switch (irec->nlink_size) { case sizeof(__uint8_t): if (irec->ino_un.ex_data->counted_nlinks.un8[ino_offset] < 0xff) { irec->ino_un.ex_data->counted_nlinks.un8[ino_offset]++; break; } nlink_grow_8_to_16(irec); /*FALLTHRU*/ case sizeof(__uint16_t): if (irec->ino_un.ex_data->counted_nlinks.un16[ino_offset] < 0xffff) { irec->ino_un.ex_data->counted_nlinks.un16[ino_offset]++; break; } nlink_grow_16_to_32(irec); /*FALLTHRU*/ case sizeof(__uint32_t): irec->ino_un.ex_data->counted_nlinks.un32[ino_offset]++; break; default: ASSERT(0); } } void drop_inode_ref(struct ino_tree_node *irec, int ino_offset) { __uint32_t refs = 0; ASSERT(irec->ino_un.ex_data != NULL); switch (irec->nlink_size) { case sizeof(__uint8_t): ASSERT(irec->ino_un.ex_data->counted_nlinks.un8[ino_offset] > 0); refs = --irec->ino_un.ex_data->counted_nlinks.un8[ino_offset]; break; case sizeof(__uint16_t): ASSERT(irec->ino_un.ex_data->counted_nlinks.un16[ino_offset] > 0); refs = --irec->ino_un.ex_data->counted_nlinks.un16[ino_offset]; break; case sizeof(__uint32_t): ASSERT(irec->ino_un.ex_data->counted_nlinks.un32[ino_offset] > 0); refs = --irec->ino_un.ex_data->counted_nlinks.un32[ino_offset]; break; default: ASSERT(0); } if (refs == 0) irec->ino_un.ex_data->ino_reached &= ~IREC_MASK(ino_offset); } __uint32_t num_inode_references(struct ino_tree_node *irec, int ino_offset) { ASSERT(irec->ino_un.ex_data != NULL); switch (irec->nlink_size) { case sizeof(__uint8_t): return irec->ino_un.ex_data->counted_nlinks.un8[ino_offset]; case sizeof(__uint16_t): return irec->ino_un.ex_data->counted_nlinks.un16[ino_offset]; case sizeof(__uint32_t): return irec->ino_un.ex_data->counted_nlinks.un32[ino_offset]; default: ASSERT(0); } } void set_inode_disk_nlinks(struct ino_tree_node *irec, int ino_offset, __uint32_t nlinks) { switch (irec->nlink_size) { case sizeof(__uint8_t): if (nlinks < 0xff) { irec->disk_nlinks.un8[ino_offset] = nlinks; break; } nlink_grow_8_to_16(irec); /*FALLTHRU*/ case sizeof(__uint16_t): if (nlinks < 0xffff) { irec->disk_nlinks.un16[ino_offset] = nlinks; break; } nlink_grow_16_to_32(irec); /*FALLTHRU*/ case sizeof(__uint32_t): irec->disk_nlinks.un32[ino_offset] = nlinks; break; default: ASSERT(0); } } __uint32_t get_inode_disk_nlinks(struct ino_tree_node *irec, int ino_offset) { switch (irec->nlink_size) { case sizeof(__uint8_t): return irec->disk_nlinks.un8[ino_offset]; case sizeof(__uint16_t): return irec->disk_nlinks.un16[ino_offset]; case sizeof(__uint32_t): return irec->disk_nlinks.un32[ino_offset]; default: ASSERT(0); } } /* * Next is the uncertain inode list -- a sorted (in ascending order) * list of inode records sorted on the starting inode number. There * is one list per ag. */ /* * Common code for creating inode records for use by trees and lists. * called only from add_inodes and add_inodes_uncertain * * IMPORTANT: all inodes (inode records) start off as free and * unconfirmed. */ static struct ino_tree_node * alloc_ino_node( xfs_agino_t starting_ino) { struct ino_tree_node *irec; irec = malloc(sizeof(*irec)); if (!irec) do_error(_("inode map malloc failed\n")); irec->avl_node.avl_nextino = NULL; irec->avl_node.avl_forw = NULL; irec->avl_node.avl_back = NULL; irec->ino_startnum = starting_ino; irec->ino_confirmed = 0; irec->ino_isa_dir = 0; irec->ir_free = (xfs_inofree_t) - 1; irec->ino_un.ex_data = NULL; irec->nlink_size = sizeof(__uint8_t); irec->disk_nlinks.un8 = alloc_nlink_array(irec->nlink_size); return irec; } static void free_nlink_array(union ino_nlink nlinks, __uint8_t nlink_size) { switch (nlink_size) { case sizeof(__uint8_t): free(nlinks.un8); break; case sizeof(__uint16_t): free(nlinks.un16); break; case sizeof(__uint32_t): free(nlinks.un32); break; default: ASSERT(0); } } static void free_ino_tree_node( struct ino_tree_node *irec) { irec->avl_node.avl_nextino = NULL; irec->avl_node.avl_forw = NULL; irec->avl_node.avl_back = NULL; free_nlink_array(irec->disk_nlinks, irec->nlink_size); if (irec->ino_un.ex_data != NULL) { if (full_ino_ex_data) { free(irec->ino_un.ex_data->parents); free_nlink_array(irec->ino_un.ex_data->counted_nlinks, irec->nlink_size); } free(irec->ino_un.ex_data); } free(irec); } /* * last referenced cache for uncertain inodes */ static ino_tree_node_t **last_rec; /* * ok, the uncertain inodes are a set of trees just like the * good inodes but all starting inode records are (arbitrarily) * aligned on XFS_CHUNK_PER_INODE boundaries to prevent overlaps. * this means we may have partials records in the tree (e.g. records * without 64 confirmed uncertain inodes). Tough. * * free is set to 1 if the inode is thought to be free, 0 if used */ void add_aginode_uncertain(xfs_agnumber_t agno, xfs_agino_t ino, int free) { ino_tree_node_t *ino_rec; xfs_agino_t s_ino; int offset; ASSERT(agno < glob_agcount); ASSERT(last_rec != NULL); s_ino = rounddown(ino, XFS_INODES_PER_CHUNK); /* * check for a cache hit */ if (last_rec[agno] != NULL && last_rec[agno]->ino_startnum == s_ino) { offset = ino - s_ino; if (free) set_inode_free(last_rec[agno], offset); else set_inode_used(last_rec[agno], offset); return; } /* * check to see if record containing inode is already in the tree. * if not, add it */ ino_rec = (ino_tree_node_t *) avl_findrange(inode_uncertain_tree_ptrs[agno], s_ino); if (!ino_rec) { ino_rec = alloc_ino_node(s_ino); if (!avl_insert(inode_uncertain_tree_ptrs[agno], &ino_rec->avl_node)) do_error( _("add_aginode_uncertain - duplicate inode range\n")); } if (free) set_inode_free(ino_rec, ino - s_ino); else set_inode_used(ino_rec, ino - s_ino); /* * set cache entry */ last_rec[agno] = ino_rec; } /* * like add_aginode_uncertain() only it needs an xfs_mount_t * * to perform the inode number conversion. */ void add_inode_uncertain(xfs_mount_t *mp, xfs_ino_t ino, int free) { add_aginode_uncertain(XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGINO(mp, ino), free); } /* * pull the indicated inode record out of the uncertain inode tree */ void get_uncertain_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, ino_tree_node_t *ino_rec) { ASSERT(inode_tree_ptrs != NULL); ASSERT(agno < mp->m_sb.sb_agcount); ASSERT(inode_tree_ptrs[agno] != NULL); avl_delete(inode_uncertain_tree_ptrs[agno], &ino_rec->avl_node); ino_rec->avl_node.avl_nextino = NULL; ino_rec->avl_node.avl_forw = NULL; ino_rec->avl_node.avl_back = NULL; } ino_tree_node_t * findfirst_uncertain_inode_rec(xfs_agnumber_t agno) { return((ino_tree_node_t *) inode_uncertain_tree_ptrs[agno]->avl_firstino); } ino_tree_node_t * find_uncertain_inode_rec(xfs_agnumber_t agno, xfs_agino_t ino) { return((ino_tree_node_t *) avl_findrange(inode_uncertain_tree_ptrs[agno], ino)); } void clear_uncertain_ino_cache(xfs_agnumber_t agno) { last_rec[agno] = NULL; } /* * Next comes the inode trees. One per AG, AVL trees of inode records, each * inode record tracking 64 inodes */ /* * Set up an inode tree record for a group of inodes that will include the * requested inode. * * This does NOT do error-check for duplicate records. The caller is * responsible for checking that. Ino must be the start of an * XFS_INODES_PER_CHUNK (64) inode chunk * * Each inode resides in a 64-inode chunk which can be part one or more chunks * (MAX(64, inodes-per-block). The fs allocates in chunks (as opposed to 1 * chunk) when a block can hold more than one chunk (inodes per block > 64). * Allocating in one chunk pieces causes us problems when it takes more than * one fs block to contain an inode chunk because the chunks can start on * *any* block boundary. So we assume that the caller has a clue because at * this level, we don't. */ static struct ino_tree_node * add_inode( struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t agino) { struct ino_tree_node *irec; irec = alloc_ino_node(agino); if (!avl_insert(inode_tree_ptrs[agno], &irec->avl_node)) do_warn(_("add_inode - duplicate inode range\n")); return irec; } /* * pull the indicated inode record out of the inode tree */ void get_inode_rec(struct xfs_mount *mp, xfs_agnumber_t agno, ino_tree_node_t *ino_rec) { ASSERT(inode_tree_ptrs != NULL); ASSERT(agno < mp->m_sb.sb_agcount); ASSERT(inode_tree_ptrs[agno] != NULL); avl_delete(inode_tree_ptrs[agno], &ino_rec->avl_node); ino_rec->avl_node.avl_nextino = NULL; ino_rec->avl_node.avl_forw = NULL; ino_rec->avl_node.avl_back = NULL; } /* * free the designated inode record (return it to the free pool) */ /* ARGSUSED */ void free_inode_rec(xfs_agnumber_t agno, ino_tree_node_t *ino_rec) { free_ino_tree_node(ino_rec); } void find_inode_rec_range(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t start_ino, xfs_agino_t end_ino, ino_tree_node_t **first, ino_tree_node_t **last) { *first = *last = NULL; /* * Is the AG inside the file system ? */ if (agno < mp->m_sb.sb_agcount) avl_findranges(inode_tree_ptrs[agno], start_ino, end_ino, (avlnode_t **) first, (avlnode_t **) last); } /* * if ino doesn't exist, it must be properly aligned -- on a * filesystem block boundary or XFS_INODES_PER_CHUNK boundary, * whichever alignment is larger. */ ino_tree_node_t * set_inode_used_alloc(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t ino) { ino_tree_node_t *ino_rec; /* * check alignment -- the only way to detect this * is too see if the chunk overlaps another chunk * already in the tree */ ino_rec = add_inode(mp, agno, ino); ASSERT(ino_rec != NULL); ASSERT(ino >= ino_rec->ino_startnum && ino - ino_rec->ino_startnum < XFS_INODES_PER_CHUNK); set_inode_used(ino_rec, ino - ino_rec->ino_startnum); return(ino_rec); } ino_tree_node_t * set_inode_free_alloc(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t ino) { ino_tree_node_t *ino_rec; ino_rec = add_inode(mp, agno, ino); ASSERT(ino_rec != NULL); ASSERT(ino >= ino_rec->ino_startnum && ino - ino_rec->ino_startnum < XFS_INODES_PER_CHUNK); set_inode_free(ino_rec, ino - ino_rec->ino_startnum); return(ino_rec); } void print_inode_list_int(xfs_agnumber_t agno, int uncertain) { ino_tree_node_t *ino_rec; if (!uncertain) { fprintf(stderr, _("good inode list is --\n")); ino_rec = findfirst_inode_rec(agno); } else { fprintf(stderr, _("uncertain inode list is --\n")); ino_rec = findfirst_uncertain_inode_rec(agno); } if (ino_rec == NULL) { fprintf(stderr, _("agno %d -- no inodes\n"), agno); return; } printf(_("agno %d\n"), agno); while(ino_rec != NULL) { fprintf(stderr, _("\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n"), (unsigned long)ino_rec, ino_rec->ino_startnum, (unsigned long long)ino_rec->ir_free, (unsigned long long)ino_rec->ino_confirmed); if (ino_rec->ino_startnum == 0) ino_rec = ino_rec; ino_rec = next_ino_rec(ino_rec); } } void print_inode_list(xfs_agnumber_t agno) { print_inode_list_int(agno, 0); } void print_uncertain_inode_list(xfs_agnumber_t agno) { print_inode_list_int(agno, 1); } /* * set parent -- use a bitmask and a packed array. The bitmask * indicate which inodes have an entry in the array. An inode that * is the Nth bit set in the mask is stored in the Nth location in * the array where N starts at 0. */ void set_inode_parent( ino_tree_node_t *irec, int offset, xfs_ino_t parent) { parent_list_t *ptbl; int i; int cnt; int target; __uint64_t bitmask; parent_entry_t *tmp; if (full_ino_ex_data) ptbl = irec->ino_un.ex_data->parents; else ptbl = irec->ino_un.plist; if (ptbl == NULL) { ptbl = (parent_list_t *)malloc(sizeof(parent_list_t)); if (!ptbl) do_error(_("couldn't malloc parent list table\n")); if (full_ino_ex_data) irec->ino_un.ex_data->parents = ptbl; else irec->ino_un.plist = ptbl; ptbl->pmask = 1LL << offset; ptbl->pentries = (xfs_ino_t*)memalign(sizeof(xfs_ino_t), sizeof(xfs_ino_t)); if (!ptbl->pentries) do_error(_("couldn't memalign pentries table\n")); #ifdef DEBUG ptbl->cnt = 1; #endif ptbl->pentries[0] = parent; return; } if (ptbl->pmask & (1LL << offset)) { bitmask = 1LL; target = 0; for (i = 0; i < offset; i++) { if (ptbl->pmask & bitmask) target++; bitmask <<= 1; } #ifdef DEBUG ASSERT(target < ptbl->cnt); #endif ptbl->pentries[target] = parent; return; } bitmask = 1LL; cnt = target = 0; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (ptbl->pmask & bitmask) { cnt++; if (i < offset) target++; } bitmask <<= 1; } #ifdef DEBUG ASSERT(cnt == ptbl->cnt); #endif ASSERT(cnt >= target); tmp = (xfs_ino_t*)memalign(sizeof(xfs_ino_t), (cnt + 1) * sizeof(xfs_ino_t)); if (!tmp) do_error(_("couldn't memalign pentries table\n")); memmove(tmp, ptbl->pentries, target * sizeof(parent_entry_t)); if (cnt > target) memmove(tmp + target + 1, ptbl->pentries + target, (cnt - target) * sizeof(parent_entry_t)); free(ptbl->pentries); ptbl->pentries = tmp; #ifdef DEBUG ptbl->cnt++; #endif ptbl->pentries[target] = parent; ptbl->pmask |= (1LL << offset); } xfs_ino_t get_inode_parent(ino_tree_node_t *irec, int offset) { __uint64_t bitmask; parent_list_t *ptbl; int i; int target; if (full_ino_ex_data) ptbl = irec->ino_un.ex_data->parents; else ptbl = irec->ino_un.plist; if (ptbl->pmask & (1LL << offset)) { bitmask = 1LL; target = 0; for (i = 0; i < offset; i++) { if (ptbl->pmask & bitmask) target++; bitmask <<= 1; } #ifdef DEBUG ASSERT(target < ptbl->cnt); #endif return(ptbl->pentries[target]); } return(0LL); } static void alloc_ex_data(ino_tree_node_t *irec) { parent_list_t *ptbl; ptbl = irec->ino_un.plist; irec->ino_un.ex_data = (ino_ex_data_t *)calloc(1, sizeof(ino_ex_data_t)); if (irec->ino_un.ex_data == NULL) do_error(_("could not malloc inode extra data\n")); irec->ino_un.ex_data->parents = ptbl; switch (irec->nlink_size) { case sizeof(__uint8_t): irec->ino_un.ex_data->counted_nlinks.un8 = alloc_nlink_array(irec->nlink_size); break; case sizeof(__uint16_t): irec->ino_un.ex_data->counted_nlinks.un16 = alloc_nlink_array(irec->nlink_size); break; case sizeof(__uint32_t): irec->ino_un.ex_data->counted_nlinks.un32 = alloc_nlink_array(irec->nlink_size); break; default: ASSERT(0); } } void add_ino_ex_data(xfs_mount_t *mp) { ino_tree_node_t *ino_rec; xfs_agnumber_t i; for (i = 0; i < mp->m_sb.sb_agcount; i++) { ino_rec = findfirst_inode_rec(i); while (ino_rec != NULL) { alloc_ex_data(ino_rec); ino_rec = next_ino_rec(ino_rec); } } full_ino_ex_data = 1; } static __psunsigned_t avl_ino_start(avlnode_t *node) { return((__psunsigned_t) ((ino_tree_node_t *) node)->ino_startnum); } static __psunsigned_t avl_ino_end(avlnode_t *node) { return((__psunsigned_t) ( ((ino_tree_node_t *) node)->ino_startnum + XFS_INODES_PER_CHUNK)); } avlops_t avl_ino_tree_ops = { avl_ino_start, avl_ino_end }; void incore_ino_init(xfs_mount_t *mp) { int i; int agcount = mp->m_sb.sb_agcount; if ((inode_tree_ptrs = malloc(agcount * sizeof(avltree_desc_t *))) == NULL) do_error(_("couldn't malloc inode tree descriptor table\n")); if ((inode_uncertain_tree_ptrs = malloc(agcount * sizeof(avltree_desc_t *))) == NULL) do_error( _("couldn't malloc uncertain ino tree descriptor table\n")); for (i = 0; i < agcount; i++) { if ((inode_tree_ptrs[i] = malloc(sizeof(avltree_desc_t))) == NULL) do_error(_("couldn't malloc inode tree descriptor\n")); if ((inode_uncertain_tree_ptrs[i] = malloc(sizeof(avltree_desc_t))) == NULL) do_error( _("couldn't malloc uncertain ino tree descriptor\n")); } for (i = 0; i < agcount; i++) { avl_init_tree(inode_tree_ptrs[i], &avl_ino_tree_ops); avl_init_tree(inode_uncertain_tree_ptrs[i], &avl_ino_tree_ops); } if ((last_rec = malloc(sizeof(ino_tree_node_t *) * agcount)) == NULL) do_error(_("couldn't malloc uncertain inode cache area\n")); memset(last_rec, 0, sizeof(ino_tree_node_t *) * agcount); full_ino_ex_data = 0; } xfsprogs-3.1.9ubuntu2/repair/globals.c0000664000000000000000000000142111140033220014645 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #define EXTERN #include "globals.h" xfsprogs-3.1.9ubuntu2/repair/scan.c0000664000000000000000000010445712062210562014175 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "scan.h" #include "versions.h" #include "bmap.h" #include "progress.h" #include "threads.h" static xfs_mount_t *mp = NULL; /* * Variables to validate AG header values against the manual count * from the btree traversal. */ struct aghdr_cnts { xfs_agnumber_t agno; xfs_extlen_t agffreeblks; xfs_extlen_t agflongest; __uint64_t agfbtreeblks; __uint32_t agicount; __uint32_t agifreecount; __uint64_t fdblocks; __uint64_t icount; __uint64_t ifreecount; }; static void scanfunc_allocbt( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, __uint32_t magic, struct aghdr_cnts *agcnts); void set_mp(xfs_mount_t *mpp) { libxfs_bcache_purge(); mp = mpp; } static void scan_sbtree( xfs_agblock_t root, int nlevels, xfs_agnumber_t agno, int suspect, void (*func)(struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, void *priv), int isroot, void *priv) { xfs_buf_t *bp; bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, root), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_error(_("can't read btree block %d/%d\n"), agno, root); return; } (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, root, agno, suspect, isroot, priv); libxfs_putbuf(bp); } /* * returns 1 on bad news (inode needs to be cleared), 0 on good */ int scan_lbtree( xfs_dfsbno_t root, int nlevels, int (*func)(struct xfs_btree_block *block, int level, int type, int whichfork, xfs_dfsbno_t bno, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups, int *dirty), int type, int whichfork, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups) { xfs_buf_t *bp; int err; int dirty = 0; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, root), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_error(_("can't read btree block %d/%d\n"), XFS_FSB_TO_AGNO(mp, root), XFS_FSB_TO_AGBNO(mp, root)); return(1); } err = (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, type, whichfork, root, ino, tot, nex, blkmapp, bm_cursor, isroot, check_dups, &dirty); ASSERT(dirty == 0 || (dirty && !no_modify)); if (dirty && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); return(err); } int scanfunc_bmap( struct xfs_btree_block *block, int level, int type, int whichfork, xfs_dfsbno_t bno, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups, int *dirty) { int i; int err; xfs_bmbt_ptr_t *pp; xfs_bmbt_key_t *pkey; xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; char *forkname; int numrecs; xfs_agnumber_t agno; xfs_agblock_t agbno; int state; if (whichfork == XFS_DATA_FORK) forkname = _("data"); else forkname = _("attr"); /* * unlike the ag freeblock btrees, if anything looks wrong * in an inode bmap tree, just bail. it's possible that * we'll miss a case where the to-be-toasted inode and * another inode are claiming the same block but that's * highly unlikely. */ if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { do_warn( _("bad magic # %#x in inode %" PRIu64 " (%s fork) bmbt block %" PRIu64 "\n"), be32_to_cpu(block->bb_magic), ino, forkname, bno); return(1); } if (be16_to_cpu(block->bb_level) != level) { do_warn( _("expected level %d got %d in inode %" PRIu64 ", (%s fork) bmbt block %" PRIu64 "\n"), level, be16_to_cpu(block->bb_level), ino, forkname, bno); return(1); } if (check_dups == 0) { /* * check sibling pointers. if bad we have a conflict * between the sibling pointers and the child pointers * in the parent block. blow out the inode if that happens */ if (bm_cursor->level[level].fsbno != NULLDFSBNO) { /* * this is not the first block on this level * so the cursor for this level has recorded the * values for this's block left-sibling. */ if (bno != bm_cursor->level[level].right_fsbno) { do_warn( _("bad fwd (right) sibling pointer (saw %" PRIu64 " parent block says %" PRIu64 ")\n" "\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"), bm_cursor->level[level].right_fsbno, bno, ino, forkname, bm_cursor->level[level].fsbno); return(1); } if (be64_to_cpu(block->bb_u.l.bb_leftsib) != bm_cursor->level[level].fsbno) { do_warn( _("bad back (left) sibling pointer (saw %llu parent block says %" PRIu64 ")\n" "\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(block->bb_u.l.bb_leftsib), bm_cursor->level[level].fsbno, ino, forkname, bno); return(1); } } else { /* * This is the first or only block on this level. * Check that the left sibling pointer is NULL */ if (be64_to_cpu(block->bb_u.l.bb_leftsib) != NULLDFSBNO) { do_warn( _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" "\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(block->bb_u.l.bb_leftsib), ino, forkname, bno); return(1); } } /* * update cursor block pointers to reflect this block */ bm_cursor->level[level].fsbno = bno; bm_cursor->level[level].left_fsbno = be64_to_cpu(block->bb_u.l.bb_leftsib); bm_cursor->level[level].right_fsbno = be64_to_cpu(block->bb_u.l.bb_rightsib); agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); pthread_mutex_lock(&ag_locks[agno]); state = get_bmap(agno, agbno); switch (state) { case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: set_bmap(agno, agbno, XR_E_INUSE); break; case XR_E_FS_MAP: case XR_E_INUSE: /* * we'll try and continue searching here since * the block looks like it's been claimed by file * to store user data, a directory to store directory * data, or the space allocation btrees but since * we made it here, the block probably * contains btree data. */ set_bmap(agno, agbno, XR_E_MULT); do_warn( _("inode 0x%" PRIx64 "bmap block 0x%" PRIx64 " claimed, state is %d\n"), ino, bno, state); break; case XR_E_MULT: case XR_E_INUSE_FS: set_bmap(agno, agbno, XR_E_MULT); do_warn( _("inode 0x%" PRIx64 " bmap block 0x%" PRIx64 " claimed, state is %d\n"), ino, bno, state); /* * if we made it to here, this is probably a bmap block * that is being used by *another* file as a bmap block * so the block will be valid. Both files should be * trashed along with any other file that impinges on * any blocks referenced by either file. So we * continue searching down this btree to mark all * blocks duplicate */ break; case XR_E_BAD_STATE: default: do_warn( _("bad state %d, inode %" PRIu64 " bmap block 0x%" PRIx64 "\n"), state, ino, bno); break; } pthread_mutex_unlock(&ag_locks[agno]); } else { /* * attribute fork for realtime files is in the regular * filesystem */ if (type != XR_INO_RTDATA || whichfork != XFS_DATA_FORK) { if (search_dup_extent(XFS_FSB_TO_AGNO(mp, bno), XFS_FSB_TO_AGBNO(mp, bno), XFS_FSB_TO_AGBNO(mp, bno) + 1)) return(1); } else { if (search_rt_dup_extent(mp, bno)) return(1); } } (*tot)++; numrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs < mp->m_bmap_dmnr[0])) { do_warn( _("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"), ino, numrecs, mp->m_bmap_dmnr[0], mp->m_bmap_dmxr[0]); return(1); } rp = XFS_BMBT_REC_ADDR(mp, block, 1); *nex += numrecs; /* * XXX - if we were going to fix up the btree record, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. */ if (check_dups == 0) { err = process_bmbt_reclist(mp, rp, &numrecs, type, ino, tot, blkmapp, &first_key, &last_key, whichfork); if (err) return 1; /* * check that key ordering is monotonically increasing. * if the last_key value in the cursor is set to * NULLDFILOFF, then we know this is the first block * on the leaf level and we shouldn't check the * last_key value. */ if (first_key <= bm_cursor->level[level].last_key && bm_cursor->level[level].last_key != NULLDFILOFF) { do_warn( _("out-of-order bmap key (file offset) in inode %" PRIu64 ", %s fork, fsbno %" PRIu64 "\n"), ino, forkname, bno); return(1); } /* * update cursor keys to reflect this block. * don't have to check if last_key is > first_key * since that gets checked by process_bmbt_reclist. */ bm_cursor->level[level].first_key = first_key; bm_cursor->level[level].last_key = last_key; return 0; } else { return scan_bmbt_reclist(mp, rp, &numrecs, type, ino, tot, whichfork); } } if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs < mp->m_bmap_dmnr[1])) { do_warn( _("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"), ino, numrecs, mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]); return(1); } pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); pkey = XFS_BMBT_KEY_ADDR(mp, block, 1); last_key = NULLDFILOFF; for (i = 0, err = 0; i < numrecs; i++) { /* * XXX - if we were going to fix up the interior btree nodes, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. */ if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { do_warn( _("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(pp[i]), ino); return(1); } err = scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, whichfork, ino, tot, nex, blkmapp, bm_cursor, 0, check_dups); if (err) return(1); /* * fix key (offset) mismatches between the first key * in the child block (as recorded in the cursor) and the * key in the interior node referencing the child block. * * fixes cases where entries have been shifted between * child blocks but the parent hasn't been updated. We * don't have to worry about the key values in the cursor * not being set since we only look at the key values of * our child and those are guaranteed to be set by the * call to scan_lbtree() above. */ if (check_dups == 0 && be64_to_cpu(pkey[i].br_startoff) != bm_cursor->level[level-1].first_key) { if (!no_modify) { do_warn( _("correcting bt key (was %llu, now %" PRIu64 ") in inode %" PRIu64 "\n" "\t\t%s fork, btree block %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(pkey[i].br_startoff), bm_cursor->level[level-1].first_key, ino, forkname, bno); *dirty = 1; pkey[i].br_startoff = cpu_to_be64( bm_cursor->level[level-1].first_key); } else { do_warn( _("bad btree key (is %llu, should be %" PRIu64 ") in inode %" PRIu64 "\n" "\t\t%s fork, btree block %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(pkey[i].br_startoff), bm_cursor->level[level-1].first_key, ino, forkname, bno); } } } /* * If we're the last node at our level, check that the last child * block's forward sibling pointer is NULL. */ if (check_dups == 0 && bm_cursor->level[level].right_fsbno == NULLDFSBNO && bm_cursor->level[level - 1].right_fsbno != NULLDFSBNO) { do_warn( _("bad fwd (right) sibling pointer (saw %" PRIu64 " should be NULLDFSBNO)\n" "\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"), bm_cursor->level[level - 1].right_fsbno, ino, forkname, bm_cursor->level[level - 1].fsbno); return(1); } /* * update cursor keys to reflect this block */ if (check_dups == 0) { bm_cursor->level[level].first_key = be64_to_cpu(pkey[0].br_startoff); bm_cursor->level[level].last_key = be64_to_cpu(pkey[numrecs - 1].br_startoff); } return(0); } static void scanfunc_bno( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, void *agcnts) { return scanfunc_allocbt(block, level, bno, agno, suspect, isroot, XFS_ABTB_MAGIC, agcnts); } static void scanfunc_cnt( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, void *agcnts) { return scanfunc_allocbt(block, level, bno, agno, suspect, isroot, XFS_ABTC_MAGIC, agcnts); } static void scanfunc_allocbt( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, __uint32_t magic, struct aghdr_cnts *agcnts) { const char *name; int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; int hdr_errors = 0; int numrecs; int state; xfs_extlen_t lastcount = 0; xfs_agblock_t lastblock = 0; assert(magic == XFS_ABTB_MAGIC || magic == XFS_ABTC_MAGIC); name = (magic == XFS_ABTB_MAGIC) ? "bno" : "cnt"; if (be32_to_cpu(block->bb_magic) != magic) { do_warn(_("bad magic # %#x in bt%s block %d/%d\n"), be32_to_cpu(block->bb_magic), name, agno, bno); hdr_errors++; if (suspect) return; } /* * All freespace btree blocks except the roots are freed for a * fully used filesystem, thus they are counted towards the * free data block counter. */ if (!isroot) { agcnts->agfbtreeblks++; agcnts->fdblocks++; } if (be16_to_cpu(block->bb_level) != level) { do_warn(_("expected level %d got %d in bt%s block %d/%d\n"), level, be16_to_cpu(block->bb_level), name, agno, bno); hdr_errors++; if (suspect) return; } /* * check for btree blocks multiply claimed */ state = get_bmap(agno, bno); if (state != XR_E_UNKNOWN) { set_bmap(agno, bno, XR_E_MULT); do_warn( _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), name, state, agno, bno, suspect); return; } set_bmap(agno, bno, XR_E_FS_MAP); numrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (numrecs > mp->m_alloc_mxr[0]) { numrecs = mp->m_alloc_mxr[0]; hdr_errors++; } if (isroot == 0 && numrecs < mp->m_alloc_mnr[0]) { numrecs = mp->m_alloc_mnr[0]; hdr_errors++; } if (hdr_errors) { do_warn( _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[0], mp->m_alloc_mxr[0], name, agno, bno); suspect++; } rp = XFS_ALLOC_REC_ADDR(mp, block, 1); for (i = 0; i < numrecs; i++) { xfs_agblock_t b, end; xfs_extlen_t len, blen; b = be32_to_cpu(rp[i].ar_startblock); len = be32_to_cpu(rp[i].ar_blockcount); end = b + len; if (b == 0 || !verify_agbno(mp, agno, b)) { do_warn( _("invalid start block %u in record %u of %s btree block %u/%u\n"), b, i, name, agno, bno); continue; } if (len == 0 || !verify_agbno(mp, agno, end - 1)) { do_warn( _("invalid length %u in record %u of %s btree block %u/%u\n"), len, i, name, agno, bno); continue; } if (magic == XFS_ABTB_MAGIC) { if (b <= lastblock) { do_warn(_( "out-of-order bno btree record %d (%u %u) block %u/%u\n"), i, b, len, agno, bno); } else { lastblock = b; } } else { agcnts->fdblocks += len; agcnts->agffreeblks += len; if (len > agcnts->agflongest) agcnts->agflongest = len; if (len < lastcount) { do_warn(_( "out-of-order cnt btree record %d (%u %u) block %u/%u\n"), i, b, len, agno, bno); } else { lastcount = len; } } for ( ; b < end; b += blen) { state = get_bmap_ext(agno, b, end, &blen); switch (state) { case XR_E_UNKNOWN: set_bmap(agno, b, XR_E_FREE1); break; case XR_E_FREE1: /* * no warning messages -- we'll catch * FREE1 blocks later */ if (magic == XFS_ABTC_MAGIC) { set_bmap_ext(agno, b, blen, XR_E_FREE); break; } default: do_warn( _("block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n"), agno, b, b + blen - 1, name, state); break; } } } return; } /* * interior record */ pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); if (numrecs > mp->m_alloc_mxr[1]) { numrecs = mp->m_alloc_mxr[1]; hdr_errors++; } if (isroot == 0 && numrecs < mp->m_alloc_mnr[1]) { numrecs = mp->m_alloc_mnr[1]; hdr_errors++; } /* * don't pass bogus tree flag down further if this block * looked ok. bail out if two levels in a row look bad. */ if (hdr_errors) { do_warn( _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[1], mp->m_alloc_mxr[1], name, agno, bno); if (suspect) return; suspect++; } else if (suspect) { suspect = 0; } for (i = 0; i < numrecs; i++) { xfs_agblock_t bno = be32_to_cpu(pp[i]); /* * XXX - put sibling detection right here. * we know our sibling chain is good. So as we go, * we check the entry before and after each entry. * If either of the entries references a different block, * check the sibling pointer. If there's a sibling * pointer mismatch, try and extract as much data * as possible. */ if (bno != 0 && verify_agbno(mp, agno, bno)) { scan_sbtree(bno, level, agno, suspect, (magic == XFS_ABTB_MAGIC) ? scanfunc_bno : scanfunc_cnt, 0, (void *)agcnts); } } } static int scan_single_ino_chunk( xfs_agnumber_t agno, xfs_inobt_rec_t *rp, int suspect) { xfs_ino_t lino; xfs_agino_t ino; xfs_agblock_t agbno; int j; int nfree; int off; int state; ino_tree_node_t *ino_rec, *first_rec, *last_rec; ino = be32_to_cpu(rp->ir_startino); off = XFS_AGINO_TO_OFFSET(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, ino); lino = XFS_AGINO_TO_INO(mp, agno, ino); /* * on multi-block block chunks, all chunks start * at the beginning of the block. with multi-chunk * blocks, all chunks must start on 64-inode boundaries * since each block can hold N complete chunks. if * fs has aligned inodes, all chunks must start * at a fs_ino_alignment*N'th agbno. skip recs * with badly aligned starting inodes. */ if (ino == 0 || (inodes_per_block <= XFS_INODES_PER_CHUNK && off != 0) || (inodes_per_block > XFS_INODES_PER_CHUNK && off % XFS_INODES_PER_CHUNK != 0) || (fs_aligned_inodes && agbno % fs_ino_alignment != 0)) { do_warn( _("badly aligned inode rec (starting inode = %" PRIu64 ")\n"), lino); suspect++; } /* * verify numeric validity of inode chunk first * before inserting into a tree. don't have to * worry about the overflow case because the * starting ino number of a chunk can only get * within 255 inodes of max (NULLAGINO). if it * gets closer, the agino number will be illegal * as the agbno will be too large. */ if (verify_aginum(mp, agno, ino)) { do_warn( _("bad starting inode # (%" PRIu64 " (0x%x 0x%x)) in ino rec, skipping rec\n"), lino, agno, ino); return ++suspect; } if (verify_aginum(mp, agno, ino + XFS_INODES_PER_CHUNK - 1)) { do_warn( _("bad ending inode # (%" PRIu64 " (0x%x 0x%zx)) in ino rec, skipping rec\n"), lino + XFS_INODES_PER_CHUNK - 1, agno, ino + XFS_INODES_PER_CHUNK - 1); return ++suspect; } /* * set state of each block containing inodes */ if (off == 0 && !suspect) { for (j = 0; j < XFS_INODES_PER_CHUNK; j += mp->m_sb.sb_inopblock) { agbno = XFS_AGINO_TO_AGBNO(mp, ino + j); state = get_bmap(agno, agbno); if (state == XR_E_UNKNOWN) { set_bmap(agno, agbno, XR_E_INO); } else if (state == XR_E_INUSE_FS && agno == 0 && ino + j >= first_prealloc_ino && ino + j < last_prealloc_ino) { set_bmap(agno, agbno, XR_E_INO); } else { do_warn( _("inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n"), agno, agbno, mp->m_sb.sb_inopblock); /* * XXX - maybe should mark * block a duplicate */ return ++suspect; } } } /* * ensure only one avl entry per chunk */ find_inode_rec_range(mp, agno, ino, ino + XFS_INODES_PER_CHUNK, &first_rec, &last_rec); if (first_rec != NULL) { /* * this chunk overlaps with one (or more) * already in the tree */ do_warn( _("inode rec for ino %" PRIu64 " (%d/%d) overlaps existing rec (start %d/%d)\n"), lino, agno, ino, agno, first_rec->ino_startnum); suspect++; /* * if the 2 chunks start at the same place, * then we don't have to put this one * in the uncertain list. go to the next one. */ if (first_rec->ino_startnum == ino) return suspect; } nfree = 0; /* * now mark all the inodes as existing and free or used. * if the tree is suspect, put them into the uncertain * inode tree. */ if (!suspect) { if (XFS_INOBT_IS_FREE_DISK(rp, 0)) { nfree++; ino_rec = set_inode_free_alloc(mp, agno, ino); } else { ino_rec = set_inode_used_alloc(mp, agno, ino); } for (j = 1; j < XFS_INODES_PER_CHUNK; j++) { if (XFS_INOBT_IS_FREE_DISK(rp, j)) { nfree++; set_inode_free(ino_rec, j); } else { set_inode_used(ino_rec, j); } } } else { for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { if (XFS_INOBT_IS_FREE_DISK(rp, j)) { nfree++; add_aginode_uncertain(agno, ino + j, 1); } else { add_aginode_uncertain(agno, ino + j, 0); } } } if (nfree != be32_to_cpu(rp->ir_freecount)) { do_warn(_("ir_freecount/free mismatch, inode " "chunk %d/%u, freecount %d nfree %d\n"), agno, ino, be32_to_cpu(rp->ir_freecount), nfree); } return suspect; } /* * this one walks the inode btrees sucking the info there into * the incore avl tree. We try and rescue corrupted btree records * to minimize our chances of losing inodes. Inode info from potentially * corrupt sources could be bogus so rather than put the info straight * into the tree, instead we put it on a list and try and verify the * info in the next phase by examining what's on disk. At that point, * we'll be able to figure out what's what and stick the corrected info * into the tree. We do bail out at some point and give up on a subtree * so as to avoid walking randomly all over the ag. * * Note that it's also ok if the free/inuse info wrong, we can correct * that when we examine the on-disk inode. The important thing is to * get the start and alignment of the inode chunks right. Those chunks * that we aren't sure about go into the uncertain list. */ static void scanfunc_ino( struct xfs_btree_block *block, int level, xfs_agblock_t bno, xfs_agnumber_t agno, int suspect, int isroot, void *priv) { struct aghdr_cnts *agcnts = priv; int i; int numrecs; int state; xfs_inobt_ptr_t *pp; xfs_inobt_rec_t *rp; int hdr_errors; hdr_errors = 0; if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { do_warn(_("bad magic # %#x in inobt block %d/%d\n"), be32_to_cpu(block->bb_magic), agno, bno); hdr_errors++; bad_ino_btree = 1; if (suspect) return; } if (be16_to_cpu(block->bb_level) != level) { do_warn(_("expected level %d got %d in inobt block %d/%d\n"), level, be16_to_cpu(block->bb_level), agno, bno); hdr_errors++; bad_ino_btree = 1; if (suspect) return; } /* * check for btree blocks multiply claimed, any unknown/free state * is ok in the bitmap block. */ state = get_bmap(agno, bno); switch (state) { case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: set_bmap(agno, bno, XR_E_FS_MAP); break; default: set_bmap(agno, bno, XR_E_MULT); do_warn( _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), state, agno, bno, suspect); } numrecs = be16_to_cpu(block->bb_numrecs); /* * leaf record in btree */ if (level == 0) { /* check for trashed btree block */ if (numrecs > mp->m_inobt_mxr[0]) { numrecs = mp->m_inobt_mxr[0]; hdr_errors++; } if (isroot == 0 && numrecs < mp->m_inobt_mnr[0]) { numrecs = mp->m_inobt_mnr[0]; hdr_errors++; } if (hdr_errors) { bad_ino_btree = 1; do_warn(_("dubious inode btree block header %d/%d\n"), agno, bno); suspect++; } rp = XFS_INOBT_REC_ADDR(mp, block, 1); /* * step through the records, each record points to * a chunk of inodes. The start of inode chunks should * be block-aligned. Each inode btree rec should point * to the start of a block of inodes or the start of a group * of INODES_PER_CHUNK (64) inodes. off is the offset into * the block. skip processing of bogus records. */ for (i = 0; i < numrecs; i++) { agcnts->agicount += XFS_INODES_PER_CHUNK; agcnts->icount += XFS_INODES_PER_CHUNK; agcnts->agifreecount += be32_to_cpu(rp[i].ir_freecount); agcnts->ifreecount += be32_to_cpu(rp[i].ir_freecount); suspect = scan_single_ino_chunk(agno, &rp[i], suspect); } if (suspect) bad_ino_btree = 1; return; } /* * interior record, continue on */ if (numrecs > mp->m_inobt_mxr[1]) { numrecs = mp->m_inobt_mxr[1]; hdr_errors++; } if (isroot == 0 && numrecs < mp->m_inobt_mnr[1]) { numrecs = mp->m_inobt_mnr[1]; hdr_errors++; } pp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]); /* * don't pass bogus tree flag down further if this block * looked ok. bail out if two levels in a row look bad. */ if (suspect && !hdr_errors) suspect = 0; if (hdr_errors) { bad_ino_btree = 1; if (suspect) return; else suspect++; } for (i = 0; i < numrecs; i++) { if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, be32_to_cpu(pp[i]))) scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect, scanfunc_ino, 0, priv); } } static void scan_freelist( xfs_agf_t *agf, struct aghdr_cnts *agcnts) { xfs_agfl_t *agfl; xfs_buf_t *agflbuf; xfs_agnumber_t agno; xfs_agblock_t bno; int count; int i; agno = be32_to_cpu(agf->agf_seqno); if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) set_bmap(agno, XFS_AGFL_BLOCK(mp), XR_E_FS_MAP); if (be32_to_cpu(agf->agf_flcount) == 0) return; agflbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0); if (!agflbuf) { do_abort(_("can't read agfl block for ag %d\n"), agno); return; } agfl = XFS_BUF_TO_AGFL(agflbuf); i = be32_to_cpu(agf->agf_flfirst); count = 0; for (;;) { bno = be32_to_cpu(agfl->agfl_bno[i]); if (verify_agbno(mp, agno, bno)) set_bmap(agno, bno, XR_E_FREE); else do_warn(_("bad agbno %u in agfl, agno %d\n"), bno, agno); count++; if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; } if (count != be32_to_cpu(agf->agf_flcount)) { do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count, be32_to_cpu(agf->agf_flcount), agno); } agcnts->fdblocks += count; libxfs_putbuf(agflbuf); } static void validate_agf( struct xfs_agf *agf, xfs_agnumber_t agno, struct aghdr_cnts *agcnts) { xfs_agblock_t bno; bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); if (bno != 0 && verify_agbno(mp, agno, bno)) { scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), agno, 0, scanfunc_bno, 1, agcnts); } else { do_warn(_("bad agbno %u for btbno root, agno %d\n"), bno, agno); } bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); if (bno != 0 && verify_agbno(mp, agno, bno)) { scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), agno, 0, scanfunc_cnt, 1, agcnts); } else { do_warn(_("bad agbno %u for btbcnt root, agno %d\n"), bno, agno); } if (be32_to_cpu(agf->agf_freeblks) != agcnts->agffreeblks) { do_warn(_("agf_freeblks %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_freeblks), agcnts->agffreeblks, agno); } if (be32_to_cpu(agf->agf_longest) != agcnts->agflongest) { do_warn(_("agf_longest %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_longest), agcnts->agflongest, agno); } if (xfs_sb_version_haslazysbcount(&mp->m_sb) && be32_to_cpu(agf->agf_btreeblks) != agcnts->agfbtreeblks) { do_warn(_("agf_btreeblks %u, counted %" PRIu64 " in ag %u\n"), be32_to_cpu(agf->agf_btreeblks), agcnts->agfbtreeblks, agno); } } static void validate_agi( struct xfs_agi *agi, xfs_agnumber_t agno, struct aghdr_cnts *agcnts) { xfs_agblock_t bno; int i; bno = be32_to_cpu(agi->agi_root); if (bno != 0 && verify_agbno(mp, agno, bno)) { scan_sbtree(bno, be32_to_cpu(agi->agi_level), agno, 0, scanfunc_ino, 1, agcnts); } else { do_warn(_("bad agbno %u for inobt root, agno %d\n"), be32_to_cpu(agi->agi_root), agno); } if (be32_to_cpu(agi->agi_count) != agcnts->agicount) { do_warn(_("agi_count %u, counted %u in ag %u\n"), be32_to_cpu(agi->agi_count), agcnts->agicount, agno); } if (be32_to_cpu(agi->agi_freecount) != agcnts->agifreecount) { do_warn(_("agi_freecount %u, counted %u in ag %u\n"), be32_to_cpu(agi->agi_freecount), agcnts->agifreecount, agno); } for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { xfs_agino_t agino = be32_to_cpu(agi->agi_unlinked[i]); if (agino != NULLAGINO) { do_warn( _("agi unlinked bucket %d is %u in ag %u (inode=%" PRIu64 ")\n"), i, agino, agno, XFS_AGINO_TO_INO(mp, agno, agino)); } } } /* * Scan an AG for obvious corruption. */ static void scan_ag( work_queue_t *wq, xfs_agnumber_t agno, void *arg) { struct aghdr_cnts *agcnts = arg; xfs_agf_t *agf; xfs_buf_t *agfbuf; int agf_dirty = 0; xfs_agi_t *agi; xfs_buf_t *agibuf; int agi_dirty = 0; xfs_sb_t *sb; xfs_buf_t *sbbuf; int sb_dirty = 0; int status; sbbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), 0); if (!sbbuf) { do_error(_("can't get root superblock for ag %d\n"), agno); return; } sb = (xfs_sb_t *)calloc(BBSIZE, 1); if (!sb) { do_error(_("can't allocate memory for superblock\n")); libxfs_putbuf(sbbuf); return; } libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbbuf)); agfbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0); if (!agfbuf) { do_error(_("can't read agf block for ag %d\n"), agno); libxfs_putbuf(sbbuf); free(sb); return; } agf = XFS_BUF_TO_AGF(agfbuf); agibuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0); if (!agibuf) { do_error(_("can't read agi block for ag %d\n"), agno); libxfs_putbuf(agfbuf); libxfs_putbuf(sbbuf); free(sb); return; } agi = XFS_BUF_TO_AGI(agibuf); /* fix up bad ag headers */ status = verify_set_agheader(mp, sbbuf, sb, agf, agi, agno); if (status & XR_AG_SB_SEC) { if (!no_modify) sb_dirty = 1; /* * clear bad sector bit because we don't want * to skip further processing. we just want to * ensure that we write out the modified sb buffer. */ status &= ~XR_AG_SB_SEC; } if (status & XR_AG_SB) { if (!no_modify) { do_warn(_("reset bad sb for ag %d\n"), agno); sb_dirty = 1; } else { do_warn(_("would reset bad sb for ag %d\n"), agno); } } if (status & XR_AG_AGF) { if (!no_modify) { do_warn(_("reset bad agf for ag %d\n"), agno); agf_dirty = 1; } else { do_warn(_("would reset bad agf for ag %d\n"), agno); } } if (status & XR_AG_AGI) { if (!no_modify) { do_warn(_("reset bad agi for ag %d\n"), agno); agi_dirty = 1; } else { do_warn(_("would reset bad agi for ag %d\n"), agno); } } if (status && no_modify) { libxfs_putbuf(agibuf); libxfs_putbuf(agfbuf); libxfs_putbuf(sbbuf); free(sb); do_warn(_("bad uncorrected agheader %d, skipping ag...\n"), agno); return; } scan_freelist(agf, agcnts); validate_agf(agf, agno, agcnts); validate_agi(agi, agno, agcnts); ASSERT(agi_dirty == 0 || (agi_dirty && !no_modify)); if (agi_dirty && !no_modify) libxfs_writebuf(agibuf, 0); else libxfs_putbuf(agibuf); ASSERT(agf_dirty == 0 || (agf_dirty && !no_modify)); if (agf_dirty && !no_modify) libxfs_writebuf(agfbuf, 0); else libxfs_putbuf(agfbuf); ASSERT(sb_dirty == 0 || (sb_dirty && !no_modify)); if (sb_dirty && !no_modify) { if (agno == 0) memcpy(&mp->m_sb, sb, sizeof(xfs_sb_t)); libxfs_sb_to_disk(XFS_BUF_TO_SBP(sbbuf), sb, XFS_SB_ALL_BITS); libxfs_writebuf(sbbuf, 0); } else libxfs_putbuf(sbbuf); free(sb); PROG_RPT_INC(prog_rpt_done[agno], 1); #ifdef XR_INODE_TRACE print_inode_list(i); #endif return; } #define SCAN_THREADS 32 void scan_ags( struct xfs_mount *mp, int scan_threads) { struct aghdr_cnts *agcnts; __uint64_t fdblocks = 0; __uint64_t icount = 0; __uint64_t ifreecount = 0; xfs_agnumber_t i; work_queue_t wq; agcnts = malloc(mp->m_sb.sb_agcount * sizeof(*agcnts)); if (!agcnts) { do_abort(_("no memory for ag header counts\n")); return; } memset(agcnts, 0, mp->m_sb.sb_agcount * sizeof(*agcnts)); create_work_queue(&wq, mp, scan_threads); for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, scan_ag, i, &agcnts[i]); destroy_work_queue(&wq); /* tally up the counts */ for (i = 0; i < mp->m_sb.sb_agcount; i++) { fdblocks += agcnts[i].fdblocks; icount += agcnts[i].icount; ifreecount += agcnts[i].ifreecount; } /* * Validate that our manual counts match the superblock. */ if (mp->m_sb.sb_icount != icount) { do_warn(_("sb_icount %" PRIu64 ", counted %" PRIu64 "\n"), mp->m_sb.sb_icount, icount); } if (mp->m_sb.sb_ifree != ifreecount) { do_warn(_("sb_ifree %" PRIu64 ", counted %" PRIu64 "\n"), mp->m_sb.sb_ifree, ifreecount); } if (mp->m_sb.sb_fdblocks != fdblocks) { do_warn(_("sb_fdblocks %" PRIu64 ", counted %" PRIu64 "\n"), mp->m_sb.sb_fdblocks, fdblocks); } } xfsprogs-3.1.9ubuntu2/repair/progress.c0000664000000000000000000003032012062210562015100 0ustar #include #include "globals.h" #include "progress.h" #include "err_protos.h" #include #define ONEMINUTE 60 #define ONEHOUR (60*ONEMINUTE) #define ONEDAY (24*ONEHOUR) #define ONEWEEK (7*ONEDAY) static char *rpt_types[] = { #define TYPE_INODE 0 N_("inodes"), #define TYPE_BLOCK 1 N_("blocks"), #define TYPE_DIR 2 N_("directories"), #define TYPE_AG 3 N_("allocation groups"), #define TYPE_AGI_BUCKET 4 N_("AGI unlinked buckets"), #define TYPE_EXTENTS 5 N_("extents"), #define TYPE_RTEXTENTS 6 N_("realtime extents"), #define TYPE_UNLINKED_LIST 7 N_("unlinked lists") }; static char *rpt_fmts[] = { #define FMT1 0 N_(" - %02d:%02d:%02d: %s - %llu of %llu %s done\n"), #define FMT2 1 N_(" - %02d:%02d:%02d: %s - %llu %s done\n"), }; typedef struct progress_rpt_s { short format; char *msg; char **fmt; char **type; } progress_rpt_t; static progress_rpt_t progress_rpt_reports[] = { {FMT1, N_("scanning filesystem freespace"), /* 0 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT1, N_("scanning agi unlinked lists"), /* 1 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT2, N_("check uncertain AG inodes"), /* 2 */ &rpt_fmts[FMT2], &rpt_types[TYPE_AGI_BUCKET]}, {FMT1, N_("process known inodes and inode discovery"), /* 3 */ &rpt_fmts[FMT1], &rpt_types[TYPE_INODE]}, {FMT1, N_("process newly discovered inodes"), /* 4 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT1, N_("setting up duplicate extent list"), /* 5 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT1, N_("initialize realtime bitmap"), /* 6 */ &rpt_fmts[FMT1], &rpt_types[TYPE_BLOCK]}, {FMT1, N_("reset realtime bitmaps"), /* 7 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT1, N_("check for inodes claiming duplicate blocks"), /* 8 */ &rpt_fmts[FMT1], &rpt_types[TYPE_INODE]}, {FMT1, N_("rebuild AG headers and trees"), /* 9 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT1, N_("traversing filesystem"), /* 10 */ &rpt_fmts[FMT1], &rpt_types[TYPE_AG]}, {FMT2, N_("traversing all unattached subtrees"), /* 11 */ &rpt_fmts[FMT2], &rpt_types[TYPE_DIR]}, {FMT2, N_("moving disconnected inodes to lost+found"), /* 12 */ &rpt_fmts[FMT2], &rpt_types[TYPE_INODE]}, {FMT1, N_("verify and correct link counts"), /* 13 */ &rpt_fmts[FMT1], &rpt_types[TYPE_INODE]}, {FMT1, N_("verify link counts"), /* 14 */ &rpt_fmts[FMT1], &rpt_types[TYPE_INODE]} }; pthread_t report_thread; typedef struct msg_block_s { pthread_mutex_t mutex; progress_rpt_t *format; __uint64_t *done; __uint64_t *total; int count; int interval; } msg_block_t; static msg_block_t global_msgs; typedef struct phase_times_s { time_t start; time_t end; time_t duration; __uint64_t item_counts[4]; } phase_times_t; static phase_times_t phase_times[8]; static void *progress_rpt_thread(void *); static int current_phase; static int running; static __uint64_t prog_rpt_total; void init_progress_rpt (void) { /* * allocate the done vector */ if ((prog_rpt_done = (__uint64_t *) malloc(sizeof(__uint64_t)*glob_agcount)) == NULL ) { do_error(_("cannot malloc pointer to done vector\n")); } bzero(prog_rpt_done, sizeof(__uint64_t)*glob_agcount); /* * Setup comm block, start the thread */ pthread_mutex_init(&global_msgs.mutex, NULL); global_msgs.count = glob_agcount; global_msgs.interval = report_interval; global_msgs.done = prog_rpt_done; global_msgs.total = &prog_rpt_total; if (pthread_create (&report_thread, NULL, progress_rpt_thread, (void *)&global_msgs)) do_error(_("unable to create progress report thread\n")); return; } void stop_progress_rpt(void) { /* * Tell msg thread to shutdown, * wait for all threads to finished */ running = 0; pthread_kill (report_thread, SIGHUP); pthread_join (report_thread, NULL); free(prog_rpt_done); return; } static void * progress_rpt_thread (void *p) { int i; int caught; sigset_t sigs_to_catch; struct tm *tmp; time_t now, elapsed; timer_t timerid; struct itimerspec timespec; char *msgbuf; __uint64_t *donep; __uint64_t sum; msg_block_t *msgp = (msg_block_t *)p; __uint64_t percent; if ((msgbuf = (char *)malloc(DURATION_BUF_SIZE)) == NULL) do_error (_("progress_rpt: cannot malloc progress msg buffer\n")); running = 1; /* * Specify a repeating timer that fires each MSG_INTERVAL seconds. */ timespec.it_value.tv_sec = msgp->interval; timespec.it_value.tv_nsec = 0; timespec.it_interval.tv_sec = msgp->interval; timespec.it_interval.tv_nsec = 0; if (timer_create (CLOCK_REALTIME, NULL, &timerid)) do_error(_("progress_rpt: cannot create timer\n")); if (timer_settime (timerid, 0, ×pec, NULL)) do_error(_("progress_rpt: cannot set timer\n")); /* * Main loop - output messages based on periodic signal arrival * set this thread's signal mask to block out all other signals */ sigemptyset (&sigs_to_catch); sigaddset (&sigs_to_catch, SIGALRM); sigaddset (&sigs_to_catch, SIGHUP); sigwait (&sigs_to_catch, &caught); while (caught != SIGHUP) { /* * Allow the mainline to hold off messages by holding * the lock. We don't want to just skip a period in case the * reporting interval is very long... people get nervous. But, * if the interval is very short, we can't let the timer go * off again without sigwait'ing for it. So disarm the timer * while we try to get the lock and giveup the cpu... the * mainline shouldn't take that long. */ if (pthread_mutex_lock(&msgp->mutex)) { do_error(_("progress_rpt: cannot lock progress mutex\n")); } if (!running) break; now = time (NULL); tmp = localtime ((const time_t *) &now); /* * Sum the work */ sum = 0; donep = msgp->done; for (i = 0; i < msgp->count; i++) { sum += *donep++; } percent = 0; switch(msgp->format->format) { case FMT1: if (*msgp->total) percent = (sum * 100) / ( *msgp->total ); sprintf (msgbuf, *msgp->format->fmt, tmp->tm_hour, tmp->tm_min, tmp->tm_sec, msgp->format->msg, sum, *msgp->total, *msgp->format->type); break; case FMT2: sprintf (msgbuf, *msgp->format->fmt, tmp->tm_hour, tmp->tm_min, tmp->tm_sec, msgp->format->msg, sum, *msgp->format->type); break; } do_log(_("%s"), msgbuf); elapsed = now - phase_times[current_phase].start; if ((msgp->format->format == FMT1) && sum && elapsed && ((current_phase == 3) || (current_phase == 4) || (current_phase == 7))) { /* for inode phase report % complete */ do_log( _("\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n"), tmp->tm_hour, tmp->tm_min, tmp->tm_sec, current_phase, duration(elapsed, msgbuf), (int) (60*sum/(elapsed)), *msgp->format->type); do_log( _("\t- %02d:%02d:%02d: Phase %d: %" PRIu64 "%% done - estimated remaining time %s\n"), tmp->tm_hour, tmp->tm_min, tmp->tm_sec, current_phase, percent, duration((int) ((*msgp->total - sum) * (elapsed)/sum), msgbuf)); } if (pthread_mutex_unlock(&msgp->mutex) != 0) { do_error( _("progress_rpt: error unlock msg mutex\n")); } sigwait (&sigs_to_catch, &caught); } if (timer_delete (timerid)) do_warn(_("cannot delete timer\n")); free (msgbuf); return (NULL); } int set_progress_msg (int report, __uint64_t total) { if (!ag_stride) return (0); if (pthread_mutex_lock(&global_msgs.mutex)) do_error(_("set_progress_msg: cannot lock progress mutex\n")); prog_rpt_total = total; global_msgs.format = &progress_rpt_reports[report]; /* reset all the accumulative totals */ if (prog_rpt_done) bzero(prog_rpt_done, sizeof(__uint64_t)*glob_agcount); if (pthread_mutex_unlock(&global_msgs.mutex)) do_error(_("set_progress_msg: cannot unlock progress mutex\n")); return (0); } __uint64_t print_final_rpt(void) { int i; struct tm *tmp; time_t now; __uint64_t *donep; __uint64_t sum; msg_block_t *msgp = &global_msgs; char msgbuf[DURATION_BUF_SIZE]; if (!ag_stride) return 0; if (pthread_mutex_lock(&global_msgs.mutex)) do_error(_("print_final_rpt: cannot lock progress mutex\n")); bzero(&msgbuf, sizeof(msgbuf)); now = time (NULL); tmp = localtime ((const time_t *) &now); /* * Sum the work */ sum = 0; donep = msgp->done; for (i = 0; i < msgp->count; i++) { sum += *donep++; } if (report_interval) { switch(msgp->format->format) { case FMT1: sprintf (msgbuf, _(*msgp->format->fmt), tmp->tm_hour, tmp->tm_min, tmp->tm_sec, _(msgp->format->msg), sum, *msgp->total, _(*msgp->format->type)); break; case FMT2: sprintf (msgbuf, _(*msgp->format->fmt), tmp->tm_hour, tmp->tm_min, tmp->tm_sec, _(msgp->format->msg), sum, _(*msgp->format->type)); break; } do_log(_("%s"), msgbuf); } if (pthread_mutex_unlock(&global_msgs.mutex)) do_error(_("print_final_rpt: cannot unlock progress mutex\n")); return(sum); } static void timediff(int phase) { phase_times[phase].duration = phase_times[phase].end - phase_times[phase].start; } /* ** Get the time and save in the phase time ** array. */ char * timestamp(int end, int phase, char *buf) { time_t now; struct tm *tmp; if (verbose > 1) cache_report(stderr, "libxfs_bcache", libxfs_bcache); now = time(NULL); if (end) { phase_times[phase].end = now; timediff(phase); /* total time in slot zero */ phase_times[0].end = now; timediff(0); if (phase < 7) { phase_times[phase+1].start = now; current_phase = phase + 1; } } else { phase_times[phase].start = now; current_phase = phase; } if (buf) { tmp = localtime((const time_t *)&now); sprintf(buf, _("%02d:%02d:%02d"), tmp->tm_hour, tmp->tm_min, tmp->tm_sec); } return(buf); } char * duration(int length, char *buf) { int sum; int weeks; int days; int hours; int minutes; int seconds; char temp[128]; *buf = '\0'; weeks = days = hours = minutes = seconds = sum = 0; if (length >= ONEWEEK) { weeks = length / ONEWEEK; sum = (weeks * ONEWEEK); if (weeks) { sprintf(buf, _("%d week"), weeks); if (weeks > 1) strcat(buf, _("s")); if ((length-sum) == 0) return(buf); } } if (length >= ONEDAY) { days = (length - sum) / ONEDAY; sum += (days * ONEDAY); if (days) { sprintf(temp, _("%d day"), days); if (days > 1) strcat(temp, _("s")); if (((length-sum) == 0) && (!weeks)) { strcpy(buf, temp); return(buf); } else if (weeks) { strcat(buf, _(", ")); } strcat(buf, temp); } } if (length >= ONEHOUR) { hours = (length - sum) / ONEHOUR; sum += (hours * ONEHOUR); if (hours) { sprintf(temp, _("%d hour"), hours); if (hours > 1) strcat(temp, _("s")); if (((length-sum) == 0) && (!weeks) && (!days)) { strcpy(buf, temp); return(buf); } else if ((weeks) || (days)) { strcat(buf, _(", ")); } strcat(buf, temp); } } if (length >= ONEMINUTE) { minutes = (length - sum) / ONEMINUTE; sum += (minutes * ONEMINUTE); if (minutes) { sprintf(temp, _("%d minute"), minutes); if (minutes > 1) strcat(temp, _("s")); if (((length-sum) == 0) && (!weeks) && (!days) && (!hours)) { strcpy(buf, temp); return(buf); } else if ((weeks)||(days)||(hours)) { strcat(buf, _(", ")); } strcat(buf, temp); } } seconds = length - sum; if (seconds) { sprintf(temp, _("%d second"), seconds); if (seconds > 1) strcat(temp, _("s")); if ((weeks)||(days)||(hours)||(minutes)) strcat(buf, _(", ")); strcat(buf, temp); } return(buf); } void summary_report(void) { int i; time_t now; struct tm end; struct tm start; char msgbuf[DURATION_BUF_SIZE]; now = time(NULL); do_log(_("\n XFS_REPAIR Summary %s\n"), ctime((const time_t *)&now)); do_log(_("Phase\t\tStart\t\tEnd\t\tDuration\n")); for (i = 1; i < 8; i++) { localtime_r((const time_t *)&phase_times[i].start, &start); localtime_r((const time_t *)&phase_times[i].end, &end); if ((no_modify) && (i == 5)) { do_log(_("Phase %d:\tSkipped\n"), i); } else if ((bad_ino_btree) && ((i == 6) || (i == 7))) { do_log(_("Phase %d:\tSkipped\n"), i); } else { do_log( _("Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n"), i, start.tm_mon+1, start.tm_mday, start.tm_hour, start.tm_min, start.tm_sec, end.tm_mon+1, end.tm_mday, end.tm_hour, end.tm_min, end.tm_sec, duration(phase_times[i].duration, msgbuf)); } } do_log(_("\nTotal run time: %s\n"), duration(phase_times[0].duration, msgbuf)); } xfsprogs-3.1.9ubuntu2/repair/versions.h0000664000000000000000000000410411140033220015100 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_VERSIONS_H #define _XR_VERSIONS_H #ifndef EXTERN #define EXTERN extern #endif /* EXTERN */ /* * possible XFS filesystem features * * attributes (6.2) * inode version 2 (32-bit link counts) (6.2) * quotas (6.2+) * aligned inodes (6.2+) * * bitmask fields happend after 6.2. */ /* * filesystem feature global vars, set to 1 if the feature * is *allowed*, 0 otherwise. These can be set via command-line * options */ EXTERN int fs_attributes_allowed; EXTERN int fs_attributes2_allowed; EXTERN int fs_inode_nlink_allowed; EXTERN int fs_quotas_allowed; EXTERN int fs_aligned_inodes_allowed; EXTERN int fs_sb_feature_bits_allowed; EXTERN int fs_has_extflgbit_allowed; EXTERN int fs_shared_allowed; /* * filesystem feature global vars, set to 1 if the feature * is on, 0 otherwise */ EXTERN int fs_attributes; EXTERN int fs_attributes2; EXTERN int fs_inode_nlink; EXTERN int fs_quotas; EXTERN int fs_aligned_inodes; EXTERN int fs_sb_feature_bits; EXTERN int fs_has_extflgbit; EXTERN int fs_shared; /* * inode chunk alignment, fsblocks */ EXTERN xfs_extlen_t fs_ino_alignment; /* * modify superblock to reflect current state of global fs * feature vars above */ void update_sb_version(xfs_mount_t *mp); /* * parse current sb to set above feature vars */ int parse_sb_version(xfs_sb_t *sb); #endif /* _XR_VERSIONS_H */ xfsprogs-3.1.9ubuntu2/repair/dir.c0000664000000000000000000021342612062210562014024 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dinode.h" #include "dir.h" #include "bmap.h" #if XFS_DIR_LEAF_MAPSIZE >= XFS_ATTR_LEAF_MAPSIZE #define XR_DA_LEAF_MAPSIZE XFS_DIR_LEAF_MAPSIZE #else #define XR_DA_LEAF_MAPSIZE XFS_ATTR_LEAF_MAPSIZE #endif typedef struct da_hole_map { int lost_holes; int num_holes; struct { int base; int size; } hentries[XR_DA_LEAF_MAPSIZE]; } da_hole_map_t; /* * takes a name and length (name need not be null-terminated) * and returns 1 if the name contains a '/' or a \0, returns 0 * otherwise */ int namecheck(char *name, int length) { char *c; int i; ASSERT(length < MAXNAMELEN); for (c = name, i = 0; i < length; i++, c++) { if (*c == '/' || *c == '\0') return(1); } return(0); } /* * this routine performs inode discovery and tries to fix things * in place. available redundancy -- inode data size should match * used directory space in inode. returns number of valid directory * entries. a non-zero return value means the directory is bogus * and should be blasted. */ static int process_shortform_dir( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, /* out - 1 if dinode buffer dirty? */ xfs_ino_t *parent, /* out - NULLFSINO if entry doesn't exist */ char *dirname, /* directory pathname */ int *repair) /* out - 1 if dir was fixed up */ { xfs_dir_shortform_t *sf; xfs_dir_sf_entry_t *sf_entry, *next_sfe, *tmp_sfe; xfs_ino_t lino; int max_size; __int64_t ino_dir_size; int num_entries; int ino_off; int namelen; int i; int junkit; int tmp_len; int tmp_elen; int bad_sfnamelen; ino_tree_node_t *irec_p; char name[MAXNAMELEN + 1]; #ifdef XR_DIR_TRACE fprintf(stderr, "process_shortform_dir - inode %llu\n", ino); #endif sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); max_size = XFS_DFORK_DSIZE(dip, mp); num_entries = sf->hdr.count; ino_dir_size = be64_to_cpu(dip->di_size); *repair = 0; ASSERT(ino_dir_size <= max_size); /* * check for bad entry count */ if (num_entries * sizeof(xfs_dir_sf_entry_t) + sizeof(xfs_dir_sf_hdr_t) > max_size || num_entries == 0) num_entries = 0xFF; /* * run through entries, stop at first bad entry, don't need * to check for .. since that's encoded in its own field */ sf_entry = next_sfe = &sf->list[0]; for (i = 0; i < num_entries && ino_dir_size > (__psint_t)next_sfe - (__psint_t)sf; i++) { tmp_sfe = NULL; sf_entry = next_sfe; junkit = 0; bad_sfnamelen = 0; xfs_dir_sf_get_dirino(&sf_entry->inumber, &lino); /* * if entry points to self, junk it since only '.' or '..' * should do that and shortform dirs don't contain either * entry. if inode number is invalid, trash entry. * if entry points to special inodes, trash it. * if inode is unknown but number is valid, * add it to the list of uncertain inodes. don't * have to worry about an entry pointing to a * deleted lost+found inode because the entry was * deleted at the same time that the inode was cleared. */ if (lino == ino) { junkit = 1; } else if (verify_inum(mp, lino)) { /* * junk the entry, mark lino as NULL since it's bad */ do_warn( _("invalid inode number %" PRIu64 " in directory %" PRIu64 "\n"), lino, ino); lino = NULLFSINO; junkit = 1; } else if (lino == mp->m_sb.sb_rbmino) { do_warn( _("entry in shortform dir %" PRIu64 " references rt bitmap inode %" PRIu64 "\n"), ino, lino); junkit = 1; } else if (lino == mp->m_sb.sb_rsumino) { do_warn( _("entry in shortform dir %" PRIu64 " references rt summary inode %" PRIu64 "\n"), ino, lino); junkit = 1; } else if (lino == mp->m_sb.sb_uquotino) { do_warn( _("entry in shortform dir %" PRIu64 " references user quota inode %" PRIu64 "\n"), ino, lino); junkit = 1; } else if (lino == mp->m_sb.sb_gquotino) { do_warn( _("entry in shortform dir %" PRIu64 " references group quota inode %" PRIu64 "\n"), ino, lino); junkit = 1; } else if ((irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino))) != NULL) { /* * if inode is marked free and we're in inode * discovery mode, leave the entry alone for now. * if the inode turns out to be used, we'll figure * that out when we scan it. If the inode really * is free, we'll hit this code again in phase 4 * after we've finished inode discovery and blow * out the entry then. */ ino_off = XFS_INO_TO_AGINO(mp, lino) - irec_p->ino_startnum; ASSERT(is_inode_confirmed(irec_p, ino_off)); if (!ino_discovery && is_inode_free(irec_p, ino_off)) { do_warn( _("entry references free inode %" PRIu64 " in shortform directory %" PRIu64 "\n"), lino, ino); junkit = 1; } } else if (ino_discovery) { /* * put the inode on the uncertain list. we'll * pull the inode off the list and check it later. * if the inode turns out be bogus, we'll delete * this entry in phase 6. */ add_inode_uncertain(mp, lino, 0); } else { /* * blow the entry out. we know about all * undiscovered entries now (past inode discovery * phase) so this is clearly a bogus entry. */ do_warn( _("entry references non-existent inode %" PRIu64 " in shortform dir %" PRIu64 "\n"), lino, ino); junkit = 1; } namelen = sf_entry->namelen; if (namelen == 0) { /* * if we're really lucky, this is * the last entry in which case we * can use the dir size to set the * namelen value. otherwise, forget * it because we're not going to be * able to find the next entry. */ bad_sfnamelen = 1; if (i == num_entries - 1) { namelen = ino_dir_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); if (!no_modify) { do_warn( _("zero length entry in shortform dir %" PRIu64 ", resetting to %d\n"), ino, namelen); sf_entry->namelen = namelen; } else { do_warn( _("zero length entry in shortform dir %" PRIu64 ", would set to %d\n"), ino, namelen); } } else { do_warn( _("zero length entry in shortform dir %" PRIu64 ", "), ino); if (!no_modify) do_warn(_("junking %d entries\n"), num_entries - i); else do_warn(_("would junk %d entries\n"), num_entries - i); /* * don't process the rest of the directory, * break out of processing looop */ break; } } else if ((__psint_t) sf_entry - (__psint_t) sf + + xfs_dir_sf_entsize_byentry(sf_entry) > ino_dir_size) { bad_sfnamelen = 1; if (i == num_entries - 1) { namelen = ino_dir_size - ((__psint_t) &sf_entry->name[0] - (__psint_t) sf); do_warn( _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "), ino); if (!no_modify) { do_warn(_("resetting to %d\n"), namelen); sf_entry->namelen = namelen; *dino_dirty = 1; } else { do_warn(_("would reset to %d\n"), namelen); } } else { do_warn( _("size of entry #%d overflows space left in in shortform dir %" PRIu64 "\n"), i, ino); if (!no_modify) { if (i == num_entries - 1) do_warn( _("junking entry #%d\n"), i); else do_warn( _("junking %d entries\n"), num_entries - i); } else { if (i == num_entries - 1) do_warn( _("would junk entry #%d\n"), i); else do_warn( _("would junk %d entries\n"), num_entries - i); } break; } } /* * check for illegal chars in name. * no need to check for bad length because * the length value is stored in a byte * so it can't be too big, it can only wrap */ if (namecheck((char *)&sf_entry->name[0], namelen)) { /* * junk entry */ do_warn( _("entry contains illegal character in shortform dir %" PRIu64 "\n"), ino); junkit = 1; } /* * junk the entry by copying up the rest of the * fork over the current entry and decrementing * the entry count. if we're in no_modify mode, * just issue the warning instead. then continue * the loop with the next_sfe pointer set to the * correct place in the fork and other counters * properly set to reflect the deletion if it * happened. */ if (junkit) { memmove(name, sf_entry->name, namelen); name[namelen] = '\0'; if (!no_modify) { tmp_elen = xfs_dir_sf_entsize_byentry(sf_entry); be64_add_cpu(&dip->di_size, -tmp_elen); ino_dir_size -= tmp_elen; tmp_sfe = (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + tmp_elen); tmp_len = max_size - ((__psint_t) tmp_sfe - (__psint_t) sf); memmove(sf_entry, tmp_sfe, tmp_len); sf->hdr.count -= 1; num_entries--; memset((void *)((__psint_t)sf_entry + tmp_len), 0, tmp_elen); /* * reset the tmp value to the current * pointer so we'll process the entry * we just moved up */ tmp_sfe = sf_entry; /* * WARNING: drop the index i by one * so it matches the decremented count * for accurate comparisons later */ i--; *dino_dirty = 1; *repair = 1; do_warn( _("junking entry \"%s\" in directory inode %" PRIu64 "\n"), name, ino); } else { do_warn( _("would have junked entry \"%s\" in directory inode %" PRIu64 "\n"), name, ino); } } /* * go onto next entry unless we've just junked an * entry in which the current entry pointer points * to an unprocessed entry. have to take into zero-len * entries into account in no modify mode since we * calculate size based on next_sfe. */ next_sfe = (tmp_sfe == NULL) ? (xfs_dir_sf_entry_t *) ((__psint_t) sf_entry + ((!bad_sfnamelen) ? xfs_dir_sf_entsize_byentry(sf_entry) : sizeof(xfs_dir_sf_entry_t) - 1 + namelen)) : tmp_sfe; } /* sync up sizes and entry counts */ if (sf->hdr.count != i) { if (no_modify) { do_warn( _("would have corrected entry count in directory %" PRIu64 " from %d to %d\n"), ino, sf->hdr.count, i); } else { do_warn( _("corrected entry count in directory %" PRIu64 ", was %d, now %d\n"), ino, sf->hdr.count, i); sf->hdr.count = i; *dino_dirty = 1; *repair = 1; } } if ((__psint_t) next_sfe - (__psint_t) sf != ino_dir_size) { if (no_modify) { do_warn( _("would have corrected directory %" PRIu64 " size from %" PRId64 "to %" PRIdPTR "\n"), ino, ino_dir_size, (intptr_t)next_sfe - (intptr_t )sf); } else { do_warn( _("corrected directory %" PRIu64 " size, was %" PRId64 ", now %" PRIdPTR "\n"), ino, ino_dir_size, (intptr_t)next_sfe - (intptr_t)sf); dip->di_size = cpu_to_be64((__psint_t)next_sfe - (__psint_t)sf); *dino_dirty = 1; *repair = 1; } } /* * check parent (..) entry */ xfs_dir_sf_get_dirino(&sf->hdr.parent, parent); /* * if parent entry is bogus, null it out. we'll fix it later . */ if (verify_inum(mp, *parent)) { *parent = NULLFSINO; do_warn( _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "), *parent, ino); if (!no_modify) { do_warn(_("clearing inode number\n")); xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn(_("would clear inode number\n")); } } else if (ino == mp->m_sb.sb_rootino && ino != *parent) { /* * root directories must have .. == . */ if (!no_modify) { do_warn( _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 "\n"), ino, *parent, ino); *parent = ino; xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn( _("would have corrected root directory %" PRIu64 " .. entry from %" PRIu64 " to %" PRIu64 "\n"), ino, *parent, ino); } } else if (ino == *parent && ino != mp->m_sb.sb_rootino) { /* * likewise, non-root directories can't have .. pointing * to . */ *parent = NULLFSINO; do_warn(_("bad .. entry in dir ino %" PRIu64 ", points to self, "), ino); if (!no_modify) { do_warn(_("clearing inode number\n")); xfs_dir_sf_put_dirino(parent, &sf->hdr.parent); *dino_dirty = 1; *repair = 1; } else { do_warn(_("would clear inode number\n")); } } return(0); } /* * Allocate a freespace map for directory or attr leaf blocks (1 bit per byte) * 1 == used, 0 == free. */ da_freemap_t * alloc_da_freemap(struct xfs_mount *mp) { return calloc(1, mp->m_sb.sb_blocksize / NBBY); } /* * Set the he range [start, stop) in the directory freemap. * * Returns 1 if there is a conflict or 0 if everything's good. * * Within a char, the lowest bit of the char represents the byte with * the smallest address */ int set_da_freemap(xfs_mount_t *mp, da_freemap_t *map, int start, int stop) { const da_freemap_t mask = 0x1; int i; if (start > stop) { /* * allow == relation since [x, x) claims 1 byte */ do_warn(_("bad range claimed [%d, %d) in da block\n"), start, stop); return(1); } if (stop > mp->m_sb.sb_blocksize) { do_warn( _("byte range end [%d %d) in da block larger than blocksize %d\n"), start, stop, mp->m_sb.sb_blocksize); return(1); } for (i = start; i < stop; i ++) { if (map[i / NBBY] & (mask << i % NBBY)) { do_warn(_("multiply claimed byte %d in da block\n"), i); return(1); } map[i / NBBY] |= (mask << i % NBBY); } return(0); } /* * returns 0 if holemap is consistent with reality (as expressed by * the da_freemap_t). returns 1 if there's a conflict. */ static int verify_da_freemap(xfs_mount_t *mp, da_freemap_t *map, da_hole_map_t *holes, xfs_ino_t ino, xfs_dablk_t da_bno) { int i, j, start, len; const da_freemap_t mask = 0x1; for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { if (holes->hentries[i].size == 0) continue; start = holes->hentries[i].base; len = holes->hentries[i].size; if (start >= mp->m_sb.sb_blocksize || start + len > mp->m_sb.sb_blocksize) { do_warn( _("hole (start %d, len %d) out of range, block %d, dir ino %" PRIu64 "\n"), start, len, da_bno, ino); return(1); } for (j = start; j < start + len; j++) { if ((map[j / NBBY] & (mask << (j % NBBY))) != 0) { /* * bad news -- hole claims a used byte is free */ do_warn( _("hole claims used byte %d, block %d, dir ino %" PRIu64 "\n"), j, da_bno, ino); return(1); } } } return(0); } static void process_da_freemap(xfs_mount_t *mp, da_freemap_t *map, da_hole_map_t *holes) { int i, j, in_hole, start, length, smallest, num_holes; const da_freemap_t mask = 0x1; num_holes = in_hole = start = length = 0; for (i = 0; i < mp->m_sb.sb_blocksize; i++) { if ((map[i / NBBY] & (mask << (i % NBBY))) == 0) { /* * byte is free (unused) */ if (in_hole == 1) continue; /* * start of a new hole */ in_hole = 1; start = i; } else { /* * byte is used */ if (in_hole == 0) continue; /* * end of a hole */ in_hole = 0; /* * if the hole disappears, throw it away */ length = i - start; if (length <= 0) continue; num_holes++; for (smallest = j = 0; j < XR_DA_LEAF_MAPSIZE; j++) { if (holes->hentries[j].size < holes->hentries[smallest].size) smallest = j; } if (length > holes->hentries[smallest].size) { holes->hentries[smallest].base = start; holes->hentries[smallest].size = length; } } } /* * see if we have a big hole at the end */ if (in_hole == 1) { /* * duplicate of hole placement code above */ length = i - start; if (length > 0) { num_holes++; for (smallest = j = 0; j < XR_DA_LEAF_MAPSIZE; j++) { if (holes->hentries[j].size < holes->hentries[smallest].size) smallest = j; } if (length > holes->hentries[smallest].size) { holes->hentries[smallest].base = start; holes->hentries[smallest].size = length; } } } holes->lost_holes = MAX(num_holes - XR_DA_LEAF_MAPSIZE, 0); holes->num_holes = num_holes; return; } /* * returns 1 if the hole info doesn't match, 0 if it does */ static int compare_da_freemaps(xfs_mount_t *mp, da_hole_map_t *holemap, da_hole_map_t *block_hmap, int entries, xfs_ino_t ino, xfs_dablk_t da_bno) { int i, k, res, found; res = 0; /* * we chop holemap->lost_holes down to being two-valued * value (1 or 0) for the test because the filesystem * value is two-valued */ if ((holemap->lost_holes > 0 ? 1 : 0) != block_hmap->lost_holes) { if (verbose) { do_warn( _("- derived hole value %d, saw %d, block %d, dir ino %" PRIu64 "\n"), holemap->lost_holes, block_hmap->lost_holes, da_bno, ino); res = 1; } else return(1); } for (i = 0; i < entries; i++) { for (found = k = 0; k < entries; k++) { if (holemap->hentries[i].base == block_hmap->hentries[k].base && holemap->hentries[i].size == block_hmap->hentries[k].size) found = 1; } if (!found) { if (verbose) { do_warn( _("- derived hole (base %d, size %d) in block %d, dir inode %" PRIu64 " not found\n"), holemap->hentries[i].base, holemap->hentries[i].size, da_bno, ino); res = 1; } else return(1); } } return(res); } /* * walk tree from root to the left-most leaf block reading in * blocks and setting up cursor. passes back file block number of the * left-most leaf block if successful (bno). returns 1 if successful, * 0 if unsuccessful. */ int traverse_int_dablock(xfs_mount_t *mp, da_bt_cursor_t *da_cursor, xfs_dablk_t *rbno, int whichfork) { xfs_dablk_t bno; int i; xfs_da_intnode_t *node; xfs_dfsbno_t fsbno; xfs_buf_t *bp; /* * traverse down left-side of tree until we hit the * left-most leaf block setting up the btree cursor along * the way. */ bno = 0; i = -1; node = NULL; da_cursor->active = 0; do { /* * read in each block along the way and set up cursor */ fsbno = blkmap_get(da_cursor->blkmap, bno); if (fsbno == NULLDFSBNO) goto error_out; bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { if (whichfork == XFS_DATA_FORK) do_warn( _("can't read block %u (fsbno %" PRIu64 ") for directory inode %" PRIu64 "\n"), bno, fsbno, da_cursor->ino); else do_warn( _("can't read block %u (fsbno %" PRIu64 ") for attrbute fork of inode %" PRIu64 "\n"), bno, fsbno, da_cursor->ino); goto error_out; } node = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) { do_warn(_("bad dir/attr magic number in inode %" PRIu64 ", " "file bno = %u, fsbno = %" PRIu64 "\n"), da_cursor->ino, bno, fsbno); libxfs_putbuf(bp); goto error_out; } if (be16_to_cpu(node->hdr.count) > mp->m_dir_node_ents) { do_warn(_("bad record count in inode %" PRIu64 ", " "count = %d, max = %d\n"), da_cursor->ino, be16_to_cpu(node->hdr.count), mp->m_dir_node_ents); libxfs_putbuf(bp); goto error_out; } /* * maintain level counter */ if (i == -1) i = da_cursor->active = be16_to_cpu(node->hdr.level); else { if (be16_to_cpu(node->hdr.level) == i - 1) { i--; } else { if (whichfork == XFS_DATA_FORK) do_warn(_("bad directory btree for " "directory inode %" PRIu64 "\n"), da_cursor->ino); else do_warn(_("bad attribute fork btree " "for inode %" PRIu64 "\n"), da_cursor->ino); libxfs_putbuf(bp); goto error_out; } } da_cursor->level[i].hashval = be32_to_cpu( node->btree[0].hashval); da_cursor->level[i].bp = bp; da_cursor->level[i].bno = bno; da_cursor->level[i].index = 0; #ifdef XR_DIR_TRACE da_cursor->level[i].n = XFS_BUF_TO_DA_INTNODE(bp); #endif /* * set up new bno for next level down */ bno = be32_to_cpu(node->btree[0].before); } while (node != NULL && i > 1); /* * now return block number and get out */ *rbno = da_cursor->level[0].bno = bno; return(1); error_out: while (i > 1 && i <= da_cursor->active) { libxfs_putbuf(da_cursor->level[i].bp); i++; } return(0); } /* * blow out buffer for this level and all the rest above as well * if error == 0, we are not expecting to encounter any unreleased * buffers (e.g. if we do, it's a mistake). if error == 1, we're * in an error-handling case so unreleased buffers may exist. */ static void release_da_cursor_int(xfs_mount_t *mp, da_bt_cursor_t *cursor, int prev_level, int error) { int level = prev_level + 1; if (cursor->level[level].bp != NULL) { if (!error) { do_warn(_("release_da_cursor_int got unexpected " "non-null bp, dabno = %u\n"), cursor->level[level].bno); } ASSERT(error != 0); libxfs_putbuf(cursor->level[level].bp); cursor->level[level].bp = NULL; } if (level < cursor->active) release_da_cursor_int(mp, cursor, level, error); return; } void release_da_cursor(xfs_mount_t *mp, da_bt_cursor_t *cursor, int prev_level) { release_da_cursor_int(mp, cursor, prev_level, 0); } void err_release_da_cursor(xfs_mount_t *mp, da_bt_cursor_t *cursor, int prev_level) { release_da_cursor_int(mp, cursor, prev_level, 1); } /* * make sure that all entries in all blocks along the right side of * of the tree are used and hashval's are consistent. level is the * level of the descendent block. returns 0 if good (even if it had * to be fixed up), and 1 if bad. The right edge of the tree is * technically a block boundary. this routine should be used then * instead of verify_da_path(). */ int verify_final_da_path(xfs_mount_t *mp, da_bt_cursor_t *cursor, const int p_level) { xfs_da_intnode_t *node; xfs_dahash_t hashval; int bad = 0; int entry; int this_level = p_level + 1; #ifdef XR_DIR_TRACE fprintf(stderr, "in verify_final_da_path, this_level = %d\n", this_level); #endif /* * the index should point to the next "unprocessed" entry * in the block which should be the final (rightmost) entry */ entry = cursor->level[this_level].index; node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); /* * check internal block consistency on this level -- ensure * that all entries are used, encountered and expected hashvals * match, etc. */ if (entry != be16_to_cpu(node->hdr.count) - 1) { do_warn(_("directory/attribute block used/count " "inconsistency - %d/%hu\n"), entry, be16_to_cpu(node->hdr.count)); bad++; } /* * hash values monotonically increasing ??? */ if (cursor->level[this_level].hashval >= be32_to_cpu(node->btree[entry].hashval)) { do_warn(_("directory/attribute block hashvalue inconsistency, " "expected > %u / saw %u\n"), cursor->level[this_level].hashval, be32_to_cpu(node->btree[entry].hashval)); bad++; } if (be32_to_cpu(node->hdr.info.forw) != 0) { do_warn(_("bad directory/attribute forward block pointer, " "expected 0, saw %u\n"), be32_to_cpu(node->hdr.info.forw)); bad++; } if (bad) { do_warn(_("bad directory block in dir ino %" PRIu64 "\n"), cursor->ino); return(1); } /* * keep track of greatest block # -- that gets * us the length of the directory */ if (cursor->level[this_level].bno > cursor->greatest_bno) cursor->greatest_bno = cursor->level[this_level].bno; /* * ok, now check descendant block number against this level */ if (cursor->level[p_level].bno != be32_to_cpu( node->btree[entry].before)) { #ifdef XR_DIR_TRACE fprintf(stderr, "bad directory btree pointer, child bno should " "be %d, block bno is %d, hashval is %u\n", be16_to_cpu(node->btree[entry].before), cursor->level[p_level].bno, cursor->level[p_level].hashval); fprintf(stderr, "verify_final_da_path returns 1 (bad) #1a\n"); #endif return(1); } if (cursor->level[p_level].hashval != be32_to_cpu( node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in non-leaf " "dir/attr block\n\tin (level %d) in " "inode %" PRIu64 ".\n"), this_level, cursor->ino); node->btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in non-leaf " "dir/attr block\n\tin (level %d) in " "inode %" PRIu64 ".\n"), this_level, cursor->ino); } } /* * Note: squirrel hashval away _before_ releasing the * buffer, preventing a use-after-free problem. */ hashval = be32_to_cpu(node->btree[entry].hashval); /* * release/write buffer */ ASSERT(cursor->level[this_level].dirty == 0 || (cursor->level[this_level].dirty && !no_modify)); if (cursor->level[this_level].dirty && !no_modify) libxfs_writebuf(cursor->level[this_level].bp, 0); else libxfs_putbuf(cursor->level[this_level].bp); cursor->level[this_level].bp = NULL; /* * bail out if this is the root block (top of tree) */ if (this_level >= cursor->active) { #ifdef XR_DIR_TRACE fprintf(stderr, "verify_final_da_path returns 0 (ok)\n"); #endif return(0); } /* * set hashvalue to correctly reflect the now-validated * last entry in this block and continue upwards validation */ cursor->level[this_level].hashval = hashval; return(verify_final_da_path(mp, cursor, this_level)); } /* * Verifies the path from a descendant block up to the root. * Should be called when the descendant level traversal hits * a block boundary before crossing the boundary (reading in a new * block). * * the directory/attr btrees work differently to the other fs btrees. * each interior block contains records that are * pairs. The bno is a file bno, not a filesystem bno. The last * hashvalue in the block will be . BUT unlike * the freespace btrees, the *last* value in each block gets * propagated up the tree instead of the first value in each block. * that is, the interior records point to child blocks and the *greatest* * hash value contained by the child block is the one the block above * uses as the key for the child block. * * level is the level of the descendent block. returns 0 if good, * and 1 if bad. The descendant block may be a leaf block. * * the invariant here is that the values in the cursor for the * levels beneath this level (this_level) and the cursor index * for this level *must* be valid. * * that is, the hashval/bno info is accurate for all * DESCENDANTS and match what the node[index] information * for the current index in the cursor for this level. * * the index values in the cursor for the descendant level * are allowed to be off by one as they will reflect the * next entry at those levels to be processed. * * the hashvalue for the current level can't be set until * we hit the last entry in the block so, it's garbage * until set by this routine. * * bno and bp for the current block/level are always valid * since they have to be set so we can get a buffer for the * block. */ int verify_da_path(xfs_mount_t *mp, da_bt_cursor_t *cursor, const int p_level) { xfs_da_intnode_t *node; xfs_da_intnode_t *newnode; xfs_dfsbno_t fsbno; xfs_dablk_t dabno; xfs_buf_t *bp; int bad; int entry; int this_level = p_level + 1; /* * index is currently set to point to the entry that * should be processed now in this level. */ entry = cursor->level[this_level].index; node = (xfs_da_intnode_t *)XFS_BUF_PTR(cursor->level[this_level].bp); /* * if this block is out of entries, validate this * block and move on to the next block. * and update cursor value for said level */ if (entry >= be16_to_cpu(node->hdr.count)) { /* * update the hash value for this level before * validating it. bno value should be ok since * it was set when the block was first read in. */ cursor->level[this_level].hashval = be32_to_cpu(node->btree[entry - 1].hashval); /* * keep track of greatest block # -- that gets * us the length of the directory */ if (cursor->level[this_level].bno > cursor->greatest_bno) cursor->greatest_bno = cursor->level[this_level].bno; /* * validate the path for the current used-up block * before we trash it */ if (verify_da_path(mp, cursor, this_level)) return(1); /* * ok, now get the next buffer and check sibling pointers */ dabno = be32_to_cpu(node->hdr.info.forw); ASSERT(dabno != 0); fsbno = blkmap_get(cursor->blkmap, dabno); if (fsbno == NULLDFSBNO) { do_warn(_("can't get map info for block %u " "of directory inode %" PRIu64 "\n"), dabno, cursor->ino); return(1); } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), dabno, fsbno, cursor->ino); return(1); } newnode = (xfs_da_intnode_t *)XFS_BUF_PTR(bp); /* * verify magic number and back pointer, sanity-check * entry count, verify level */ bad = 0; if (XFS_DA_NODE_MAGIC != be16_to_cpu(newnode->hdr.info.magic)) { do_warn( _("bad magic number %x in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.info.magic), dabno, fsbno, cursor->ino); bad++; } if (be32_to_cpu(newnode->hdr.info.back) != cursor->level[this_level].bno) { do_warn( _("bad back pointer in block %u (%"PRIu64 ") for directory inode %" PRIu64 "\n"), dabno, fsbno, cursor->ino); bad++; } if (be16_to_cpu(newnode->hdr.count) > mp->m_dir_node_ents) { do_warn( _("entry count %d too large in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.count), dabno, fsbno, cursor->ino); bad++; } if (be16_to_cpu(newnode->hdr.level) != this_level) { do_warn( _("bad level %d in block %u (%" PRIu64 ") for directory inode %" PRIu64 "\n"), be16_to_cpu(newnode->hdr.level), dabno, fsbno, cursor->ino); bad++; } if (bad) { #ifdef XR_DIR_TRACE fprintf(stderr, "verify_da_path returns 1 (bad) #4\n"); #endif libxfs_putbuf(bp); return(1); } /* * update cursor, write out the *current* level if * required. don't write out the descendant level */ ASSERT(cursor->level[this_level].dirty == 0 || (cursor->level[this_level].dirty && !no_modify)); if (cursor->level[this_level].dirty && !no_modify) libxfs_writebuf(cursor->level[this_level].bp, 0); else libxfs_putbuf(cursor->level[this_level].bp); cursor->level[this_level].bp = bp; cursor->level[this_level].dirty = 0; cursor->level[this_level].bno = dabno; cursor->level[this_level].hashval = be32_to_cpu(newnode->btree[0].hashval); #ifdef XR_DIR_TRACE cursor->level[this_level].n = newnode; #endif node = newnode; entry = cursor->level[this_level].index = 0; } /* * ditto for block numbers */ if (cursor->level[p_level].bno != be32_to_cpu(node->btree[entry].before)) { #ifdef XR_DIR_TRACE fprintf(stderr, "bad directory btree pointer, child bno " "should be %d, block bno is %d, hashval is %u\n", be32_to_cpu(node->btree[entry].before), cursor->level[p_level].bno, cursor->level[p_level].hashval); fprintf(stderr, "verify_da_path returns 1 (bad) #1a\n"); #endif return(1); } /* * ok, now validate last hashvalue in the descendant * block against the hashval in the current entry */ if (cursor->level[p_level].hashval != be32_to_cpu(node->btree[entry].hashval)) { if (!no_modify) { do_warn(_("correcting bad hashval in interior " "dir/attr block\n\tin (level %d) in " "inode %" PRIu64 ".\n"), this_level, cursor->ino); node->btree[entry].hashval = cpu_to_be32( cursor->level[p_level].hashval); cursor->level[this_level].dirty++; } else { do_warn(_("would correct bad hashval in interior " "dir/attr block\n\tin (level %d) in " "inode %" PRIu64 ".\n"), this_level, cursor->ino); } } /* * increment index for this level to point to next entry * (which should point to the next descendant block) */ cursor->level[this_level].index++; #ifdef XR_DIR_TRACE fprintf(stderr, "verify_da_path returns 0 (ok)\n"); #endif return(0); } /* * called by both node dir and leaf dir processing routines * validates all contents *but* the sibling pointers (forw/back) * and the magic number. * * returns 0 if the directory is ok or has been brought to the * stage that it can be fixed up later (in phase 6), * 1 if it has to be junked. * * Right now we fix a lot of things (TBD == to be deleted). * * incorrect . entries - inode # is corrected * entries with mismatched hashvalue/name strings - hashvalue reset * entries whose hashvalues are out-of-order - entry marked TBD * .. entries with invalid inode numbers - entry marked TBD * entries with invalid inode numbers - entry marked TBD * multiple . entries - all but the first entry are marked TBD * zero-length entries - entry is deleted * entries with an out-of-bounds name index ptr - entry is deleted * * entries marked TBD have the first character of the name (which * lives in the heap) have the first character in the name set * to '/' -- an illegal value. * * entries deleted right here are deleted by blowing away the entry * (but leaving the heap untouched). any space that was used * by the deleted entry will be reclaimed by the block freespace * (da_freemap) processing code. * * if two entries claim the same space in the heap (say, due to * bad entry name index pointers), we lose the directory. We could * try harder to fix this but it'll do for now. */ static int process_leaf_dir_block( xfs_mount_t *mp, xfs_dir_leafblock_t *leaf, xfs_dablk_t da_bno, xfs_ino_t ino, xfs_dahash_t last_hashval, /* last hashval encountered */ int ino_discovery, blkmap_t *blkmap, int *dot, int *dotdot, xfs_ino_t *parent, int *buf_dirty, /* is buffer dirty? */ xfs_dahash_t *next_hashval) /* greatest hashval in block */ { xfs_ino_t lino; xfs_dir_leaf_entry_t *entry; xfs_dir_leaf_entry_t *s_entry; xfs_dir_leaf_entry_t *d_entry; xfs_dir_leafblock_t *new_leaf; char *first_byte; xfs_dir_leaf_name_t *namest; ino_tree_node_t *irec_p; int num_entries; xfs_dahash_t hashval; int i; int nm_illegal; int bytes; int start; int stop; int res = 0; int ino_off; int first_used; int bytes_used; int reset_holes; int zero_len_entries; char fname[MAXNAMELEN + 1]; da_hole_map_t holemap; da_hole_map_t bholemap; da_freemap_t *dir_freemap; #ifdef XR_DIR_TRACE fprintf(stderr, "\tprocess_leaf_dir_block - ino %" PRIu64 "\n", ino); #endif /* * clear static dir block freespace bitmap */ dir_freemap = alloc_da_freemap(mp); *buf_dirty = 0; first_used = mp->m_sb.sb_blocksize; zero_len_entries = 0; bytes_used = 0; i = stop = sizeof(xfs_dir_leaf_hdr_t); if (set_da_freemap(mp, dir_freemap, 0, stop)) { do_warn( _("directory block header conflicts with used space in directory inode %" PRIu64 "\n"), ino); res = 1; goto out; } /* * verify structure: monotonically increasing hash value for * all leaf entries, indexes for all entries must be within * this fs block (trivially true for 64K blocks). also track * used space so we can check the freespace map. check for * zero-length entries. for now, if anything's wrong, we * junk the directory and we'll pick up no-longer referenced * inodes on a later pass. */ for (i = 0, entry = &leaf->entries[0]; i < be16_to_cpu(leaf->hdr.count); i++, entry++) { /* * check that the name index isn't out of bounds * if it is, delete the entry since we can't * grab the inode #. */ if (be16_to_cpu(entry->nameidx) >= mp->m_sb.sb_blocksize) { if (!no_modify) { *buf_dirty = 1; if (be16_to_cpu(leaf->hdr.count) > 1) { do_warn( _("nameidx %d for entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, deleting entry\n"), be16_to_cpu(entry->nameidx), i, da_bno, ino); ASSERT(be16_to_cpu(leaf->hdr.count) > i); bytes = (be16_to_cpu(leaf->hdr.count) - i) * sizeof(xfs_dir_leaf_entry_t); /* * compress table unless we're * only dealing with 1 entry * (the last one) in which case * just zero it. */ if (bytes > sizeof(xfs_dir_leaf_entry_t)) { memmove(entry, entry + 1, bytes); memset((void *) ((__psint_t) entry + bytes), 0, sizeof(xfs_dir_leaf_entry_t)); } else { memset(entry, 0, sizeof(xfs_dir_leaf_entry_t)); } /* * sync vars to match smaller table. * don't have to worry about freespace * map since we haven't set it for * this entry yet. */ be16_add_cpu(&leaf->hdr.count, -1); i--; entry--; } else { do_warn( _("nameidx %d, entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, marking entry bad\n"), be16_to_cpu(entry->nameidx), i, da_bno, ino); entry->nameidx = cpu_to_be16( mp->m_sb.sb_blocksize - sizeof(xfs_dir_leaf_name_t)); namest = xfs_dir_leaf_namestruct(leaf, be16_to_cpu(entry->nameidx)); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); namest->name[0] = '/'; } } else { do_warn( _("nameidx %d, entry #%d, bno %d, ino %" PRIu64 " > fs blocksize, would delete entry\n"), be16_to_cpu(entry->nameidx), i, da_bno, ino); } continue; } /* * inode processing -- make sure the inode * is in our tree or we add it to the uncertain * list if the inode # is valid. if namelen is 0, * we can still try for the inode as long as nameidx * is ok. */ namest = xfs_dir_leaf_namestruct(leaf, be16_to_cpu(entry->nameidx)); xfs_dir_sf_get_dirino(&namest->inumber, &lino); /* * we may have to blow out an entry because of bad * inode numbers. do NOT touch the name until after * we've computed the hashvalue and done a namecheck() * on the name. */ if (!ino_discovery && lino == NULLFSINO) { /* * don't do a damned thing. We already * found this (or did it ourselves) during * phase 3. */ } else if (verify_inum(mp, lino)) { /* * bad inode number. clear the inode * number and the entry will get removed * later. We don't trash the directory * since it's still structurally intact. */ do_warn( _("invalid ino number %" PRIu64 " in dir ino %" PRIu64 ", entry #%d, bno %d\n"), lino, ino, i, da_bno); if (!no_modify) { do_warn( _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("\twould clear ino number in entry %d...\n"), i); } } else if (lino == mp->m_sb.sb_rbmino) { do_warn( _("entry #%d, bno %d in directory %" PRIu64 " references realtime bitmap inode %" PRIu64 "\n"), i, da_bno, ino, lino); if (!no_modify) { do_warn( _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("\twould clear ino number in entry %d...\n"), i); } } else if (lino == mp->m_sb.sb_rsumino) { do_warn( _("entry #%d, bno %d in directory %" PRIu64 " references realtime summary inode %" PRIu64 "\n"), i, da_bno, ino, lino); if (!no_modify) { do_warn( _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("\twould clear ino number in entry %d...\n"), i); } } else if (lino == mp->m_sb.sb_uquotino) { do_warn( _("entry #%d, bno %d in directory %" PRIu64 " references user quota inode %" PRIu64 "\n"), i, da_bno, ino, lino); if (!no_modify) { do_warn( _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("\twould clear ino number in entry %d...\n"), i); } } else if (lino == mp->m_sb.sb_gquotino) { do_warn( _("entry #%d, bno %d in directory %" PRIu64 " references group quota inode %" PRIu64 "\n"), i, da_bno, ino, lino); if (!no_modify) { do_warn( _("\tclearing ino number in entry %d...\n"), i); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("\twould clear ino number in entry %d...\n"), i); } } else if ((irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino))) != NULL) { /* * inode recs should have only confirmed * inodes in them */ ino_off = XFS_INO_TO_AGINO(mp, lino) - irec_p->ino_startnum; ASSERT(is_inode_confirmed(irec_p, ino_off)); /* * if inode is marked free and we're in inode * discovery mode, leave the entry alone for now. * if the inode turns out to be used, we'll figure * that out when we scan it. If the inode really * is free, we'll hit this code again in phase 4 * after we've finished inode discovery and blow * out the entry then. */ if (!ino_discovery && is_inode_free(irec_p, ino_off)) { if (!no_modify) { do_warn( _("entry references free inode %" PRIu64 " in directory %" PRIu64 ", will clear entry\n"), lino, ino); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("entry references free inode %" PRIu64 " in directory %" PRIu64 ", would clear entry\n"), lino, ino); } } } else if (ino_discovery) { add_inode_uncertain(mp, lino, 0); } else { do_warn( _("bad ino number %" PRIu64 " in dir ino %" PRIu64 ", entry #%d, bno %d\n"), lino, ino, i, da_bno); if (!no_modify) { do_warn(_("clearing inode number...\n")); lino = NULLFSINO; xfs_dir_sf_put_dirino(&lino, &namest->inumber); *buf_dirty = 1; } else { do_warn(_("would clear inode number...\n")); } } /* * if we have a zero-length entry, trash it. * we may lose the inode (chunk) if we don't * finish the repair successfully and the inode * isn't mentioned anywhere else (like in the inode * tree) but the alternative is to risk losing the * entire directory by trying to use the next byte * to turn the entry into a 1-char entry. That's * probably a safe bet but if it didn't work, we'd * lose the entire directory the way we currently do * things. (Maybe we should change that later :-). */ if (entry->namelen == 0) { *buf_dirty = 1; if (be16_to_cpu(leaf->hdr.count) > 1) { do_warn( _("entry #%d, dir inode %" PRIu64 ", has zero-len name, deleting entry\n"), i, ino); ASSERT(be16_to_cpu(leaf->hdr.count) > i); bytes = (be16_to_cpu(leaf->hdr.count) - i) * sizeof(xfs_dir_leaf_entry_t); /* * compress table unless we're * only dealing with 1 entry * (the last one) in which case * just zero it. */ if (bytes > sizeof(xfs_dir_leaf_entry_t)) { memmove(entry, entry + 1, bytes); memset((void *)((__psint_t) entry + bytes), 0, sizeof(xfs_dir_leaf_entry_t)); } else { memset(entry, 0, sizeof(xfs_dir_leaf_entry_t)); } /* * sync vars to match smaller table. * don't have to worry about freespace * map since we haven't set it for * this entry yet. */ be16_add_cpu(&leaf->hdr.count, -1); i--; entry--; } else { /* * if it's the only entry, preserve the * inode number for now */ do_warn( _("entry #%d, dir inode %" PRIu64 ", has zero-len name, marking entry bad\n"), i, ino); entry->nameidx = cpu_to_be16( mp->m_sb.sb_blocksize - sizeof(xfs_dir_leaf_name_t)); namest = xfs_dir_leaf_namestruct(leaf, be16_to_cpu(entry->nameidx)); xfs_dir_sf_put_dirino(&lino, &namest->inumber); namest->name[0] = '/'; } } else if (be16_to_cpu(entry->nameidx) + entry->namelen > XFS_LBSIZE(mp)) { do_warn( _("bad size, entry #%d in dir inode %" PRIu64 ", block %u -- entry overflows block\n"), i, ino, da_bno); res = 1; goto out; } start = (__psint_t)&leaf->entries[i] - (__psint_t)leaf;; stop = start + sizeof(xfs_dir_leaf_entry_t); if (set_da_freemap(mp, dir_freemap, start, stop)) { do_warn( _("dir entry slot %d in block %u conflicts with used space in dir inode %" PRIu64 "\n"), i, da_bno, ino); res = 1; goto out; } /* * check if the name is legal. if so, then * check that the name and hashvalues match. * * if the name is illegal, we don't check the * hashvalue computed from it. we just make * sure that the hashvalue in the entry is * monotonically increasing wrt to the previous * entry. * * Note that we do NOT have to check the length * because the length is stored in a one-byte * unsigned int which max's out at MAXNAMELEN * making it impossible for the stored length * value to be out of range. */ memmove(fname, namest->name, entry->namelen); fname[entry->namelen] = '\0'; hashval = libxfs_da_hashname((uchar_t *) fname, entry->namelen); /* * only complain about illegal names in phase 3 (when * inode discovery is turned on). Otherwise, we'd complain * a lot during phase 4. If the name is illegal, leave * the hash value in that entry alone. */ nm_illegal = namecheck(fname, entry->namelen); if (ino_discovery && nm_illegal) { /* * junk the entry, illegal name */ if (!no_modify) { do_warn( _("illegal name \"%s\" in directory inode %" PRIu64 ", entry will be cleared\n"), fname, ino); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn( _("illegal name \"%s\" in directory inode %" PRIu64 ", entry would be cleared\n"), fname, ino); } } else if (!nm_illegal && be32_to_cpu(entry->hashval) != hashval) { /* * try resetting the hashvalue to the correct * value for the string, if the string has been * corrupted, too, that will get picked up next */ do_warn(_("\tmismatched hash value for entry \"%s\"\n"), fname); if (!no_modify) { do_warn( _("\t\tin directory inode %" PRIu64 ". resetting hash value.\n"), ino); entry->hashval = cpu_to_be32(hashval); *buf_dirty = 1; } else { do_warn( _("\t\tin directory inode %" PRIu64 ". would reset hash value.\n"), ino); } } /* * now we can mark entries with NULLFSINO's bad */ if (!no_modify && lino == NULLFSINO) { namest->name[0] = '/'; *buf_dirty = 1; } /* * regardless of whether the entry has or hasn't been * marked for deletion, the hash value ordering must * be maintained. */ if (be32_to_cpu(entry->hashval) < last_hashval) { /* * blow out the entry -- set hashval to sane value * and set the first character in the string to * the illegal value '/'. Reset the hash value * to the last hashvalue so that verify_da_path * will fix up the interior pointers correctly. * the entry will be deleted later (by routines * that need only the entry #). We keep the * inode number in the entry so we can attach * the inode to the orphanage later. */ do_warn(_("\tbad hash ordering for entry \"%s\"\n"), fname); if (!no_modify) { do_warn( _("\t\tin directory inode %" PRIu64 ". will clear entry\n"), ino); entry->hashval = cpu_to_be32(last_hashval); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn( _("\t\tin directory inode %" PRIu64 ". would clear entry\n"), ino); } } *next_hashval = last_hashval = be32_to_cpu(entry->hashval); /* * if heap data conflicts with something, * blow it out and skip the rest of the loop */ if (set_da_freemap(mp, dir_freemap, be16_to_cpu(entry->nameidx), be16_to_cpu(entry->nameidx) + sizeof(xfs_dir_leaf_name_t) + entry->namelen - 1)) { do_warn( _("name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %" PRIu64 "\n"), fname, da_bno, i, ino); if (!no_modify) { entry->namelen = 0; *buf_dirty = 1; do_warn( _("will clear entry \"%s\" (#%d) in directory inode %" PRIu64 "\n"), fname, i, ino); } else { do_warn( _("would clear entry \"%s\" (#%d)in directory inode %" PRIu64 "\n"), fname, i, ino); } continue; } /* * keep track of heap stats (first byte used, total bytes used) */ if (be16_to_cpu(entry->nameidx) < first_used) first_used = be16_to_cpu(entry->nameidx); bytes_used += entry->namelen; /* * special . or .. entry processing */ if (entry->namelen == 2 && namest->name[0] == '.' && namest->name[1] == '.') { /* * the '..' case */ if (!*dotdot) { (*dotdot)++; *parent = lino; #ifdef XR_DIR_TRACE fprintf(stderr, "process_leaf_dir_block found .. entry (parent) = %" PRIu64 "\n", lino); #endif /* * what if .. == .? legal only in * the root inode. blow out entry * and set parent to NULLFSINO otherwise. */ if (ino == lino && ino != mp->m_sb.sb_rootino) { *parent = NULLFSINO; do_warn( _("bad .. entry in dir ino %" PRIu64 ", points to self"), ino); if (!no_modify) { do_warn( _("will clear entry\n")); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn( _("would clear entry\n")); } } else if (ino != lino && ino == mp->m_sb.sb_rootino) { /* * we have to make sure that . == .. * in the root inode */ if (!no_modify) { do_warn( _("correcting .. entry in root inode %" PRIu64 ", was %" PRIu64 "\n"), ino, *parent); xfs_dir_sf_put_dirino( &ino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _("bad .. entry (%" PRIu64 ") in root inode %" PRIu64 " should be %" PRIu64 "\n"), *parent, ino, ino); } } } else { /* * can't fix the directory unless we know * which .. entry is the right one. Both * have valid inode numbers, match the hash * value and the hash values are ordered * properly or we wouldn't be here. So * since both seem equally valid, trash * this one. */ if (!no_modify) { do_warn( _("multiple .. entries in directory inode %" PRIu64 ", will clear second entry\n"), ino); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn( _("multiple .. entries in directory inode %" PRIu64 ", would clear second entry\n"), ino); } } } else if (entry->namelen == 1 && namest->name[0] == '.') { /* * the '.' case */ if (!*dot) { (*dot)++; if (lino != ino) { if (!no_modify) { do_warn( _(". in directory inode %" PRIu64 " has wrong value (%" PRIu64 "), fixing entry...\n"), ino, lino); xfs_dir_sf_put_dirino(&ino, &namest->inumber); *buf_dirty = 1; } else { do_warn( _(". in directory inode %" PRIu64 " has wrong value (%" PRIu64 ")\n"), ino, lino); } } } else { do_warn( _("multiple . entries in directory inode %" PRIu64 "\n"), ino); /* * mark entry as to be junked. */ if (!no_modify) { do_warn( _("will clear one . entry in directory inode %" PRIu64 "\n"), ino); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn( _("would clear one . entry in directory inode %" PRIu64 "\n"), ino); } } } else { /* * all the rest -- make sure only . references self */ if (lino == ino) { do_warn( _("entry \"%s\" in directory inode %" PRIu64 " points to self, "), fname, ino); if (!no_modify) { do_warn(_("will clear entry\n")); namest->name[0] = '/'; *buf_dirty = 1; } else { do_warn(_("would clear entry\n")); } } } } /* * compare top of heap values and reset as required. if the * holes flag is set, don't reset first_used unless it's * pointing to used bytes. we're being conservative here * since the block will get compacted anyhow by the kernel. */ if ((leaf->hdr.holes == 0 && first_used != be16_to_cpu(leaf->hdr.firstused)) || be16_to_cpu(leaf->hdr.firstused) > first_used) { if (!no_modify) { if (verbose) do_warn( _("- resetting first used heap value from %d to %d in block %u of dir ino %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.firstused), first_used, da_bno, ino); leaf->hdr.firstused = cpu_to_be16(first_used); *buf_dirty = 1; } else { if (verbose) do_warn( _("- would reset first used value from %d to %d in block %u of dir ino %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.firstused), first_used, da_bno, ino); } } if (bytes_used != be16_to_cpu(leaf->hdr.namebytes)) { if (!no_modify) { if (verbose) do_warn( _("- resetting namebytes cnt from %d to %d in block %u of dir inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.namebytes), bytes_used, da_bno, ino); leaf->hdr.namebytes = cpu_to_be16(bytes_used); *buf_dirty = 1; } else { if (verbose) do_warn( _("- would reset namebytes cnt from %d to %d in block %u of dir inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.namebytes), bytes_used, da_bno, ino); } } /* * If the hole flag is not set, then we know that there can * be no lost holes. If the hole flag is set, then it's ok * if the on-disk holemap doesn't describe everything as long * as what it does describe doesn't conflict with reality. */ reset_holes = 0; bholemap.lost_holes = leaf->hdr.holes; for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { bholemap.hentries[i].base = be16_to_cpu(leaf->hdr.freemap[i].base); bholemap.hentries[i].size = be16_to_cpu(leaf->hdr.freemap[i].size); } /* * Ok, now set up our own freespace list * (XFS_DIR_LEAF_MAPSIZE (3) * biggest regions) * and see if they match what's in the block */ memset(&holemap, 0, sizeof(da_hole_map_t)); process_da_freemap(mp, dir_freemap, &holemap); if (zero_len_entries) { reset_holes = 1; } else if (leaf->hdr.holes == 0) { if (holemap.lost_holes > 0) { if (verbose) do_warn( _("- found unexpected lost holes in block %u, dir inode %" PRIu64 "\n"), da_bno, ino); reset_holes = 1; } else if (compare_da_freemaps(mp, &holemap, &bholemap, XFS_DIR_LEAF_MAPSIZE, ino, da_bno)) { if (verbose) do_warn( _("- hole info non-optimal in block %u, dir inode %" PRIu64 "\n"), da_bno, ino); reset_holes = 1; } } else if (verify_da_freemap(mp, dir_freemap, &holemap, ino, da_bno)) { if (verbose) do_warn( _("- hole info incorrect in block %u, dir inode %" PRIu64 "\n"), da_bno, ino); reset_holes = 1; } if (reset_holes) { /* * have to reset block hole info */ if (verbose) { do_warn( _("- existing hole info for block %d, dir inode %" PRIu64 " (base, size) - \n"), da_bno, ino); do_warn("- \t"); for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; i++) { do_warn( "- (%d, %d) ", bholemap.hentries[i].base, bholemap.hentries[i].size); } do_warn(_("- holes flag = %d\n"), bholemap.lost_holes); } if (!no_modify) { if (verbose) do_warn( _("- compacting block %u in dir inode %" PRIu64 "\n"), da_bno, ino); new_leaf = malloc(mp->m_sb.sb_blocksize); /* * copy leaf block header */ memmove(&new_leaf->hdr, &leaf->hdr, sizeof(xfs_dir_leaf_hdr_t)); /* * reset count in case we have some zero length entries * that are being junked */ num_entries = 0; first_used = XFS_LBSIZE(mp); first_byte = (char *) new_leaf + (__psint_t) XFS_LBSIZE(mp); /* * copy entry table and pack names starting from the end * of the block */ for (i = 0, s_entry = &leaf->entries[0], d_entry = &new_leaf->entries[0]; i < be16_to_cpu(leaf->hdr.count); i++, s_entry++) { /* * skip zero-length entries */ if (s_entry->namelen == 0) continue; bytes = sizeof(xfs_dir_leaf_name_t) + s_entry->namelen - 1; if ((__psint_t) first_byte - bytes < sizeof(xfs_dir_leaf_entry_t) + (__psint_t) d_entry) { do_warn( _("not enough space in block %u of dir inode %" PRIu64 " for all entries\n"), da_bno, ino); free(new_leaf); break; } first_used -= bytes; first_byte -= bytes; d_entry->nameidx = cpu_to_be16(first_used); d_entry->hashval = s_entry->hashval; d_entry->namelen = s_entry->namelen; d_entry->pad2 = 0; memmove(first_byte, (char *)leaf + be16_to_cpu(s_entry->nameidx), bytes); num_entries++; d_entry++; } ASSERT((char *) first_byte >= (char *) d_entry); ASSERT(first_used <= XFS_LBSIZE(mp)); /* * zero space between end of table and top of heap */ memset(d_entry, 0, (__psint_t) first_byte - (__psint_t) d_entry); /* * reset header info */ if (num_entries != be16_to_cpu(new_leaf->hdr.count)) new_leaf->hdr.count = cpu_to_be16(num_entries); new_leaf->hdr.firstused = cpu_to_be16(first_used); new_leaf->hdr.holes = 0; new_leaf->hdr.pad1 = 0; new_leaf->hdr.freemap[0].base = cpu_to_be16( (__psint_t) d_entry - (__psint_t) new_leaf); new_leaf->hdr.freemap[0].size = cpu_to_be16( (__psint_t) first_byte - (__psint_t) d_entry); ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < first_used); ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) == (__psint_t) (&new_leaf->entries[0]) - (__psint_t) new_leaf + i * sizeof(xfs_dir_leaf_entry_t)); ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) < XFS_LBSIZE(mp)); ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].size) < XFS_LBSIZE(mp)); ASSERT(be16_to_cpu(new_leaf->hdr.freemap[0].base) + be16_to_cpu(new_leaf->hdr.freemap[0].size) == first_used); new_leaf->hdr.freemap[1].base = 0; new_leaf->hdr.freemap[1].size = 0; new_leaf->hdr.freemap[2].base = 0; new_leaf->hdr.freemap[2].size = 0; /* * final step, copy block back */ memmove(leaf, new_leaf, mp->m_sb.sb_blocksize); free(new_leaf); *buf_dirty = 1; } else { if (verbose) do_warn( _("- would compact block %u in dir inode %" PRIu64 "\n"), da_bno, ino); } } #if 0 if (!no_modify) { /* * now take care of deleting or marking the entries with * zero-length namelen's */ junk_zerolen_dir_leaf_entries(mp, leaf, ino, buf_dirty); } #endif out: free(dir_freemap); #ifdef XR_DIR_TRACE fprintf(stderr, "process_leaf_dir_block returns %d\n", res); #endif return res > 0 ? 1 : 0; } /* * returns 0 if the directory is ok, 1 if it has to be junked. */ static int process_leaf_dir_level(xfs_mount_t *mp, da_bt_cursor_t *da_cursor, int ino_discovery, int *repair, int *dot, int *dotdot, xfs_ino_t *parent) { xfs_dir_leafblock_t *leaf; xfs_buf_t *bp; xfs_ino_t ino; xfs_dfsbno_t dev_bno; xfs_dablk_t da_bno; xfs_dablk_t prev_bno; int res = 0; int buf_dirty = 0; xfs_daddr_t bd_addr; xfs_dahash_t current_hashval = 0; xfs_dahash_t greatest_hashval; #ifdef XR_DIR_TRACE fprintf(stderr, "process_leaf_dir_level - ino %" PRIu64 "\n", da_cursor->ino); #endif *repair = 0; da_bno = da_cursor->level[0].bno; ino = da_cursor->ino; prev_bno = 0; do { dev_bno = blkmap_get(da_cursor->blkmap, da_bno); /* * directory code uses 0 as the NULL block pointer * since 0 is the root block and no directory block * pointer can point to the root block of the btree */ ASSERT(da_bno != 0); if (dev_bno == NULLDFSBNO) { do_warn( _("can't map block %u for directory inode %" PRIu64 "\n"), da_bno, ino); goto error_out; } bd_addr = (xfs_daddr_t)XFS_FSB_TO_DADDR(mp, dev_bno); bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read file block %u (fsbno %" PRIu64 ", daddr %" PRId64 ") " "for directory inode %" PRIu64 "\n"), da_bno, dev_bno, bd_addr, ino); goto error_out; } leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); /* * check magic number for leaf directory btree block */ if (XFS_DIR_LEAF_MAGIC != be16_to_cpu(leaf->hdr.info.magic)) { do_warn( _("bad directory leaf magic # %#x for dir ino %" PRIu64"\n"), be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); goto error_out; } /* * keep track of greatest block # -- that gets * us the length of the directory */ if (da_bno > da_cursor->greatest_bno) da_cursor->greatest_bno = da_bno; buf_dirty = 0; /* * for each block, process the block, verify its path, * then get next block. update cursor values along the way */ if (process_leaf_dir_block(mp, leaf, da_bno, ino, current_hashval, ino_discovery, da_cursor->blkmap, dot, dotdot, parent, &buf_dirty, &greatest_hashval)) { libxfs_putbuf(bp); goto error_out; } /* * index can be set to hdr.count so match the * indexes of the interior blocks -- which at the * end of the block will point to 1 after the final * real entry in the block */ da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = buf_dirty; if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn( _("bad sibling back pointer for directory block %u in directory inode %" PRIu64 "\n"), da_bno, ino); libxfs_putbuf(bp); goto error_out; } prev_bno = da_bno; da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0) if (verify_da_path(mp, da_cursor, 0)) { libxfs_putbuf(bp); goto error_out; } current_hashval = greatest_hashval; ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); if (buf_dirty && !no_modify) { *repair = 1; libxfs_writebuf(bp, 0); } else libxfs_putbuf(bp); } while (da_bno != 0 && res == 0); if (verify_final_da_path(mp, da_cursor, 0)) { /* * verify the final path up (right-hand-side) if still ok */ do_warn(_("bad hash path in directory %" PRIu64 "\n"), da_cursor->ino); goto error_out; } #ifdef XR_DIR_TRACE fprintf(stderr, "process_leaf_dir_level returns %d (%s)\n", res, ((res) ? "bad" : "ok")); #endif /* * redundant but just for testing */ release_da_cursor(mp, da_cursor, 0); return(res); error_out: /* * release all buffers holding interior btree blocks */ err_release_da_cursor(mp, da_cursor, 0); return(1); } /* * a node directory is a true btree directory -- where the directory * has gotten big enough that it is represented as a non-trivial (e.g. * has more than just a root block) btree. * * Note that if we run into any problems, we trash the * directory. Even if it's the root directory, * we'll be able to traverse all the disconnected * subtrees later (phase 6). * * one day, if we actually fix things, we'll set repair to 1 to * indicate that we have or that we should. * * dirname can be set to NULL if the name is unknown (or to * the string representation of the inode) * * returns 0 if things are ok, 1 if bad (directory needs to be junked) */ static int process_node_dir( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, blkmap_t *blkmap, int *dot, int *dotdot, xfs_ino_t *parent, /* out - parent ino # or NULLFSINO */ char *dirname, int *repair) { xfs_dablk_t bno; int error = 0; da_bt_cursor_t da_cursor; #ifdef XR_DIR_TRACE fprintf(stderr, "process_node_dir - ino %" PRIu64 "\n", ino); #endif *repair = *dot = *dotdot = 0; *parent = NULLFSINO; /* * try again -- traverse down left-side of tree until we hit * the left-most leaf block setting up the btree cursor along * the way. Then walk the leaf blocks left-to-right, calling * a parent-verification routine each time we traverse a block. */ memset(&da_cursor, 0, sizeof(da_bt_cursor_t)); da_cursor.active = 0; da_cursor.type = 0; da_cursor.ino = ino; da_cursor.dip = dip; da_cursor.greatest_bno = 0; da_cursor.blkmap = blkmap; /* * now process interior node */ error = traverse_int_dablock(mp, &da_cursor, &bno, XFS_DATA_FORK); if (error == 0) return(1); /* * now pass cursor and bno into leaf-block processing routine * the leaf dir level routine checks the interior paths * up to the root including the final right-most path. */ error = process_leaf_dir_level(mp, &da_cursor, ino_discovery, repair, dot, dotdot, parent); if (error) return(1); /* * sanity check inode size */ if (be64_to_cpu(dip->di_size) < (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize) { if ((xfs_fsize_t) da_cursor.greatest_bno * mp->m_sb.sb_blocksize > UINT_MAX) { do_warn( _("out of range internal directory block numbers (inode %" PRIu64 ")\n"), ino); return(1); } do_warn( _("setting directory inode (%" PRIu64 ") size to %" PRIu64 " bytes, was %" PRId64 " bytes\n"), ino, (xfs_dfiloff_t) (da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize, (__int64_t)be64_to_cpu(dip->di_size)); dip->di_size = cpu_to_be64((da_cursor.greatest_bno + 1) * mp->m_sb.sb_blocksize); } return(0); } /* * a leaf directory is one where the directory is too big for * the inode data fork but is small enough to fit into one * directory btree block (filesystem block) outside the inode * * returns NULLFSINO if the directory is cannot be salvaged * and the .. ino if things are ok (even if the directory had * to be altered to make it ok). * * dirname can be set to NULL if the name is unknown (or to * the string representation of the inode) * * returns 0 if things are ok, 1 if bad (directory needs to be junked) */ static int process_leaf_dir( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, blkmap_t *blkmap, int *dot, /* out - 1 if there is a dot, else 0 */ int *dotdot, /* out - 1 if there's a dotdot, else 0 */ xfs_ino_t *parent, /* out - parent ino # or NULLFSINO */ char *dirname, /* in - directory pathname */ int *repair) /* out - 1 if something was fixed */ { xfs_dir_leafblock_t *leaf; xfs_dahash_t next_hashval; xfs_dfsbno_t bno; xfs_buf_t *bp; int buf_dirty = 0; #ifdef XR_DIR_TRACE fprintf(stderr, "process_leaf_dir - ino %" PRIu64 "\n", ino); #endif *repair = *dot = *dotdot = 0; *parent = NULLFSINO; bno = blkmap_get(blkmap, 0); if (bno == NULLDFSBNO) { do_warn(_("block 0 for directory inode %" PRIu64 " is missing\n"), ino); return(1); } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn(_("can't read block 0 for directory inode %" PRIu64 "\n"), ino); return(1); } /* * verify leaf block */ leaf = (xfs_dir_leafblock_t *)XFS_BUF_PTR(bp); /* * check magic number for leaf directory btree block */ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { do_warn(_("bad directory leaf magic # %#x for dir ino %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); return(1); } if (process_leaf_dir_block(mp, leaf, 0, ino, 0, ino_discovery, blkmap, dot, dotdot, parent, &buf_dirty, &next_hashval)) { /* * the block is bad. lose the directory. * XXX - later, we should try and just lose * the block without losing the entire directory */ ASSERT(*dotdot == 0 || (*dotdot == 1 && *parent != NULLFSINO)); libxfs_putbuf(bp); return(1); } /* * check sibling pointers in leaf block (above doesn't do it) */ if (leaf->hdr.info.forw || leaf->hdr.info.back) { if (!no_modify) { do_warn(_("clearing forw/back pointers for " "directory inode %" PRIu64 "\n"), ino); buf_dirty = 1; leaf->hdr.info.forw = 0; leaf->hdr.info.back = 0; } else { do_warn(_("would clear forw/back pointers for " "directory inode %" PRIu64 "\n"), ino); } } ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify)); if (buf_dirty && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); return(0); } /* * returns 1 if things are bad (directory needs to be junked) * and 0 if things are ok. If ino_discovery is 1, add unknown * inodes to uncertain inode list. */ int process_dir( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dino_dirty, char *dirname, xfs_ino_t *parent, blkmap_t *blkmap) { int dot; int dotdot; int repair = 0; int res = 0; *parent = NULLFSINO; dot = dotdot = 0; /* * branch off depending on the type of inode. This routine * is only called ONCE so all the subordinate routines will * fix '.' and junk '..' if they're bogus. */ if (be64_to_cpu(dip->di_size) <= XFS_DFORK_DSIZE(dip, mp)) { dot = 1; dotdot = 1; if (process_shortform_dir(mp, ino, dip, ino_discovery, dino_dirty, parent, dirname, &repair)) res = 1; } else if (be64_to_cpu(dip->di_size) <= XFS_LBSIZE(mp)) { if (process_leaf_dir(mp, ino, dip, ino_discovery, dino_dirty, blkmap, &dot, &dotdot, parent, dirname, &repair)) res = 1; } else { if (process_node_dir(mp, ino, dip, ino_discovery, blkmap, &dot, &dotdot, parent, dirname, &repair)) res = 1; } /* * bad . entries in all directories will be fixed up in phase 6 */ if (dot == 0) do_warn(_("no . entry for directory %" PRIu64 "\n"), ino); /* * shortform dirs always have a .. entry. .. for all longform * directories will get fixed in phase 6. .. for other shortform * dirs also get fixed there. .. for a shortform root was * fixed in place since we know what it should be */ if (dotdot == 0 && ino != mp->m_sb.sb_rootino) { do_warn(_("no .. entry for directory %" PRIu64 "\n"), ino); } else if (dotdot == 0 && ino == mp->m_sb.sb_rootino) { do_warn(_("no .. entry for root directory %" PRIu64 "\n"), ino); need_root_dotdot = 1; } #ifdef XR_DIR_TRACE fprintf(stderr, "(process_dir), parent of %" PRIu64 " is %" PRIu64 "\n", ino, parent); #endif return(res); } xfsprogs-3.1.9ubuntu2/repair/rt.c0000664000000000000000000001435411650373061013700 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "dinode.h" #include "protos.h" #include "err_protos.h" #include "rt.h" #define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */ void rtinit(xfs_mount_t *mp) { if (mp->m_sb.sb_rblocks == 0) return; /* * realtime init -- blockmap initialization is * handled by incore_init() */ /* sumfile = calloc(mp->m_rsumsize, 1); */ if ((btmcompute = calloc(mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize, 1)) == NULL) do_error( _("couldn't allocate memory for incore realtime bitmap.\n")); if ((sumcompute = calloc(mp->m_rsumsize, 1)) == NULL) do_error( _("couldn't allocate memory for incore realtime summary info.\n")); } /* * generate the real-time bitmap and summary info based on the * incore realtime extent map. */ int generate_rtinfo(xfs_mount_t *mp, xfs_rtword_t *words, xfs_suminfo_t *sumcompute) { xfs_drtbno_t extno; xfs_drtbno_t start_ext; int bitsperblock; int bmbno; xfs_rtword_t freebit; xfs_rtword_t bits; int start_bmbno; int i; int offs; int log; int len; int in_extent; ASSERT(mp->m_rbmip == NULL); bitsperblock = mp->m_sb.sb_blocksize * NBBY; extno = start_ext = 0; bmbno = in_extent = start_bmbno = 0; /* * slower but simple, don't play around with trying to set * things one word at a time, just set bit as required. * Have to * track start and end (size) of each range of * free extents to set the summary info properly. */ while (extno < mp->m_sb.sb_rextents) { freebit = 1; *words = 0; bits = 0; for (i = 0; i < sizeof(xfs_rtword_t) * NBBY && extno < mp->m_sb.sb_rextents; i++, extno++) { if (get_rtbmap(extno) == XR_E_FREE) { sb_frextents++; bits |= freebit; if (in_extent == 0) { start_ext = extno; start_bmbno = bmbno; in_extent = 1; } } else if (in_extent == 1) { len = (int) (extno - start_ext); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; in_extent = 0; } freebit <<= 1; } *words = bits; words++; if (extno % bitsperblock == 0) bmbno++; } if (in_extent == 1) { len = (int) (extno - start_ext); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; } return(0); } #if 0 /* * returns 1 if bad, 0 if good */ int check_summary(xfs_mount_t *mp) { xfs_drfsbno_t bno; xfs_suminfo_t *csp; xfs_suminfo_t *fsp; int log; int error = 0; error = 0; csp = sumcompute; fsp = sumfile; for (log = 0; log < mp->m_rsumlevels; log++) { for (bno = 0; bno < mp->m_sb.sb_rbmblocks; bno++, csp++, fsp++) { if (*csp != *fsp) { do_warn( _("rt summary mismatch, size %d block %llu, file: %d, computed: %d\n"), log, bno, *fsp, *csp); error = 1; } } } return(error); } /* * examine the real-time bitmap file and compute summary * info off it. Should probably be changed to compute * the summary information off the incore computed bitmap * instead of the realtime bitmap file */ void process_rtbitmap(xfs_mount_t *mp, xfs_dinode_t *dino, blkmap_t *blkmap) { int error; int bit; int bitsperblock; int bmbno; int end_bmbno; xfs_dfsbno_t bno; xfs_buf_t *bp; xfs_drtbno_t extno; int i; int len; int log; int offs; int prevbit; int start_bmbno; int start_bit; xfs_rtword_t *words; ASSERT(mp->m_rbmip == NULL); bitsperblock = mp->m_sb.sb_blocksize * NBBY; prevbit = 0; extno = 0; error = 0; end_bmbno = howmany(be64_to_cpu(dino->di_size), mp->m_sb.sb_blocksize); for (bmbno = 0; bmbno < end_bmbno; bmbno++) { bno = blkmap_get(blkmap, bmbno); if (bno == NULLDFSBNO) { do_warn(_("can't find block %d for rtbitmap inode\n"), bmbno); error = 1; continue; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1)); if (!bp) { do_warn(_("can't read block %d for rtbitmap inode\n"), bmbno); error = 1; continue; } words = (xfs_rtword_t *)bp->b_un.b_addr; for (bit = 0; bit < bitsperblock && extno < mp->m_sb.sb_rextents; bit++, extno++) { if (xfs_isset(words, bit)) { set_rtbmap(extno, XR_E_FREE); sb_frextents++; if (prevbit == 0) { start_bmbno = bmbno; start_bit = bit; prevbit = 1; } } else if (prevbit == 1) { len = (bmbno - start_bmbno) * bitsperblock + (bit - start_bit); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; prevbit = 0; } } libxfs_putbuf(bp); if (extno == mp->m_sb.sb_rextents) break; } if (prevbit == 1) { len = (bmbno - start_bmbno) * bitsperblock + (bit - start_bit); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; } } /* * copy the real-time summary file data into memory */ void process_rtsummary(xfs_mount_t *mp, xfs_dinode_t *dino, blkmap_t *blkmap) { xfs_fsblock_t bno; xfs_buf_t *bp; char *bytes; int sumbno; for (sumbno = 0; sumbno < blkmap->count; sumbno++) { bno = blkmap_get(blkmap, sumbno); if (bno == NULLDFSBNO) { do_warn(_("block %d for rtsummary inode is missing\n"), sumbno); error++; continue; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1)); if (!bp) { do_warn(_("can't read block %d for rtsummary inode\n"), sumbno); error++; continue; } bytes = bp->b_un.b_addr; memmove((char *)sumfile + sumbno * mp->m_sb.sb_blocksize, bytes, mp->m_sb.sb_blocksize); libxfs_putbuf(bp); } } #endif xfsprogs-3.1.9ubuntu2/repair/prefetch.h0000664000000000000000000000245311307015331015045 0ustar #ifndef _XFS_REPAIR_PREFETCH_H #define _XFS_REPAIR_PREFETCH_H #include #include "incore.h" extern int do_prefetch; #define PF_THREAD_COUNT 4 typedef struct prefetch_args { pthread_mutex_t lock; pthread_t queuing_thread; pthread_t io_threads[PF_THREAD_COUNT]; struct btree_root *io_queue; pthread_cond_t start_reading; pthread_cond_t start_processing; int agno; int dirs_only; volatile int can_start_reading; volatile int can_start_processing; volatile int prefetch_done; volatile int queuing_done; volatile int inode_bufs_queued; volatile xfs_fsblock_t last_bno_read; sem_t ra_count; struct prefetch_args *next_args; } prefetch_args_t; void init_prefetch( xfs_mount_t *pmp); prefetch_args_t * start_inode_prefetch( xfs_agnumber_t agno, int dirs_only, prefetch_args_t *prev_args); void wait_for_inode_prefetch( prefetch_args_t *args); void cleanup_inode_prefetch( prefetch_args_t *args); #ifdef XR_PF_TRACE void pftrace_init(void); void pftrace_done(void); #define pftrace(msg...) _pftrace(__FUNCTION__, ## msg) void _pftrace(const char *, const char *, ...); #else static inline void pftrace_init(void) { }; static inline void pftrace_done(void) { }; static inline void pftrace(const char *msg, ...) { }; #endif #endif /* _XFS_REPAIR_PREFETCH_H */ xfsprogs-3.1.9ubuntu2/repair/dir.h0000664000000000000000000000650012062210562014022 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_DIR_H #define _XR_DIR_H struct blkmap; typedef unsigned char da_freemap_t; /* * the cursor gets passed up and down the da btree processing * routines. The interior block processing routines use the * cursor to determine if the pointers to and from the preceding * and succeeding sibling blocks are ok and whether the values in * the current block are consistent with the entries in the parent * nodes. When a block is traversed, a parent-verification routine * is called to verify if the next logical entry in the next level up * is consistent with the greatest hashval in the next block of the * current level. The verification routine is itself recursive and * calls itself if it has to traverse an interior block to get * the next logical entry. The routine recurses upwards through * the tree until it finds a block where it can simply step to * the next entry. The hashval in that entry should be equal to * the hashval being passed to it (the greatest hashval in the block * that the entry points to). If that isn't true, then the tree * is blown and we need to trash it, salvage and trash it, or fix it. * Currently, we just trash it. */ typedef struct da_level_state { xfs_buf_t *bp; /* block bp */ #ifdef XR_DIR_TRACE xfs_da_intnode_t *n; /* bp data */ #endif xfs_dablk_t bno; /* file block number */ xfs_dahash_t hashval; /* last verified hashval */ int index; /* current index in block */ int dirty; /* is buffer dirty ? (1 == yes) */ } da_level_state_t; typedef struct da_bt_cursor { int active; /* highest level in tree (# levels-1) */ int type; /* 0 if dir, 1 if attr */ xfs_ino_t ino; xfs_dablk_t greatest_bno; xfs_dinode_t *dip; da_level_state_t level[XFS_DA_NODE_MAXDEPTH]; struct blkmap *blkmap; } da_bt_cursor_t; /* ROUTINES */ void err_release_da_cursor( xfs_mount_t *mp, da_bt_cursor_t *cursor, int prev_level); da_freemap_t * alloc_da_freemap( xfs_mount_t *mp); int namecheck( char *name, int length); int process_dir( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, int ino_discovery, int *dirty, char *dirname, xfs_ino_t *parent, struct blkmap *blkmap); void release_da_cursor( xfs_mount_t *mp, da_bt_cursor_t *cursor, int prev_level); int set_da_freemap( xfs_mount_t *mp, da_freemap_t *map, int start, int stop); int traverse_int_dablock( xfs_mount_t *mp, da_bt_cursor_t *da_cursor, xfs_dablk_t *rbno, int whichfork); int verify_da_path( xfs_mount_t *mp, da_bt_cursor_t *cursor, const int p_level); int verify_final_da_path( xfs_mount_t *mp, da_bt_cursor_t *cursor, const int p_level); #endif /* _XR_DIR_H */ xfsprogs-3.1.9ubuntu2/repair/protos.h0000664000000000000000000000320712062210562014573 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ void xfs_init(libxfs_init_t *args); int verify_sb(xfs_sb_t *sb, int is_primary_sb); int verify_set_primary_sb(xfs_sb_t *root_sb, int sb_index, int *sb_modified); int get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno); void write_primary_sb(xfs_sb_t *sbp, int size); int find_secondary_sb(xfs_sb_t *sb); struct fs_geometry; void get_sb_geometry(struct fs_geometry *geo, xfs_sb_t *sbp); char *alloc_ag_buf(int size); void print_inode_list(xfs_agnumber_t i); char *err_string(int err_code); void thread_init(void); void phase1(struct xfs_mount *); void phase2(struct xfs_mount *, int); void phase3(struct xfs_mount *); void phase4(struct xfs_mount *); void phase5(struct xfs_mount *); void phase6(struct xfs_mount *); void phase7(struct xfs_mount *); int verify_set_agheader(struct xfs_mount *, struct xfs_buf *, struct xfs_sb *, struct xfs_agf *, struct xfs_agi *, xfs_agnumber_t); xfsprogs-3.1.9ubuntu2/repair/bmap.c0000664000000000000000000001755612062210562014173 0ustar /* * Copyright (c) 2000-2001,2005,2008 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "err_protos.h" #include "bmap.h" /* * Track the logical to physical block mapping for inodes. * * Repair only processes one inode at a given time per thread, and the * block map does not have to outlive the processing of a single inode. * * The combination of those factors means we can use pthreads thread-local * storage to store the block map, and we can re-use the allocation over * and over again. */ pthread_key_t dblkmap_key; pthread_key_t ablkmap_key; blkmap_t * blkmap_alloc( xfs_extnum_t nex, int whichfork) { pthread_key_t key; blkmap_t *blkmap; ASSERT(whichfork == XFS_DATA_FORK || whichfork == XFS_ATTR_FORK); if (nex < 1) nex = 1; if (nex > BLKMAP_NEXTS_MAX) { #if (BITS_PER_LONG == 32) do_warn( _("Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" "If this is not a corruption, then you will need a 64 bit system\n" "to repair this filesystem.\n"), nex); #endif return NULL; } key = whichfork ? ablkmap_key : dblkmap_key; blkmap = pthread_getspecific(key); if (!blkmap || blkmap->naexts < nex) { blkmap = realloc(blkmap, BLKMAP_SIZE(nex)); if (!blkmap) { do_warn(_("malloc failed in blkmap_alloc (%zu bytes)\n"), BLKMAP_SIZE(nex)); return NULL; } pthread_setspecific(key, blkmap); blkmap->naexts = nex; } blkmap->nexts = 0; return blkmap; } /* * Free a block map. * * If the map is a large, uncommon size (say for hundreds of thousands of * extents) then free it to release the memory. This prevents us from pinning * large tracts of memory due to corrupted fork values or one-off fragmented * files. Otherwise we have nothing to do but keep the memory around for the * next inode */ void blkmap_free( blkmap_t *blkmap) { if (!blkmap) return; /* consider more than 100k extents rare */ if (blkmap->naexts < 100 * 1024) return; if (blkmap == pthread_getspecific(dblkmap_key)) pthread_setspecific(dblkmap_key, NULL); else pthread_setspecific(ablkmap_key, NULL); free(blkmap); } /* * Get one entry from a block map. */ xfs_dfsbno_t blkmap_get( blkmap_t *blkmap, xfs_dfiloff_t o) { bmap_ext_t *ext = blkmap->exts; int i; for (i = 0; i < blkmap->nexts; i++, ext++) { if (o >= ext->startoff && o < ext->startoff + ext->blockcount) return ext->startblock + (o - ext->startoff); } return NULLDFSBNO; } /* * Get a chunk of entries from a block map - only used for reading dirv2 blocks */ int blkmap_getn( blkmap_t *blkmap, xfs_dfiloff_t o, xfs_dfilblks_t nb, bmap_ext_t **bmpp, bmap_ext_t *bmpp_single) { bmap_ext_t *bmp = NULL; bmap_ext_t *ext; int i; int nex; if (nb == 1) { /* * in the common case, when mp->m_dirblkfsbs == 1, * avoid additional malloc/free overhead */ bmpp_single->startblock = blkmap_get(blkmap, o); goto single_ext; } ext = blkmap->exts; nex = 0; for (i = 0; i < blkmap->nexts; i++, ext++) { if (ext->startoff >= o + nb) break; if (ext->startoff + ext->blockcount <= o) continue; /* * if all the requested blocks are in one extent (also common), * use the bmpp_single option as well */ if (!bmp && o >= ext->startoff && o + nb <= ext->startoff + ext->blockcount) { bmpp_single->startblock = ext->startblock + (o - ext->startoff); goto single_ext; } /* * rare case - multiple extents for a single dir block */ if (!bmp) bmp = malloc(nb * sizeof(bmap_ext_t)); if (!bmp) do_error(_("blkmap_getn malloc failed (%" PRIu64 " bytes)\n"), nb * sizeof(bmap_ext_t)); bmp[nex].startblock = ext->startblock + (o - ext->startoff); bmp[nex].blockcount = MIN(nb, ext->blockcount - (bmp[nex].startblock - ext->startblock)); o += bmp[nex].blockcount; nb -= bmp[nex].blockcount; nex++; } *bmpp = bmp; return nex; single_ext: bmpp_single->blockcount = nb; bmpp_single->startoff = 0; /* not even used by caller! */ *bmpp = bmpp_single; return (bmpp_single->startblock != NULLDFSBNO) ? 1 : 0; } /* * Return the last offset in a block map. */ xfs_dfiloff_t blkmap_last_off( blkmap_t *blkmap) { bmap_ext_t *ext; if (!blkmap->nexts) return NULLDFILOFF; ext = blkmap->exts + blkmap->nexts - 1; return ext->startoff + ext->blockcount; } /** * blkmap_next_off - Return next logical block offset in a block map. * @blkmap: blockmap to use * @o: current file logical block number * @t: current extent index into blockmap (in/out) * * Given a logical block offset in a file, return the next mapped logical offset * The map index "t" tracks the current extent number in the block map, and * is updated automatically if the returned offset resides within the next * mapped extent. * * If the blockmap contains no extents, or no more logical offsets are mapped, * or the extent index exceeds the number of extents in the map, * return NULLDFILOFF. * * If offset o is beyond extent index t, the first offset in the next extent * after extent t will be returned. * * Intended to be called starting with offset 0, index 0, and iterated. */ xfs_dfiloff_t blkmap_next_off( blkmap_t *blkmap, xfs_dfiloff_t o, int *t) { bmap_ext_t *ext; if (!blkmap->nexts) return NULLDFILOFF; if (o == NULLDFILOFF) { *t = 0; return blkmap->exts[0].startoff; } if (*t >= blkmap->nexts) return NULLDFILOFF; ext = blkmap->exts + *t; if (o < ext->startoff + ext->blockcount - 1) return o + 1; if (*t == blkmap->nexts - 1) return NULLDFILOFF; (*t)++; return ext[1].startoff; } /* * Make a block map larger. */ static blkmap_t * blkmap_grow( blkmap_t *blkmap) { pthread_key_t key = dblkmap_key; blkmap_t *new_blkmap; int new_naexts = blkmap->naexts + 4; if (pthread_getspecific(key) != blkmap) { key = ablkmap_key; ASSERT(pthread_getspecific(key) == blkmap); } if (new_naexts > BLKMAP_NEXTS_MAX) { #if (BITS_PER_LONG == 32) do_error( _("Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" "You need a 64 bit system to repair this filesystem.\n"), new_naexts); #endif return NULL; } if (new_naexts <= 0) { do_error( _("Number of extents requested in blkmap_grow (%d) overflowed the\n" "maximum number of supported extents (%d).\n"), new_naexts, BLKMAP_NEXTS_MAX); return NULL; } new_blkmap = realloc(blkmap, BLKMAP_SIZE(new_naexts)); if (!new_blkmap) { do_error(_("realloc failed in blkmap_grow\n")); return NULL; } new_blkmap->naexts = new_naexts; pthread_setspecific(key, new_blkmap); return new_blkmap; } /* * Set an extent into a block map. * * If this function fails, it leaves the blkmapp untouched so the caller can * handle the error and free the blkmap appropriately. */ int blkmap_set_ext( blkmap_t **blkmapp, xfs_dfiloff_t o, xfs_dfsbno_t b, xfs_dfilblks_t c) { blkmap_t *blkmap = *blkmapp; xfs_extnum_t i; if (blkmap->nexts == blkmap->naexts) { blkmap = blkmap_grow(blkmap); if (!blkmap) return ENOMEM; *blkmapp = blkmap; } ASSERT(blkmap->nexts < blkmap->naexts); for (i = 0; i < blkmap->nexts; i++) { if (blkmap->exts[i].startoff > o) { memmove(blkmap->exts + i + 1, blkmap->exts + i, sizeof(bmap_ext_t) * (blkmap->nexts - i)); break; } } blkmap->exts[i].startoff = o; blkmap->exts[i].startblock = b; blkmap->exts[i].blockcount = c; blkmap->nexts++; return 0; } xfsprogs-3.1.9ubuntu2/repair/dinode.c0000664000000000000000000021647212062210562014514 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dir.h" #include "dir2.h" #include "dinode.h" #include "scan.h" #include "versions.h" #include "attr_repair.h" #include "bmap.h" #include "threads.h" /* * inode clearing routines */ static int clear_dinode_attr(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num) { ASSERT(dino->di_forkoff != 0); if (!no_modify) fprintf(stderr, _("clearing inode %" PRIu64 " attributes\n"), ino_num); else fprintf(stderr, _("would have cleared inode %" PRIu64 " attributes\n"), ino_num); if (be16_to_cpu(dino->di_anextents) != 0) { if (no_modify) return(1); dino->di_anextents = cpu_to_be16(0); } if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) { if (no_modify) return(1); dino->di_aformat = XFS_DINODE_FMT_EXTENTS; } /* get rid of the fork by clearing forkoff */ /* Originally, when the attr repair code was added, the fork was cleared * by turning it into shortform status. This meant clearing the * hdr.totsize/count fields and also changing aformat to LOCAL * (vs EXTENTS). Over various fixes, the aformat and forkoff have * been updated to not show an attribute fork at all, however. * It could be possible that resetting totsize/count are not needed, * but just to be safe, leave it in for now. */ if (!no_modify) { xfs_attr_shortform_t *asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dino); asf->hdr.totsize = cpu_to_be16(sizeof(xfs_attr_sf_hdr_t)); asf->hdr.count = 0; dino->di_forkoff = 0; /* got to do this after asf is set */ } /* * always returns 1 since the fork gets zapped */ return(1); } static int clear_dinode_core(xfs_dinode_t *dinoc, xfs_ino_t ino_num) { int dirty = 0; if (be16_to_cpu(dinoc->di_magic) != XFS_DINODE_MAGIC) { dirty = 1; if (no_modify) return(1); dinoc->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); } if (!XFS_DINODE_GOOD_VERSION(dinoc->di_version) || (!fs_inode_nlink && dinoc->di_version > 1)) { dirty = 1; if (no_modify) return(1); dinoc->di_version = (fs_inode_nlink) ? 2 : 1; } if (be16_to_cpu(dinoc->di_mode) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_mode = 0; } if (be16_to_cpu(dinoc->di_flags) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_flags = 0; } if (be32_to_cpu(dinoc->di_dmevmask) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_dmevmask = 0; } if (dinoc->di_forkoff != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_forkoff = 0; } if (dinoc->di_format != XFS_DINODE_FMT_EXTENTS) { dirty = 1; if (no_modify) return(1); dinoc->di_format = XFS_DINODE_FMT_EXTENTS; } if (dinoc->di_aformat != XFS_DINODE_FMT_EXTENTS) { dirty = 1; if (no_modify) return(1); dinoc->di_aformat = XFS_DINODE_FMT_EXTENTS; } if (be64_to_cpu(dinoc->di_size) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_size = 0; } if (be64_to_cpu(dinoc->di_nblocks) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_nblocks = 0; } if (be16_to_cpu(dinoc->di_onlink) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_onlink = 0; } if (be32_to_cpu(dinoc->di_nextents) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_nextents = 0; } if (be16_to_cpu(dinoc->di_anextents) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_anextents = 0; } if (dinoc->di_version > 1 && be32_to_cpu(dinoc->di_nlink) != 0) { dirty = 1; if (no_modify) return(1); dinoc->di_nlink = 0; } return(dirty); } static int clear_dinode_unlinked(xfs_mount_t *mp, xfs_dinode_t *dino) { if (be32_to_cpu(dino->di_next_unlinked) != NULLAGINO) { if (!no_modify) dino->di_next_unlinked = cpu_to_be32(NULLAGINO); return(1); } return(0); } /* * this clears the unlinked list too so it should not be called * until after the agi unlinked lists are walked in phase 3. * returns > zero if the inode has been altered while being cleared */ static int clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num) { int dirty; dirty = clear_dinode_core(dino, ino_num); dirty += clear_dinode_unlinked(mp, dino); /* and clear the forks */ if (dirty && !no_modify) memset(XFS_DFORK_DPTR(dino), 0, XFS_LITINO(mp)); return(dirty); } /* * misc. inode-related utility routines */ /* * verify_ag_bno is heavily used. In the common case, it * performs just two number of compares * Returns 1 for bad ag/bno pair or 0 if it's valid. */ static __inline int verify_ag_bno(xfs_sb_t *sbp, xfs_agnumber_t agno, xfs_agblock_t agbno) { if (agno < (sbp->sb_agcount - 1)) return (agbno >= sbp->sb_agblocks); if (agno == (sbp->sb_agcount - 1)) return (agbno >= (sbp->sb_dblocks - ((xfs_drfsbno_t)(sbp->sb_agcount - 1) * sbp->sb_agblocks))); return 1; } /* * returns 0 if inode number is valid, 1 if bogus */ int verify_inum(xfs_mount_t *mp, xfs_ino_t ino) { xfs_agnumber_t agno; xfs_agino_t agino; xfs_agblock_t agbno; xfs_sb_t *sbp = &mp->m_sb;; /* range check ag #, ag block. range-checking offset is pointless */ agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); if (agbno == 0) return 1; if (ino == 0 || ino == NULLFSINO) return(1); if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) return(1); return verify_ag_bno(sbp, agno, agbno); } /* * have a separate routine to ensure that we don't accidentally * lose illegally set bits in the agino by turning it into an FSINO * to feed to the above routine */ int verify_aginum(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino) { xfs_agblock_t agbno; xfs_sb_t *sbp = &mp->m_sb;; /* range check ag #, ag block. range-checking offset is pointless */ if (agino == 0 || agino == NULLAGINO) return(1); /* * agino's can't be too close to NULLAGINO because the min blocksize * is 9 bits and at most 1 bit of that gets used for the inode offset * so if the agino gets shifted by the # of offset bits and compared * to the legal agbno values, a bogus agino will be too large. there * will be extra bits set at the top that shouldn't be set. */ agbno = XFS_AGINO_TO_AGBNO(mp, agino); if (agbno == 0) return 1; return verify_ag_bno(sbp, agno, agbno); } /* * return 1 if block number is good, 0 if out of range */ int verify_dfsbno(xfs_mount_t *mp, xfs_dfsbno_t fsbno) { xfs_agnumber_t agno; xfs_agblock_t agbno; xfs_sb_t *sbp = &mp->m_sb;; /* range check ag #, ag block. range-checking offset is pointless */ agno = XFS_FSB_TO_AGNO(mp, fsbno); agbno = XFS_FSB_TO_AGBNO(mp, fsbno); return verify_ag_bno(sbp, agno, agbno) == 0; } #define XR_DFSBNORANGE_VALID 0 #define XR_DFSBNORANGE_BADSTART 1 #define XR_DFSBNORANGE_BADEND 2 #define XR_DFSBNORANGE_OVERFLOW 3 static __inline int verify_dfsbno_range(xfs_mount_t *mp, xfs_dfsbno_t fsbno, xfs_dfilblks_t count) { xfs_agnumber_t agno; xfs_agblock_t agbno; xfs_sb_t *sbp = &mp->m_sb;; /* the start and end blocks better be in the same allocation group */ agno = XFS_FSB_TO_AGNO(mp, fsbno); if (agno != XFS_FSB_TO_AGNO(mp, fsbno + count - 1)) { return XR_DFSBNORANGE_OVERFLOW; } agbno = XFS_FSB_TO_AGBNO(mp, fsbno); if (verify_ag_bno(sbp, agno, agbno)) { return XR_DFSBNORANGE_BADSTART; } agbno = XFS_FSB_TO_AGBNO(mp, fsbno + count - 1); if (verify_ag_bno(sbp, agno, agbno)) { return XR_DFSBNORANGE_BADEND; } return (XR_DFSBNORANGE_VALID); } int verify_agbno(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno) { xfs_sb_t *sbp = &mp->m_sb;; /* range check ag #, ag block. range-checking offset is pointless */ return verify_ag_bno(sbp, agno, agbno) == 0; } static int process_rt_rec( xfs_mount_t *mp, xfs_bmbt_irec_t *irec, xfs_ino_t ino, xfs_drfsbno_t *tot, int check_dups) { xfs_dfsbno_t b; xfs_drtbno_t ext; int state; int pwe; /* partially-written extent */ /* * check numeric validity of the extent */ if (irec->br_startblock >= mp->m_sb.sb_rblocks) { do_warn( _("inode %" PRIu64 " - bad rt extent start block number %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec->br_startblock, irec->br_startoff); return 1; } if (irec->br_startblock + irec->br_blockcount - 1 >= mp->m_sb.sb_rblocks) { do_warn( _("inode %" PRIu64 " - bad rt extent last block number %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec->br_startblock + irec->br_blockcount - 1, irec->br_startoff); return 1; } if (irec->br_startblock + irec->br_blockcount - 1 < irec->br_startblock) { do_warn( _("inode %" PRIu64 " - bad rt extent overflows - start %" PRIu64 ", " "end %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec->br_startblock, irec->br_startblock + irec->br_blockcount - 1, irec->br_startoff); return 1; } /* * verify that the blocks listed in the record * are multiples of an extent */ if (xfs_sb_version_hasextflgbit(&mp->m_sb) == 0 && (irec->br_startblock % mp->m_sb.sb_rextsize != 0 || irec->br_blockcount % mp->m_sb.sb_rextsize != 0)) { do_warn( _("malformed rt inode extent [%" PRIu64 " %" PRIu64 "] (fs rtext size = %u)\n"), irec->br_startblock, irec->br_blockcount, mp->m_sb.sb_rextsize); return 1; } /* * set the appropriate number of extents * this iterates block by block, this can be optimised using extents */ for (b = irec->br_startblock; b < irec->br_startblock + irec->br_blockcount; b += mp->m_sb.sb_rextsize) { ext = (xfs_drtbno_t) b / mp->m_sb.sb_rextsize; pwe = xfs_sb_version_hasextflgbit(&mp->m_sb) && irec->br_state == XFS_EXT_UNWRITTEN && (b % mp->m_sb.sb_rextsize != 0); if (check_dups == 1) { if (search_rt_dup_extent(mp, ext) && !pwe) { do_warn( _("data fork in rt ino %" PRIu64 " claims dup rt extent," "off - %" PRIu64 ", start - %" PRIu64 ", count %" PRIu64 "\n"), ino, irec->br_startoff, irec->br_startblock, irec->br_blockcount); return 1; } continue; } state = get_rtbmap(ext); switch (state) { case XR_E_FREE: case XR_E_UNKNOWN: set_rtbmap(ext, XR_E_INUSE); break; case XR_E_BAD_STATE: do_error( _("bad state in rt block map %" PRIu64 "\n"), ext); case XR_E_FS_MAP: case XR_E_INO: case XR_E_INUSE_FS: do_error( _("data fork in rt inode %" PRIu64 " found metadata block %" PRIu64 " in rt bmap\n"), ino, ext); case XR_E_INUSE: if (pwe) break; case XR_E_MULT: set_rtbmap(ext, XR_E_MULT); do_warn( _("data fork in rt inode %" PRIu64 " claims used rt block %" PRIu64 "\n"), ino, ext); return 1; case XR_E_FREE1: default: do_error( _("illegal state %d in rt block map %" PRIu64 "\n"), state, b); } } /* * bump up the block counter */ *tot += irec->br_blockcount; return 0; } /* * return 1 if inode should be cleared, 0 otherwise * if check_dups should be set to 1, that implies that * the primary purpose of this call is to see if the * file overlaps with any duplicate extents (in the * duplicate extent list). */ static int process_bmbt_reclist_int( xfs_mount_t *mp, xfs_bmbt_rec_t *rp, int *numrecs, int type, xfs_ino_t ino, xfs_drfsbno_t *tot, blkmap_t **blkmapp, xfs_dfiloff_t *first_key, xfs_dfiloff_t *last_key, int check_dups, int whichfork) { xfs_bmbt_irec_t irec; xfs_dfilblks_t cp = 0; /* prev count */ xfs_dfsbno_t sp = 0; /* prev start */ xfs_dfiloff_t op = 0; /* prev offset */ xfs_dfsbno_t b; char *ftype; char *forkname; int i; int state; xfs_agnumber_t agno; xfs_agblock_t agbno; xfs_agblock_t ebno; xfs_extlen_t blen; xfs_agnumber_t locked_agno = -1; int error = 1; if (whichfork == XFS_DATA_FORK) forkname = _("data"); else forkname = _("attr"); if (type == XR_INO_RTDATA) ftype = _("real-time"); else ftype = _("regular"); for (i = 0; i < *numrecs; i++) { libxfs_bmbt_disk_get_all(rp + i, &irec); if (i == 0) *last_key = *first_key = irec.br_startoff; else *last_key = irec.br_startoff; if (i > 0 && op + cp > irec.br_startoff) { do_warn( _("bmap rec out of order, inode %" PRIu64" entry %d " "[o s c] [%" PRIu64 " %" PRIu64 " %" PRIu64 "], " "%d [%" PRIu64 " %" PRIu64 " %" PRIu64 "]\n"), ino, i, irec.br_startoff, irec.br_startblock, irec.br_blockcount, i - 1, op, sp, cp); goto done; } op = irec.br_startoff; cp = irec.br_blockcount; sp = irec.br_startblock; /* * check numeric validity of the extent */ if (irec.br_blockcount == 0) { do_warn( _("zero length extent (off = %" PRIu64 ", fsbno = %" PRIu64 ") in ino %" PRIu64 "\n"), irec.br_startoff, irec.br_startblock, ino); goto done; } if (type == XR_INO_RTDATA && whichfork == XFS_DATA_FORK) { /* * realtime bitmaps don't use AG locks, so returning * immediately is fine for this code path. */ if (process_rt_rec(mp, &irec, ino, tot, check_dups)) return 1; /* * skip rest of loop processing since that'irec.br_startblock * all for regular file forks and attr forks */ continue; } /* * regular file data fork or attribute fork */ switch (verify_dfsbno_range(mp, irec.br_startblock, irec.br_blockcount)) { case XR_DFSBNORANGE_VALID: break; case XR_DFSBNORANGE_BADSTART: do_warn( _("inode %" PRIu64 " - bad extent starting block number %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec.br_startblock, irec.br_startoff); goto done; case XR_DFSBNORANGE_BADEND: do_warn( _("inode %" PRIu64 " - bad extent last block number %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec.br_startblock + irec.br_blockcount - 1, irec.br_startoff); goto done; case XR_DFSBNORANGE_OVERFLOW: do_warn( _("inode %" PRIu64 " - bad extent overflows - start %" PRIu64 ", " "end %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec.br_startblock, irec.br_startblock + irec.br_blockcount - 1, irec.br_startoff); goto done; } if (irec.br_startoff >= fs_max_file_offset) { do_warn( _("inode %" PRIu64 " - extent offset too large - start %" PRIu64 ", " "count %" PRIu64 ", offset %" PRIu64 "\n"), ino, irec.br_startblock, irec.br_blockcount, irec.br_startoff); goto done; } if (blkmapp && *blkmapp) { error = blkmap_set_ext(blkmapp, irec.br_startoff, irec.br_startblock, irec.br_blockcount); if (error) { /* * we don't want to clear the inode due to an * internal bmap tracking error, but if we've * run out of memory then we simply can't * validate that the filesystem is consistent. * Hence just abort at this point with an ENOMEM * error. */ do_abort( _("Fatal error: inode %" PRIu64 " - blkmap_set_ext(): %s\n" "\t%s fork, off - %" PRIu64 ", start - %" PRIu64 ", cnt %" PRIu64 "\n"), ino, strerror(error), forkname, irec.br_startoff, irec.br_startblock, irec.br_blockcount); } } /* * Profiling shows that the following loop takes the * most time in all of xfs_repair. */ agno = XFS_FSB_TO_AGNO(mp, irec.br_startblock); agbno = XFS_FSB_TO_AGBNO(mp, irec.br_startblock); ebno = agbno + irec.br_blockcount; if (agno != locked_agno) { if (locked_agno != -1) pthread_mutex_unlock(&ag_locks[locked_agno]); pthread_mutex_lock(&ag_locks[agno]); locked_agno = agno; } if (check_dups) { /* * if we're just checking the bmap for dups, * return if we find one, otherwise, continue * checking each entry without setting the * block bitmap */ if (search_dup_extent(agno, agbno, ebno)) { do_warn( _("%s fork in ino %" PRIu64 " claims dup extent, " "off - %" PRIu64 ", start - %" PRIu64 ", cnt %" PRIu64 "\n"), forkname, ino, irec.br_startoff, irec.br_startblock, irec.br_blockcount); goto done; } *tot += irec.br_blockcount; continue; } for (b = irec.br_startblock; agbno < ebno; b += blen, agbno += blen) { state = get_bmap_ext(agno, agbno, ebno, &blen); switch (state) { case XR_E_FREE: case XR_E_FREE1: do_warn( _("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"), forkname, ino, (__uint64_t) b); /* fall through ... */ case XR_E_UNKNOWN: set_bmap_ext(agno, agbno, blen, XR_E_INUSE); break; case XR_E_BAD_STATE: do_error(_("bad state in block map %" PRIu64 "\n"), b); case XR_E_FS_MAP: case XR_E_INO: case XR_E_INUSE_FS: do_warn( _("%s fork in inode %" PRIu64 " claims metadata block %" PRIu64 "\n"), forkname, ino, b); goto done; case XR_E_INUSE: case XR_E_MULT: set_bmap_ext(agno, agbno, blen, XR_E_MULT); do_warn( _("%s fork in %s inode %" PRIu64 " claims used block %" PRIu64 "\n"), forkname, ftype, ino, b); goto done; default: do_error( _("illegal state %d in block map %" PRIu64 "\n"), state, b); } } *tot += irec.br_blockcount; } error = 0; done: if (locked_agno != -1) pthread_mutex_unlock(&ag_locks[locked_agno]); if (i != *numrecs) { ASSERT(i < *numrecs); do_warn(_("correcting nextents for inode %" PRIu64 "\n"), ino); *numrecs = i; } return error; } /* * return 1 if inode should be cleared, 0 otherwise, sets block bitmap * as a side-effect */ int process_bmbt_reclist( xfs_mount_t *mp, xfs_bmbt_rec_t *rp, int *numrecs, int type, xfs_ino_t ino, xfs_drfsbno_t *tot, blkmap_t **blkmapp, xfs_dfiloff_t *first_key, xfs_dfiloff_t *last_key, int whichfork) { return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, blkmapp, first_key, last_key, 0, whichfork); } /* * return 1 if inode should be cleared, 0 otherwise, does not set * block bitmap */ int scan_bmbt_reclist( xfs_mount_t *mp, xfs_bmbt_rec_t *rp, int *numrecs, int type, xfs_ino_t ino, xfs_drfsbno_t *tot, int whichfork) { xfs_dfiloff_t first_key = 0; xfs_dfiloff_t last_key = 0; return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, NULL, &first_key, &last_key, 1, whichfork); } /* * these two are meant for routines that read and work with inodes * one at a time where the inodes may be in any order (like walking * the unlinked lists to look for inodes). the caller is responsible * for writing/releasing the buffer. */ xfs_buf_t * get_agino_buf(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino, xfs_dinode_t **dipp) { ino_tree_node_t *irec; xfs_buf_t *bp; int size; if ((irec = find_inode_rec(mp, agno, agino)) == NULL) return(NULL); size = XFS_FSB_TO_BB(mp, MAX(1, XFS_INODES_PER_CHUNK/inodes_per_block)); bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum)), size, 0); if (!bp) { do_warn(_("cannot read inode (%u/%u), disk block %" PRIu64 "\n"), agno, irec->ino_startnum, XFS_AGB_TO_DADDR(mp, agno, XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum))); return(NULL); } *dipp = xfs_make_iptr(mp, bp, agino - XFS_OFFBNO_TO_AGINO(mp, XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum), 0)); return(bp); } /* * these next routines return the filesystem blockno of the * block containing the block "bno" in the file whose bmap * tree (or extent list) is rooted by "rootblock". * * the next routines are utility routines for the third * routine, get_bmapi(). * * NOTE: getfunc_extlist only used by dirv1 checking code */ static xfs_dfsbno_t getfunc_extlist(xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, xfs_dfiloff_t bno, int whichfork) { xfs_bmbt_irec_t irec; xfs_dfsbno_t final_fsbno = NULLDFSBNO; xfs_bmbt_rec_t *rootblock = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); xfs_extnum_t nextents = XFS_DFORK_NEXTENTS(dip, whichfork); int i; for (i = 0; i < nextents; i++) { libxfs_bmbt_disk_get_all(rootblock + i, &irec); if (irec.br_startoff <= bno && bno < irec.br_startoff + irec.br_blockcount) { final_fsbno = bno - irec.br_startoff + irec.br_startblock; break; } } return(final_fsbno); } /* * NOTE: getfunc_btree only used by dirv1 checking code... */ static xfs_dfsbno_t getfunc_btree(xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, xfs_dfiloff_t bno, int whichfork) { int i; #ifdef DEBUG int prev_level; #endif int found; int numrecs; xfs_bmbt_rec_t *rec; xfs_bmbt_irec_t irec; xfs_bmbt_ptr_t *pp; xfs_bmbt_key_t *key; xfs_bmdr_key_t *rkey; xfs_bmdr_ptr_t *rp; xfs_dfsbno_t fsbno; xfs_buf_t *bp; xfs_dfsbno_t final_fsbno = NULLDFSBNO; struct xfs_btree_block *block; xfs_bmdr_block_t *rootblock = (xfs_bmdr_block_t *) XFS_DFORK_PTR(dip, whichfork); ASSERT(rootblock->bb_level != 0); /* * deal with root block, it's got a slightly different * header structure than interior nodes. We know that * a btree should have at least 2 levels otherwise it * would be an extent list. */ rkey = XFS_BMDR_KEY_ADDR(rootblock, 1); rp = XFS_BMDR_PTR_ADDR(rootblock, 1, xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 1)); found = -1; for (i = 0; i < be16_to_cpu(rootblock->bb_numrecs) - 1; i++) { if (be64_to_cpu(rkey[i].br_startoff) <= bno && bno < be64_to_cpu(rkey[i + 1].br_startoff)) { found = i; break; } } if (i == be16_to_cpu(rootblock->bb_numrecs) - 1 && bno >= be64_to_cpu(rkey[i].br_startoff)) found = i; ASSERT(found != -1); fsbno = be64_to_cpu(rp[found]); ASSERT(verify_dfsbno(mp, fsbno)); bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_error(_("cannot read bmap block %" PRIu64 "\n"), fsbno); return(NULLDFSBNO); } block = XFS_BUF_TO_BLOCK(bp); numrecs = be16_to_cpu(block->bb_numrecs); /* * ok, now traverse any interior btree nodes */ #ifdef DEBUG prev_level = be16_to_cpu(block->bb_level); #endif while (be16_to_cpu(block->bb_level) > 0) { #ifdef DEBUG ASSERT(be16_to_cpu(block->bb_level) < prev_level); prev_level = be16_to_cpu(block->bb_level); #endif if (numrecs > mp->m_bmap_dmxr[1]) { do_warn( _("# of bmap records in inode %" PRIu64 " exceeds max (%u, max - %u)\n"), ino, numrecs, mp->m_bmap_dmxr[1]); libxfs_putbuf(bp); return(NULLDFSBNO); } if (verbose && numrecs < mp->m_bmap_dmnr[1]) { do_warn( _("- # of bmap records in inode %" PRIu64 " less than minimum (%u, min - %u), proceeding ...\n"), ino, numrecs, mp->m_bmap_dmnr[1]); } key = XFS_BMBT_KEY_ADDR(mp, block, 1); pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); for (found = -1, i = 0; i < numrecs - 1; i++) { if (be64_to_cpu(key[i].br_startoff) <= bno && bno < be64_to_cpu(key[i + 1].br_startoff)) { found = i; break; } } if (i == numrecs - 1 && bno >= be64_to_cpu(key[i].br_startoff)) found = i; ASSERT(found != -1); fsbno = be64_to_cpu(pp[found]); ASSERT(verify_dfsbno(mp, fsbno)); /* * release current btree block and read in the * next btree block to be traversed */ libxfs_putbuf(bp); bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_error(_("cannot read bmap block %" PRIu64 "\n"), fsbno); return(NULLDFSBNO); } block = XFS_BUF_TO_BLOCK(bp); numrecs = be16_to_cpu(block->bb_numrecs); } /* * current block must be a leaf block */ ASSERT(be16_to_cpu(block->bb_level) == 0); if (numrecs > mp->m_bmap_dmxr[0]) { do_warn( _("# of bmap records in inode %" PRIu64 " greater than maximum (%u, max - %u)\n"), ino, numrecs, mp->m_bmap_dmxr[0]); libxfs_putbuf(bp); return(NULLDFSBNO); } if (verbose && numrecs < mp->m_bmap_dmnr[0]) do_warn( _("- # of bmap records in inode %" PRIu64 " less than minimum (%u, min - %u), continuing...\n"), ino, numrecs, mp->m_bmap_dmnr[0]); rec = XFS_BMBT_REC_ADDR(mp, block, 1); for (i = 0; i < numrecs; i++) { libxfs_bmbt_disk_get_all(rec + i, &irec); if (irec.br_startoff <= bno && bno < irec.br_startoff + irec.br_blockcount) { final_fsbno = bno - irec.br_startoff + irec.br_startblock; break; } } libxfs_putbuf(bp); if (final_fsbno == NULLDFSBNO) do_warn(_("could not map block %" PRIu64 "\n"), bno); return(final_fsbno); } /* * this could be smarter. maybe we should have an open inode * routine that would get the inode buffer and return back * an inode handle. I'm betting for the moment that this * is used only by the directory and attribute checking code * and that the avl tree find and buffer cache search are * relatively cheap. If they're too expensive, we'll just * have to fix this and add an inode handle to the da btree * cursor. * * caller is responsible for checking doubly referenced blocks * and references to holes * * NOTE: get_bmapi only used by dirv1 checking code */ xfs_dfsbno_t get_bmapi(xfs_mount_t *mp, xfs_dinode_t *dino_p, xfs_ino_t ino_num, xfs_dfiloff_t bno, int whichfork) { xfs_dfsbno_t fsbno; switch (XFS_DFORK_FORMAT(dino_p, whichfork)) { case XFS_DINODE_FMT_EXTENTS: fsbno = getfunc_extlist(mp, ino_num, dino_p, bno, whichfork); break; case XFS_DINODE_FMT_BTREE: fsbno = getfunc_btree(mp, ino_num, dino_p, bno, whichfork); break; case XFS_DINODE_FMT_LOCAL: do_error(_("get_bmapi() called for local inode %" PRIu64 "\n"), ino_num); fsbno = NULLDFSBNO; break; default: /* * shouldn't happen */ do_error(_("bad inode format for inode %" PRIu64 "\n"), ino_num); fsbno = NULLDFSBNO; } return(fsbno); } /* * higher level inode processing stuff starts here: * first, one utility routine for each type of inode */ /* * return 1 if inode should be cleared, 0 otherwise */ static int process_btinode( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dip, int type, int *dirty, xfs_drfsbno_t *tot, __uint64_t *nex, blkmap_t **blkmapp, int whichfork, int check_dups) { xfs_bmdr_block_t *dib; xfs_dfiloff_t last_key; xfs_dfiloff_t first_key = 0; xfs_ino_t lino; xfs_bmbt_ptr_t *pp; xfs_bmbt_key_t *pkey; char *forkname; int i; int level; int numrecs; bmap_cursor_t cursor; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); lino = XFS_AGINO_TO_INO(mp, agno, ino); *tot = 0; *nex = 0; if (whichfork == XFS_DATA_FORK) forkname = _("data"); else forkname = _("attr"); level = be16_to_cpu(dib->bb_level); numrecs = be16_to_cpu(dib->bb_numrecs); if ((level == 0) || (level > XFS_BM_MAXLEVELS(mp, whichfork))) { /* * XXX - if we were going to fix up the inode, * we'd try to treat the fork as an interior * node and see if we could get an accurate * level value from one of the blocks pointed * to by the pointers in the fork. For now * though, we just bail (and blow out the inode). */ do_warn( _("bad level %d in inode %" PRIu64 " bmap btree root block\n"), level, XFS_AGINO_TO_INO(mp, agno, ino)); return(1); } if (numrecs == 0) { do_warn( _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), XFS_AGINO_TO_INO(mp, agno, ino)); return(1); } /* * use bmdr/dfork_dsize since the root block is in the data fork */ if (XFS_BMDR_SPACE_CALC(numrecs) > XFS_DFORK_SIZE(dip, mp, whichfork)) { do_warn( _("indicated size of %s btree root (%d bytes) greater than space in " "inode %" PRIu64 " %s fork\n"), forkname, XFS_BMDR_SPACE_CALC(numrecs), lino, forkname); return(1); } init_bm_cursor(&cursor, level + 1); pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 0)); pkey = XFS_BMDR_KEY_ADDR(dib, 1); last_key = NULLDFILOFF; for (i = 0; i < numrecs; i++) { /* * XXX - if we were going to do more to fix up the inode * btree, we'd do it right here. For now, if there's a * problem, we'll bail out and presumably clear the inode. */ if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(pp[i]), lino); return(1); } if (scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, whichfork, lino, tot, nex, blkmapp, &cursor, 1, check_dups)) return(1); /* * fix key (offset) mismatches between the keys in root * block records and the first key of each child block. * fixes cases where entries have been shifted between * blocks but the parent hasn't been updated */ if (!check_dups && cursor.level[level-1].first_key != be64_to_cpu(pkey[i].br_startoff)) { if (!no_modify) { do_warn( _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " "%" PRIu64" %s fork\n"), (unsigned long long) be64_to_cpu(pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); *dirty = 1; pkey[i].br_startoff = cpu_to_be64( cursor.level[level-1].first_key); } else { do_warn( _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " "%" PRIu64 " %s fork\n"), (unsigned long long) be64_to_cpu(pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); } } /* * make sure that keys are in ascending order. blow out * inode if the ordering doesn't hold */ if (check_dups == 0) { if (last_key != NULLDFILOFF && last_key >= cursor.level[level-1].first_key) { do_warn( _("out of order bmbt root key %" PRIu64 " in inode %" PRIu64 " %s fork\n"), first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); return(1); } last_key = cursor.level[level-1].first_key; } } /* * Ideally if all the extents are ok (perhaps after further * checks below?) we'd just move this back into extents format. * But for now clear it, as the kernel will choke on this */ if (*nex <= XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { do_warn( _("extent count for ino %" PRIu64 " %s fork too low (%" PRIu64 ") for file format\n"), lino, forkname, *nex); return(1); } /* * Check that the last child block's forward sibling pointer * is NULL. */ if (check_dups == 0 && cursor.level[0].right_fsbno != NULLDFSBNO) { do_warn( _("bad fwd (right) sibling pointer (saw %" PRIu64 " should be NULLDFSBNO)\n"), cursor.level[0].right_fsbno); do_warn( _("\tin inode %" PRIu64 " (%s fork) bmap btree block %" PRIu64 "\n"), XFS_AGINO_TO_INO(mp, agno, ino), forkname, cursor.level[0].fsbno); return(1); } return(0); } /* * return 1 if inode should be cleared, 0 otherwise */ static int process_exinode( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dip, int type, int *dirty, xfs_drfsbno_t *tot, __uint64_t *nex, blkmap_t **blkmapp, int whichfork, int check_dups) { xfs_ino_t lino; xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; int numrecs; int ret; lino = XFS_AGINO_TO_INO(mp, agno, ino); rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); *tot = 0; numrecs = XFS_DFORK_NEXTENTS(dip, whichfork); /* * XXX - if we were going to fix up the btree record, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. */ if (check_dups == 0) ret = process_bmbt_reclist(mp, rp, &numrecs, type, lino, tot, blkmapp, &first_key, &last_key, whichfork); else ret = scan_bmbt_reclist(mp, rp, &numrecs, type, lino, tot, whichfork); *nex = numrecs; return ret; } /* * return 1 if inode should be cleared, 0 otherwise */ static int process_lclinode( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dip, int whichfork) { xfs_attr_shortform_t *asf; xfs_ino_t lino; lino = XFS_AGINO_TO_INO(mp, agno, ino); if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_size) > XFS_DFORK_DSIZE(dip, mp)) { do_warn( _("local inode %" PRIu64 " data fork is too large (size = %lld, max = %d)\n"), lino, (unsigned long long) be64_to_cpu(dip->di_size), XFS_DFORK_DSIZE(dip, mp)); return(1); } else if (whichfork == XFS_ATTR_FORK) { asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) { do_warn( _("local inode %" PRIu64 " attr fork too large (size %d, max = %d)\n"), lino, be16_to_cpu(asf->hdr.totsize), XFS_DFORK_ASIZE(dip, mp)); return(1); } if (be16_to_cpu(asf->hdr.totsize) < sizeof(xfs_attr_sf_hdr_t)) { do_warn( _("local inode %" PRIu64 " attr too small (size = %d, min size = %zd)\n"), lino, be16_to_cpu(asf->hdr.totsize), sizeof(xfs_attr_sf_hdr_t)); return(1); } } return(0); } static int process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino) { xfs_dfiloff_t expected_offset; xfs_bmbt_rec_t *rp; xfs_bmbt_irec_t irec; int numrecs; int i; int max_blocks; if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) { if (dino->di_format == XFS_DINODE_FMT_LOCAL) return 0; do_warn( _("mismatch between format (%d) and size (%" PRId64 ") in symlink ino %" PRIu64 "\n"), dino->di_format, (__int64_t)be64_to_cpu(dino->di_size), lino); return 1; } if (dino->di_format == XFS_DINODE_FMT_LOCAL) { do_warn( _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu64 "\n"), dino->di_format, (__int64_t)be64_to_cpu(dino->di_size), lino); return 1; } rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino); numrecs = be32_to_cpu(dino->di_nextents); /* * the max # of extents in a symlink inode is equal to the * number of max # of blocks required to store the symlink */ if (numrecs > max_symlink_blocks) { do_warn( _("bad number of extents (%d) in symlink %" PRIu64 " data fork\n"), numrecs, lino); return(1); } max_blocks = max_symlink_blocks; expected_offset = 0; for (i = 0; i < numrecs; i++) { libxfs_bmbt_disk_get_all(rp + i, &irec); if (irec.br_startoff != expected_offset) { do_warn( _("bad extent #%d offset (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"), i, irec.br_startoff, lino); return(1); } if (irec.br_blockcount == 0 || irec.br_blockcount > max_blocks) { do_warn( _("bad extent #%d count (%" PRIu64 ") in symlink %" PRIu64 " data fork\n"), i, irec.br_blockcount, lino); return(1); } max_blocks -= irec.br_blockcount; expected_offset += irec.br_blockcount; } return(0); } /* * takes a name and length and returns 1 if the name contains * a \0, returns 0 otherwise */ static int null_check(char *name, int length) { int i; ASSERT(length < MAXPATHLEN); for (i = 0; i < length; i++, name++) { if (*name == '\0') return(1); } return(0); } /* * like usual, returns 0 if everything's ok and 1 if something's * bogus */ static int process_symlink( xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino, blkmap_t *blkmap) { xfs_dfsbno_t fsbno; xfs_buf_t *bp = NULL; char *symlink, *cptr, *buf_data; int i, size, amountdone; char data[MAXPATHLEN]; /* * check size against kernel symlink limits. we know * size is consistent with inode storage format -- e.g. * the inode is structurally ok so we don't have to check * for that */ if (be64_to_cpu(dino->di_size) >= MAXPATHLEN) { do_warn(_("symlink in inode %" PRIu64 " too long (%llu chars)\n"), lino, (unsigned long long) be64_to_cpu(dino->di_size)); return(1); } /* * have to check symlink component by component. * get symlink contents into data area */ symlink = &data[0]; if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) { /* * local symlink, just copy the symlink out of the * inode into the data area */ memmove(symlink, XFS_DFORK_DPTR(dino), be64_to_cpu(dino->di_size)); } else { /* * stored in a meta-data file, have to bmap one block * at a time and copy the symlink into the data area */ i = size = amountdone = 0; cptr = symlink; while (amountdone < be64_to_cpu(dino->di_size)) { fsbno = blkmap_get(blkmap, i); if (fsbno != NULLDFSBNO) bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, fsbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp || fsbno == NULLDFSBNO) { do_warn( _("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"), lino, i, fsbno); return(1); } buf_data = (char *)XFS_BUF_PTR(bp); size = MIN(be64_to_cpu(dino->di_size) - amountdone, XFS_FSB_TO_BB(mp, 1) * BBSIZE); memmove(cptr, buf_data, size); cptr += size; amountdone += size; i++; libxfs_putbuf(bp); } } data[be64_to_cpu(dino->di_size)] = '\0'; /* * check for nulls */ if (null_check(symlink, be64_to_cpu(dino->di_size))) { do_warn( _("found illegal null character in symlink inode %" PRIu64 "\n"), lino); return(1); } /* * check for any component being too long */ if (be64_to_cpu(dino->di_size) >= MAXNAMELEN) { cptr = strchr(symlink, '/'); while (cptr != NULL) { if (cptr - symlink >= MAXNAMELEN) { do_warn( _("component of symlink in inode %" PRIu64 " too long\n"), lino); return(1); } symlink = cptr + 1; cptr = strchr(symlink, '/'); } if (strlen(symlink) >= MAXNAMELEN) { do_warn( _("component of symlink in inode %" PRIu64 " too long\n"), lino); return(1); } } return(0); } /* * called to process the set of misc inode special inode types * that have no associated data storage (fifos, pipes, devices, etc.). */ static int process_misc_ino_types(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t lino, int type) { /* * disallow mountpoint inodes until such time as the * kernel actually allows them to be created (will * probably require a superblock version rev, sigh). */ if (type == XR_INO_MOUNTPOINT) { do_warn( _("inode %" PRIu64 " has bad inode type (IFMNT)\n"), lino); return(1); } /* * must also have a zero size */ if (be64_to_cpu(dino->di_size) != 0) { switch (type) { case XR_INO_CHRDEV: do_warn( _("size of character device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino, (__int64_t)be64_to_cpu(dino->di_size)); break; case XR_INO_BLKDEV: do_warn( _("size of block device inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino, (__int64_t)be64_to_cpu(dino->di_size)); break; case XR_INO_SOCK: do_warn( _("size of socket inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino, (__int64_t)be64_to_cpu(dino->di_size)); break; case XR_INO_FIFO: do_warn( _("size of fifo inode %" PRIu64 " != 0 (%" PRId64 " bytes)\n"), lino, (__int64_t)be64_to_cpu(dino->di_size)); break; default: do_warn(_("Internal error - process_misc_ino_types, " "illegal type %d\n"), type); abort(); } return(1); } return(0); } static int process_misc_ino_types_blocks(xfs_drfsbno_t totblocks, xfs_ino_t lino, int type) { /* * you can not enforce all misc types have zero data fork blocks * by checking dino->di_nblocks because atotblocks (attribute * blocks) are part of nblocks. We must check this later when atotblocks * has been calculated or by doing a simple check that anExtents == 0. * We must also guarantee that totblocks is 0. Thus nblocks checking * will be done later in process_dinode_int for misc types. */ if (totblocks != 0) { switch (type) { case XR_INO_CHRDEV: do_warn( _("size of character device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"), lino, totblocks); break; case XR_INO_BLKDEV: do_warn( _("size of block device inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"), lino, totblocks); break; case XR_INO_SOCK: do_warn( _("size of socket inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"), lino, totblocks); break; case XR_INO_FIFO: do_warn( _("size of fifo inode %" PRIu64 " != 0 (%" PRIu64 " blocks)\n"), lino, totblocks); break; default: return(0); } return(1); } return (0); } static inline int dinode_fmt( xfs_dinode_t *dino) { return be16_to_cpu(dino->di_mode) & S_IFMT; } static inline void change_dinode_fmt( xfs_dinode_t *dino, int new_fmt) { int mode = be16_to_cpu(dino->di_mode); ASSERT((new_fmt & ~S_IFMT) == 0); mode &= ~S_IFMT; mode |= new_fmt; dino->di_mode = cpu_to_be16(mode); } static int check_dinode_mode_format( xfs_dinode_t *dinoc) { if (dinoc->di_format >= XFS_DINODE_FMT_UUID) return -1; /* FMT_UUID is not used */ switch (dinode_fmt(dinoc)) { case S_IFIFO: case S_IFCHR: case S_IFBLK: case S_IFSOCK: return (dinoc->di_format != XFS_DINODE_FMT_DEV) ? -1 : 0; case S_IFDIR: return (dinoc->di_format < XFS_DINODE_FMT_LOCAL || dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0; case S_IFREG: return (dinoc->di_format < XFS_DINODE_FMT_EXTENTS || dinoc->di_format > XFS_DINODE_FMT_BTREE) ? -1 : 0; case S_IFLNK: return (dinoc->di_format < XFS_DINODE_FMT_LOCAL || dinoc->di_format > XFS_DINODE_FMT_EXTENTS) ? -1 : 0; default: ; } return 0; /* invalid modes are checked elsewhere */ } /* * If inode is a superblock inode, does type check to make sure is it valid. * Returns 0 if it's valid, non-zero if it needs to be cleared. */ static int process_check_sb_inodes( xfs_mount_t *mp, xfs_dinode_t *dinoc, xfs_ino_t lino, int *type, int *dirty) { if (lino == mp->m_sb.sb_rootino) { if (*type != XR_INO_DIR) { do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"), lino, dinode_fmt(dinoc)); *type = XR_INO_DIR; if (!no_modify) { do_warn(_("resetting to directory\n")); change_dinode_fmt(dinoc, S_IFDIR); *dirty = 1; } else do_warn(_("would reset to directory\n")); } return 0; } if (lino == mp->m_sb.sb_uquotino) { if (*type != XR_INO_DATA) { do_warn(_("user quota inode %" PRIu64 " has bad type 0x%x\n"), lino, dinode_fmt(dinoc)); mp->m_sb.sb_uquotino = NULLFSINO; return 1; } return 0; } if (lino == mp->m_sb.sb_gquotino) { if (*type != XR_INO_DATA) { do_warn(_("group quota inode %" PRIu64 " has bad type 0x%x\n"), lino, dinode_fmt(dinoc)); mp->m_sb.sb_gquotino = NULLFSINO; return 1; } return 0; } if (lino == mp->m_sb.sb_rsumino) { if (*type != XR_INO_RTSUM) { do_warn( _("realtime summary inode %" PRIu64 " has bad type 0x%x, "), lino, dinode_fmt(dinoc)); if (!no_modify) { do_warn(_("resetting to regular file\n")); change_dinode_fmt(dinoc, S_IFREG); *dirty = 1; } else { do_warn(_("would reset to regular file\n")); } } if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) { do_warn( _("bad # of extents (%u) for realtime summary inode %" PRIu64 "\n"), be32_to_cpu(dinoc->di_nextents), lino); return 1; } return 0; } if (lino == mp->m_sb.sb_rbmino) { if (*type != XR_INO_RTBITMAP) { do_warn( _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "), lino, dinode_fmt(dinoc)); if (!no_modify) { do_warn(_("resetting to regular file\n")); change_dinode_fmt(dinoc, S_IFREG); *dirty = 1; } else { do_warn(_("would reset to regular file\n")); } } if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) { do_warn( _("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"), be32_to_cpu(dinoc->di_nextents), lino); return 1; } return 0; } return 0; } /* * general size/consistency checks: * * if the size <= size of the data fork, directories must be * local inodes unlike regular files which would be extent inodes. * all the other mentioned types have to have a zero size value. * * if the size and format don't match, get out now rather than * risk trying to process a non-existent extents or btree * type data fork. */ static int process_check_inode_sizes( xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t lino, int type) { xfs_fsize_t size = be64_to_cpu(dino->di_size); switch (type) { case XR_INO_DIR: if (size <= XFS_DFORK_DSIZE(dino, mp) && dino->di_format != XFS_DINODE_FMT_LOCAL) { do_warn( _("mismatch between format (%d) and size (%" PRId64 ") in directory ino %" PRIu64 "\n"), dino->di_format, size, lino); return 1; } if (size > XFS_DIR2_LEAF_OFFSET) { do_warn( _("directory inode %" PRIu64 " has bad size %" PRId64 "\n"), lino, size); return 1; } break; case XR_INO_SYMLINK: if (process_symlink_extlist(mp, lino, dino)) { do_warn(_("bad data fork in symlink %" PRIu64 "\n"), lino); return 1; } break; case XR_INO_CHRDEV: /* fall through to FIFO case ... */ case XR_INO_BLKDEV: /* fall through to FIFO case ... */ case XR_INO_SOCK: /* fall through to FIFO case ... */ case XR_INO_MOUNTPOINT: /* fall through to FIFO case ... */ case XR_INO_FIFO: if (process_misc_ino_types(mp, dino, lino, type)) return 1; break; case XR_INO_RTDATA: /* * if we have no realtime blocks, any inode claiming * to be a real-time file is bogus */ if (mp->m_sb.sb_rblocks == 0) { do_warn( _("found inode %" PRIu64 " claiming to be a real-time file\n"), lino); return 1; } break; case XR_INO_RTBITMAP: if (size != (__int64_t)mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize) { do_warn( _("realtime bitmap inode %" PRIu64 " has bad size %" PRId64 " (should be %" PRIu64 ")\n"), lino, size, (__int64_t) mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize); return 1; } break; case XR_INO_RTSUM: if (size != mp->m_rsumsize) { do_warn( _("realtime summary inode %" PRIu64 " has bad size %" PRId64 " (should be %d)\n"), lino, size, mp->m_rsumsize); return 1; } break; default: break; } return 0; } /* * check for illegal values of forkoff */ static int process_check_inode_forkoff( xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t lino) { if (dino->di_forkoff == 0) return 0; switch (dino->di_format) { case XFS_DINODE_FMT_DEV: if (dino->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3)) { do_warn( _("bad attr fork offset %d in dev inode %" PRIu64 ", should be %d\n"), dino->di_forkoff, lino, (int)(roundup(sizeof(xfs_dev_t), 8) >> 3)); return 1; } break; case XFS_DINODE_FMT_LOCAL: /* fall through ... */ case XFS_DINODE_FMT_EXTENTS: /* fall through ... */ case XFS_DINODE_FMT_BTREE: if (dino->di_forkoff >= (XFS_LITINO(mp) >> 3)) { do_warn( _("bad attr fork offset %d in inode %" PRIu64 ", max=%d\n"), dino->di_forkoff, lino, XFS_LITINO(mp) >> 3); return 1; } break; default: do_error(_("unexpected inode format %d\n"), dino->di_format); break; } return 0; } /* * Updates the inodes block and extent counts if they are wrong */ static int process_inode_blocks_and_extents( xfs_dinode_t *dino, xfs_drfsbno_t nblocks, __uint64_t nextents, __uint64_t anextents, xfs_ino_t lino, int *dirty) { if (nblocks != be64_to_cpu(dino->di_nblocks)) { if (!no_modify) { do_warn( _("correcting nblocks for inode %" PRIu64 ", was %llu - counted %" PRIu64 "\n"), lino, (unsigned long long) be64_to_cpu(dino->di_nblocks), nblocks); dino->di_nblocks = cpu_to_be64(nblocks); *dirty = 1; } else { do_warn( _("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"), (unsigned long long) be64_to_cpu(dino->di_nblocks), lino, nblocks); } } if (nextents > MAXEXTNUM) { do_warn( _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"), nextents, lino); return 1; } if (nextents != be32_to_cpu(dino->di_nextents)) { if (!no_modify) { do_warn( _("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"), lino, be32_to_cpu(dino->di_nextents), nextents); dino->di_nextents = cpu_to_be32(nextents); *dirty = 1; } else { do_warn( _("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"), be32_to_cpu(dino->di_nextents), lino, nextents); } } if (anextents > MAXAEXTNUM) { do_warn( _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"), anextents, lino); return 1; } if (anextents != be16_to_cpu(dino->di_anextents)) { if (!no_modify) { do_warn( _("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"), lino, be16_to_cpu(dino->di_anextents), anextents); dino->di_anextents = cpu_to_be16(anextents); *dirty = 1; } else { do_warn( _("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"), be16_to_cpu(dino->di_anextents), lino, anextents); } } /* * We are comparing different units here, but that's fine given that * an extent has to have at least a block in it. */ if (nblocks < nextents + anextents) { do_warn( _("nblocks (%" PRIu64 ") smaller than nextents for inode %" PRIu64 "\n"), nblocks, lino); return 1; } return 0; } /* * check data fork -- if it's bad, clear the inode */ static int process_inode_data_fork( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dino, int type, int *dirty, xfs_drfsbno_t *totblocks, __uint64_t *nextents, blkmap_t **dblkmap, int check_dups) { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); int err = 0; *nextents = be32_to_cpu(dino->di_nextents); if (*nextents > be64_to_cpu(dino->di_nblocks)) *nextents = 1; if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA) *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK); *nextents = 0; switch (dino->di_format) { case XFS_DINODE_FMT_LOCAL: err = process_lclinode(mp, agno, ino, dino, XFS_DATA_FORK); *totblocks = 0; break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, check_dups); break; case XFS_DINODE_FMT_BTREE: err = process_btinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, check_dups); break; case XFS_DINODE_FMT_DEV: /* fall through */ err = 0; break; default: do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"), dino->di_format, lino, be16_to_cpu(dino->di_mode)); } if (err) { do_warn(_("bad data fork in inode %" PRIu64 "\n"), lino); if (!no_modify) { *dirty += clear_dinode(mp, dino, lino); ASSERT(*dirty > 0); } return 1; } if (check_dups) { /* * if check_dups was non-zero, we have to * re-process data fork to set bitmap since the * bitmap wasn't set the first time through */ switch (dino->di_format) { case XFS_DINODE_FMT_LOCAL: err = process_lclinode(mp, agno, ino, dino, XFS_DATA_FORK); break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, 0); break; case XFS_DINODE_FMT_BTREE: err = process_btinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, 0); break; case XFS_DINODE_FMT_DEV: /* fall through */ err = 0; break; default: do_error(_("unknown format %d, ino %" PRIu64 " (mode = %d)\n"), dino->di_format, lino, be16_to_cpu(dino->di_mode)); } if (no_modify && err != 0) return 1; ASSERT(err == 0); } return 0; } /* * Process extended attribute fork in inode */ static int process_inode_attr_fork( xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t ino, xfs_dinode_t *dino, int type, int *dirty, xfs_drfsbno_t *atotblocks, __uint64_t *anextents, int check_dups, int extra_attr_check, int *retval) { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); blkmap_t *ablkmap = NULL; int repair = 0; int err; if (!XFS_DFORK_Q(dino)) { *anextents = 0; if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) { do_warn(_("bad attribute format %d in inode %" PRIu64 ", "), dino->di_aformat, lino); if (!no_modify) { do_warn(_("resetting value\n")); dino->di_aformat = XFS_DINODE_FMT_EXTENTS; *dirty = 1; } else do_warn(_("would reset value\n")); } return 0; } *anextents = be16_to_cpu(dino->di_anextents); if (*anextents > be64_to_cpu(dino->di_nblocks)) *anextents = 1; switch (dino->di_aformat) { case XFS_DINODE_FMT_LOCAL: *anextents = 0; *atotblocks = 0; err = process_lclinode(mp, agno, ino, dino, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_EXTENTS: ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK); *anextents = 0; err = process_exinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, XFS_ATTR_FORK, check_dups); break; case XFS_DINODE_FMT_BTREE: ablkmap = blkmap_alloc(*anextents, XFS_ATTR_FORK); *anextents = 0; err = process_btinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, XFS_ATTR_FORK, check_dups); break; default: do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"), dino->di_aformat, lino); err = 1; break; } if (err) { /* * clear the attribute fork if necessary. we can't * clear the inode because we've already put the * inode space info into the blockmap. * * XXX - put the inode onto the "move it" list and * log the the attribute scrubbing */ do_warn(_("bad attribute fork in inode %" PRIu64), lino); if (!no_modify) { if (delete_attr_ok) { do_warn(_(", clearing attr fork\n")); *dirty += clear_dinode_attr(mp, dino, lino); dino->di_aformat = XFS_DINODE_FMT_LOCAL; } else { do_warn("\n"); *dirty += clear_dinode(mp, dino, lino); } ASSERT(*dirty > 0); } else { do_warn(_(", would clear attr fork\n")); } *atotblocks = 0; *anextents = 0; blkmap_free(ablkmap); *retval = 1; return delete_attr_ok ? 0 : 1; } if (check_dups) { switch (dino->di_aformat) { case XFS_DINODE_FMT_LOCAL: err = process_lclinode(mp, agno, ino, dino, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, XFS_ATTR_FORK, 0); break; case XFS_DINODE_FMT_BTREE: err = process_btinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, XFS_ATTR_FORK, 0); break; default: do_error(_("illegal attribute fmt %d, ino %" PRIu64 "\n"), dino->di_aformat, lino); } if (no_modify && err != 0) { blkmap_free(ablkmap); return 1; } ASSERT(err == 0); } /* * do attribute semantic-based consistency checks now */ /* get this only in phase 3, not in both phase 3 and 4 */ if (extra_attr_check && process_attributes(mp, lino, dino, ablkmap, &repair)) { do_warn( _("problem with attribute contents in inode %" PRIu64 "\n"), lino); if (!repair) { /* clear attributes if not done already */ if (!no_modify) { *dirty += clear_dinode_attr(mp, dino, lino); dino->di_aformat = XFS_DINODE_FMT_LOCAL; } else { do_warn(_("would clear attr fork\n")); } *atotblocks = 0; *anextents = 0; } else { *dirty = 1; /* it's been repaired */ } } blkmap_free(ablkmap); return 0; } /* * check nlinks feature, if it's a version 1 inode, * just leave nlinks alone. even if it's set wrong, * it'll be reset when read in. */ static int process_check_inode_nlink_version( xfs_dinode_t *dino, xfs_ino_t lino) { int dirty = 0; if (dino->di_version > 1 && !fs_inode_nlink) { /* * do we have a fs/inode version mismatch with a valid * version 2 inode here that has to stay version 2 or * lose links? */ if (be32_to_cpu(dino->di_nlink) > XFS_MAXLINK_1) { /* * yes. are nlink inodes allowed? */ if (fs_inode_nlink_allowed) { /* * yes, update status variable which will * cause sb to be updated later. */ fs_inode_nlink = 1; do_warn (_("version 2 inode %" PRIu64 " claims > %u links, "), lino, XFS_MAXLINK_1); if (!no_modify) { do_warn( _("updating superblock version number\n")); } else { do_warn( _("would update superblock version number\n")); } } else { /* * no, have to convert back to onlinks * even if we lose some links */ do_warn( _("WARNING: version 2 inode %" PRIu64 " claims > %u links, "), lino, XFS_MAXLINK_1); if (!no_modify) { do_warn(_("converting back to version 1,\n" "this may destroy %d links\n"), be32_to_cpu(dino->di_nlink) - XFS_MAXLINK_1); dino->di_version = 1; dino->di_nlink = cpu_to_be32(XFS_MAXLINK_1); dino->di_onlink = cpu_to_be16(XFS_MAXLINK_1); dirty = 1; } else { do_warn(_("would convert back to version 1,\n" "\tthis might destroy %d links\n"), be32_to_cpu(dino->di_nlink) - XFS_MAXLINK_1); } } } else { /* * do we have a v2 inode that we could convert back * to v1 without losing any links? if we do and * we have a mismatch between superblock bits and the * version bit, alter the version bit in this case. * * the case where we lost links was handled above. */ do_warn(_("found version 2 inode %" PRIu64 ", "), lino); if (!no_modify) { do_warn(_("converting back to version 1\n")); dino->di_version = 1; dino->di_onlink = cpu_to_be16( be32_to_cpu(dino->di_nlink)); dirty = 1; } else { do_warn(_("would convert back to version 1\n")); } } } /* * ok, if it's still a version 2 inode, it's going * to stay a version 2 inode. it should have a zero * onlink field, so clear it. */ if (dino->di_version > 1 && dino->di_onlink != 0 && fs_inode_nlink > 0) { if (!no_modify) { do_warn( _("clearing obsolete nlink field in version 2 inode %" PRIu64 ", was %d, now 0\n"), lino, be16_to_cpu(dino->di_onlink)); dino->di_onlink = 0; dirty = 1; } else { do_warn( _("would clear obsolete nlink field in version 2 inode %" PRIu64 ", currently %d\n"), lino, be16_to_cpu(dino->di_onlink)); } } return dirty; } /* * returns 0 if the inode is ok, 1 if the inode is corrupt * check_dups can be set to 1 *only* when called by the * first pass of the duplicate block checking of phase 4. * *dirty is set > 0 if the dinode has been altered and * needs to be written out. * * for detailed, info, look at process_dinode() comments. */ static int process_dinode_int(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino, int was_free, /* 1 if inode is currently free */ int *dirty, /* out == > 0 if inode is now dirty */ int *used, /* out == 1 if inode is in use */ int verify_mode, /* 1 == verify but don't modify inode */ int uncertain, /* 1 == inode is uncertain */ int ino_discovery, /* 1 == check dirs for unknown inodes */ int check_dups, /* 1 == check if inode claims * duplicate blocks */ int extra_attr_check, /* 1 == do attribute format and value checks */ int *isa_dir, /* out == 1 if inode is a directory */ xfs_ino_t *parent) /* out -- parent if ino is a dir */ { xfs_drfsbno_t totblocks = 0; xfs_drfsbno_t atotblocks = 0; int di_mode; int type; int retval = 0; __uint64_t nextents; __uint64_t anextents; xfs_ino_t lino; const int is_free = 0; const int is_used = 1; blkmap_t *dblkmap = NULL; *dirty = *isa_dir = 0; *used = is_used; type = XR_INO_UNKNOWN; lino = XFS_AGINO_TO_INO(mp, agno, ino); di_mode = be16_to_cpu(dino->di_mode); /* * if in verify mode, don't modify the inode. * * if correcting, reset stuff that has known values * * if in uncertain mode, be silent on errors since we're * trying to find out if these are inodes as opposed * to assuming that they are. Just return the appropriate * return code in that case. * * If uncertain is set, verify_mode MUST be set. */ ASSERT(uncertain == 0 || verify_mode != 0); if (be16_to_cpu(dino->di_magic) != XFS_DINODE_MAGIC) { retval = 1; if (!uncertain) do_warn(_("bad magic number 0x%x on inode %" PRIu64 "%c"), be16_to_cpu(dino->di_magic), lino, verify_mode ? '\n' : ','); if (!verify_mode) { if (!no_modify) { do_warn(_(" resetting magic number\n")); dino->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); *dirty = 1; } else do_warn(_(" would reset magic number\n")); } } if (!XFS_DINODE_GOOD_VERSION(dino->di_version) || (!fs_inode_nlink && dino->di_version > 1)) { retval = 1; if (!uncertain) do_warn(_("bad version number 0x%x on inode %" PRIu64 "%c"), (__s8)dino->di_version, lino, verify_mode ? '\n' : ','); if (!verify_mode) { if (!no_modify) { do_warn(_(" resetting version number\n")); dino->di_version = (fs_inode_nlink) ? 2 : 1; *dirty = 1; } else do_warn(_(" would reset version number\n")); } } /* * blow out of here if the inode size is < 0 */ if ((xfs_fsize_t)be64_to_cpu(dino->di_size) < 0) { if (!uncertain) do_warn( _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), (__int64_t)be64_to_cpu(dino->di_size), lino); if (verify_mode) return 1; goto clear_bad_out; } /* * if not in verify mode, check to sii if the inode and imap * agree that the inode is free */ if (!verify_mode && di_mode == 0) { /* * was_free value is not meaningful if we're in verify mode */ if (was_free) { /* * easy case, inode free -- inode and map agree, clear * it just in case to ensure that format, etc. are * set correctly */ if (!no_modify) *dirty += clear_dinode(mp, dino, lino); *used = is_free; return 0; } /* * the inode looks free but the map says it's in use. * clear the inode just to be safe and mark the inode * free. */ do_warn( _("imap claims a free inode %" PRIu64 " is in use, "), lino); if (!no_modify) { do_warn(_("correcting imap and clearing inode\n")); *dirty += clear_dinode(mp, dino, lino); retval = 1; } else do_warn(_("would correct imap and clear inode\n")); *used = is_free; return retval; } /* * because of the lack of any write ordering guarantee, it's * possible that the core got updated but the forks didn't. * so rather than be ambitious (and probably incorrect), * if there's an inconsistency, we get conservative and * just pitch the file. blow off checking formats of * free inodes since technically any format is legal * as we reset the inode when we re-use it. */ if (di_mode != 0 && check_dinode_mode_format(dino) != 0) { if (!uncertain) do_warn( _("bad inode format in inode %" PRIu64 "\n"), lino); if (verify_mode) return 1; goto clear_bad_out; } /* * check that we only have valid flags set, and those that are set make * sense. */ if (dino->di_flags) { uint16_t flags = be16_to_cpu(dino->di_flags); if (flags & ~XFS_DIFLAG_ANY) { if (!uncertain) { do_warn( _("Bad flags set in inode %" PRIu64 "\n"), lino); } flags &= ~XFS_DIFLAG_ANY; } if (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT)) { /* need an rt-dev! */ if (!rt_name) { if (!uncertain) { do_warn( _("inode %" PRIu64 " has RT flag set but there is no RT device\n"), lino); } flags &= ~(XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT); } } if (flags & XFS_DIFLAG_NEWRTBM) { /* must be a rt bitmap inode */ if (lino != mp->m_sb.sb_rbmino) { if (!uncertain) { do_warn( _("inode %" PRIu64 " not rt bitmap\n"), lino); } flags &= ~XFS_DIFLAG_NEWRTBM; } } if (flags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS)) { /* must be a directory */ if (di_mode && !S_ISDIR(di_mode)) { if (!uncertain) { do_warn( _("directory flags set on non-directory inode %" PRIu64 "\n" ), lino); } flags &= ~(XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS); } } if (flags & (XFS_DIFLAG_REALTIME | XFS_XFLAG_EXTSIZE)) { /* must be a file */ if (di_mode && !S_ISREG(di_mode)) { if (!uncertain) { do_warn( _("file flags set on non-file inode %" PRIu64 "\n"), lino); } flags &= ~(XFS_DIFLAG_REALTIME | XFS_XFLAG_EXTSIZE); } } if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) { if (!no_modify) { do_warn(_(", fixing bad flags.\n")); dino->di_flags = cpu_to_be16(flags); *dirty = 1; } else do_warn(_(", would fix bad flags.\n")); } } if (verify_mode) return retval; /* * clear the next unlinked field if necessary on a good * inode only during phase 4 -- when checking for inodes * referencing duplicate blocks. then it's safe because * we've done the inode discovery and have found all the inodes * we're going to find. check_dups is set to 1 only during * phase 4. Ugly. */ if (check_dups && !no_modify) *dirty += clear_dinode_unlinked(mp, dino); /* set type and map type info */ switch (di_mode & S_IFMT) { case S_IFDIR: type = XR_INO_DIR; *isa_dir = 1; break; case S_IFREG: if (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_REALTIME) type = XR_INO_RTDATA; else if (lino == mp->m_sb.sb_rbmino) type = XR_INO_RTBITMAP; else if (lino == mp->m_sb.sb_rsumino) type = XR_INO_RTSUM; else type = XR_INO_DATA; break; case S_IFLNK: type = XR_INO_SYMLINK; break; case S_IFCHR: type = XR_INO_CHRDEV; break; case S_IFBLK: type = XR_INO_BLKDEV; break; case S_IFSOCK: type = XR_INO_SOCK; break; case S_IFIFO: type = XR_INO_FIFO; break; default: do_warn(_("bad inode type %#o inode %" PRIu64 "\n"), di_mode & S_IFMT, lino); goto clear_bad_out; } /* * type checks for superblock inodes */ if (process_check_sb_inodes(mp, dino, lino, &type, dirty) != 0) goto clear_bad_out; /* * only regular files with REALTIME or EXTSIZE flags set can have * extsize set, or directories with EXTSZINHERIT. */ if (be32_to_cpu(dino->di_extsize) != 0) { if ((type == XR_INO_RTDATA) || (type == XR_INO_DIR && (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_EXTSZINHERIT)) || (type == XR_INO_DATA && (be16_to_cpu(dino->di_flags) & XFS_DIFLAG_EXTSIZE))) { /* s'okay */ ; } else { do_warn( _("bad non-zero extent size %u for non-realtime/extsize inode %" PRIu64 ", "), be32_to_cpu(dino->di_extsize), lino); if (!no_modify) { do_warn(_("resetting to zero\n")); dino->di_extsize = 0; *dirty = 1; } else do_warn(_("would reset to zero\n")); } } /* * general size/consistency checks: */ if (process_check_inode_sizes(mp, dino, lino, type) != 0) goto clear_bad_out; /* * check for illegal values of forkoff */ if (process_check_inode_forkoff(mp, dino, lino) != 0) goto clear_bad_out; /* * check data fork -- if it's bad, clear the inode */ if (process_inode_data_fork(mp, agno, ino, dino, type, dirty, &totblocks, &nextents, &dblkmap, check_dups) != 0) goto bad_out; /* * check attribute fork if necessary. attributes are * always stored in the regular filesystem. */ if (process_inode_attr_fork(mp, agno, ino, dino, type, dirty, &atotblocks, &anextents, check_dups, extra_attr_check, &retval)) goto bad_out; /* * enforce totblocks is 0 for misc types */ if (process_misc_ino_types_blocks(totblocks, lino, type)) goto clear_bad_out; /* * correct space counters if required */ if (process_inode_blocks_and_extents(dino, totblocks + atotblocks, nextents, anextents, lino, dirty) != 0) goto clear_bad_out; /* * do any semantic type-based checking here */ switch (type) { case XR_INO_DIR: if (xfs_sb_version_hasdirv2(&mp->m_sb) ? process_dir2(mp, lino, dino, ino_discovery, dirty, "", parent, dblkmap) : process_dir(mp, lino, dino, ino_discovery, dirty, "", parent, dblkmap)) { do_warn( _("problem with directory contents in inode %" PRIu64 "\n"), lino); goto clear_bad_out; } break; case XR_INO_SYMLINK: if (process_symlink(mp, lino, dino, dblkmap) != 0) { do_warn( _("problem with symbolic link in inode %" PRIu64 "\n"), lino); goto clear_bad_out; } break; default: break; } blkmap_free(dblkmap); /* * check nlinks feature, if it's a version 1 inode, * just leave nlinks alone. even if it's set wrong, * it'll be reset when read in. */ *dirty += process_check_inode_nlink_version(dino, lino); return retval; clear_bad_out: if (!no_modify) { *dirty += clear_dinode(mp, dino, lino); ASSERT(*dirty > 0); } bad_out: *used = is_free; *isa_dir = 0; blkmap_free(dblkmap); return 1; } /* * returns 1 if inode is used, 0 if free. * performs any necessary salvaging actions. * note that we leave the generation count alone * because nothing we could set it to would be * guaranteed to be correct so the best guess for * the correct value is just to leave it alone. * * The trick is detecting empty files. For those, * the core and the forks should all be in the "empty" * or zero-length state -- a zero or possibly minimum length * (in the case of dirs) extent list -- although inline directories * and symlinks might be handled differently. So it should be * possible to sanity check them against each other. * * If the forks are an empty extent list though, then forget it. * The file is toast anyway since we can't recover its storage. * * Parameters: * Ins: * mp -- mount structure * dino -- pointer to on-disk inode structure * agno/ino -- inode numbers * free -- whether the map thinks the inode is free (1 == free) * ino_discovery -- whether we should examine directory * contents to discover new inodes * check_dups -- whether we should check to see if the * inode references duplicate blocks * if so, we compare the inode's claimed * blocks against the contents of the * duplicate extent list but we don't * set the bitmap. If not, we set the * bitmap and try and detect multiply * claimed blocks using the bitmap. * Outs: * dirty -- whether we changed the inode (1 == yes) * used -- 1 if the inode is used, 0 if free. In no modify * mode, whether the inode should be used or free * isa_dir -- 1 if the inode is a directory, 0 if not. In * no modify mode, if the inode would be a dir or not. * * Return value -- 0 if the inode is good, 1 if it is/was corrupt */ int process_dinode( xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino, int was_free, int *dirty, int *used, int ino_discovery, int check_dups, int extra_attr_check, int *isa_dir, xfs_ino_t *parent) { const int verify_mode = 0; const int uncertain = 0; #ifdef XR_INODE_TRACE fprintf(stderr, _("processing inode %d/%d\n"), agno, ino); #endif return process_dinode_int(mp, dino, agno, ino, was_free, dirty, used, verify_mode, uncertain, ino_discovery, check_dups, extra_attr_check, isa_dir, parent); } /* * a more cursory check, check inode core, *DON'T* check forks * this basically just verifies whether the inode is an inode * and whether or not it has been totally trashed. returns 0 * if the inode passes the cursory sanity check, 1 otherwise. */ int verify_dinode( xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino) { xfs_ino_t parent; int used = 0; int dirty = 0; int isa_dir = 0; const int verify_mode = 1; const int check_dups = 0; const int ino_discovery = 0; const int uncertain = 0; return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used, verify_mode, uncertain, ino_discovery, check_dups, 0, &isa_dir, &parent); } /* * like above only for inode on the uncertain list. it sets * the uncertain flag which makes process_dinode_int quieter. * returns 0 if the inode passes the cursory sanity check, 1 otherwise. */ int verify_uncertain_dinode( xfs_mount_t *mp, xfs_dinode_t *dino, xfs_agnumber_t agno, xfs_agino_t ino) { xfs_ino_t parent; int used = 0; int dirty = 0; int isa_dir = 0; const int verify_mode = 1; const int check_dups = 0; const int ino_discovery = 0; const int uncertain = 1; return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used, verify_mode, uncertain, ino_discovery, check_dups, 0, &isa_dir, &parent); } xfsprogs-3.1.9ubuntu2/repair/dino_chunks.c0000664000000000000000000007730712062210562015560 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "globals.h" #include "agheader.h" #include "incore.h" #include "protos.h" #include "err_protos.h" #include "dir.h" #include "dinode.h" #include "versions.h" #include "prefetch.h" #include "progress.h" /* * validates inode block or chunk, returns # of good inodes * the dinodes are verified using verify_uncertain_dinode() which * means only the basic inode info is checked, no fork checks. */ static int check_aginode_block(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno) { xfs_dinode_t *dino_p; int i; int cnt = 0; xfs_buf_t *bp; /* * it's ok to read these possible inode blocks in one at * a time because they don't belong to known inodes (if * they did, we'd know about them courtesy of the incore inode * tree and we wouldn't be here and we stale the buffers out * so no one else will overlap them. */ bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn(_("cannot read agbno (%u/%u), disk block %" PRId64 "\n"), agno, agbno, XFS_AGB_TO_DADDR(mp, agno, agbno)); return(0); } for (i = 0; i < mp->m_sb.sb_inopblock; i++) { dino_p = xfs_make_iptr(mp, bp, i); if (!verify_uncertain_dinode(mp, dino_p, agno, XFS_OFFBNO_TO_AGINO(mp, agbno, i))) cnt++; } libxfs_putbuf(bp); return(cnt); } /* * tries to establish if the inode really exists in a valid * inode chunk. returns number of new inodes if things are good * and 0 if bad. start is the start of the discovered inode chunk. * routine assumes that ino is a legal inode number * (verified by verify_inum()). If the inode chunk turns out * to be good, this routine will put the inode chunk into * the good inode chunk tree if required. * * the verify_(ag)inode* family of routines are utility * routines called by check_uncertain_aginodes() and * process_uncertain_aginodes(). */ static int verify_inode_chunk(xfs_mount_t *mp, xfs_ino_t ino, xfs_ino_t *start_ino) { xfs_agnumber_t agno; xfs_agino_t agino; xfs_agino_t start_agino; xfs_agblock_t agbno; xfs_agblock_t start_agbno = 0; xfs_agblock_t end_agbno; xfs_agblock_t max_agbno; xfs_agblock_t cur_agbno; xfs_agblock_t chunk_start_agbno; xfs_agblock_t chunk_stop_agbno; ino_tree_node_t *irec_before_p = NULL; ino_tree_node_t *irec_after_p = NULL; ino_tree_node_t *irec_p; ino_tree_node_t *irec_next_p; int irec_cnt; int ino_cnt = 0; int num_blks; int i; int j; int state; xfs_extlen_t blen; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_INO_TO_AGBNO(mp, ino); *start_ino = NULLFSINO; ASSERT(XFS_IALLOC_BLOCKS(mp) > 0); if (agno == mp->m_sb.sb_agcount - 1) max_agbno = mp->m_sb.sb_dblocks - (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno; else max_agbno = mp->m_sb.sb_agblocks; /* * is the inode beyond the end of the AG? */ if (agbno >= max_agbno) return(0); /* * check for the easy case, inodes per block >= XFS_INODES_PER_CHUNK * (multiple chunks per block) */ if (XFS_IALLOC_BLOCKS(mp) == 1) { if (agbno > max_agbno) return 0; if (check_aginode_block(mp, agno, agino) == 0) return 0; pthread_mutex_lock(&ag_locks[agno]); state = get_bmap(agno, agbno); switch (state) { case XR_E_INO: do_warn( _("uncertain inode block %d/%d already known\n"), agno, agbno); break; case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: set_bmap(agno, agbno, XR_E_INO); break; case XR_E_MULT: case XR_E_INUSE: case XR_E_INUSE_FS: case XR_E_FS_MAP: /* * if block is already claimed, forget it. */ do_warn( _("inode block %d/%d multiply claimed, (state %d)\n"), agno, agbno, state); set_bmap(agno, agbno, XR_E_MULT); pthread_mutex_unlock(&ag_locks[agno]); return(0); default: do_warn( _("inode block %d/%d bad state, (state %d)\n"), agno, agbno, state); set_bmap(agno, agbno, XR_E_INO); break; } pthread_mutex_unlock(&ag_locks[agno]); start_agino = XFS_OFFBNO_TO_AGINO(mp, agbno, 0); *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino); /* * put new inode record(s) into inode tree */ for (j = 0; j < chunks_pblock; j++) { if ((irec_p = find_inode_rec(mp, agno, start_agino)) == NULL) { irec_p = set_inode_free_alloc(mp, agno, start_agino); for (i = 1; i < XFS_INODES_PER_CHUNK; i++) set_inode_free(irec_p, i); } if (start_agino <= agino && agino < start_agino + XFS_INODES_PER_CHUNK) set_inode_used(irec_p, agino - start_agino); start_agino += XFS_INODES_PER_CHUNK; ino_cnt += XFS_INODES_PER_CHUNK; } return(ino_cnt); } else if (fs_aligned_inodes) { /* * next easy case -- aligned inode filesystem. * just check out the chunk */ start_agbno = rounddown(XFS_INO_TO_AGBNO(mp, ino), fs_ino_alignment); end_agbno = start_agbno + XFS_IALLOC_BLOCKS(mp); /* * if this fs has aligned inodes but the end of the * chunk is beyond the end of the ag, this is a bad * chunk */ if (end_agbno > max_agbno) return(0); /* * check out all blocks in chunk */ ino_cnt = 0; for (cur_agbno = start_agbno; cur_agbno < end_agbno; cur_agbno++) { ino_cnt += check_aginode_block(mp, agno, cur_agbno); } /* * if we lose either 2 blocks worth of inodes or >25% of * the chunk, just forget it. */ if (ino_cnt < XFS_INODES_PER_CHUNK - 2 * mp->m_sb.sb_inopblock || ino_cnt < XFS_INODES_PER_CHUNK - 16) return(0); /* * ok, put the record into the tree, if no conflict. */ if (find_uncertain_inode_rec(agno, XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0))) return(0); start_agino = XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0); *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino); irec_p = set_inode_free_alloc(mp, agno, XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0)); for (i = 1; i < XFS_INODES_PER_CHUNK; i++) set_inode_free(irec_p, i); ASSERT(start_agino <= agino && start_agino + XFS_INODES_PER_CHUNK > agino); set_inode_used(irec_p, agino - start_agino); return(XFS_INODES_PER_CHUNK); } /* * hard case -- pre-6.3 filesystem. * set default start/end agbnos and ensure agbnos are legal. * we're setting a range [start_agbno, end_agbno) such that * a discovered inode chunk completely within that range * would include the inode passed into us. */ if (XFS_IALLOC_BLOCKS(mp) > 1) { if (agino > XFS_IALLOC_INODES(mp)) start_agbno = agbno - XFS_IALLOC_BLOCKS(mp) + 1; else start_agbno = 1; } end_agbno = agbno + XFS_IALLOC_BLOCKS(mp); if (end_agbno > max_agbno) end_agbno = max_agbno; /* * search tree for known inodes within +/- 1 inode chunk range */ irec_before_p = irec_after_p = NULL; find_inode_rec_range(mp, agno, XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0), XFS_OFFBNO_TO_AGINO(mp, end_agbno, mp->m_sb.sb_inopblock - 1), &irec_before_p, &irec_after_p); /* * if we have known inode chunks in our search range, establish * their start and end-points to tighten our search range. range * is [start, end) -- e.g. max/end agbno is one beyond the * last block to be examined. the avl routines work this way. */ if (irec_before_p) { /* * only one inode record in the range, move one boundary in */ if (irec_before_p == irec_after_p) { if (irec_before_p->ino_startnum < agino) start_agbno = XFS_AGINO_TO_AGBNO(mp, irec_before_p->ino_startnum + XFS_INODES_PER_CHUNK); else end_agbno = XFS_AGINO_TO_AGBNO(mp, irec_before_p->ino_startnum); } /* * find the start of the gap in the search range (which * should contain our unknown inode). if the only irec * within +/- 1 chunks starts after the inode we're * looking for, skip this stuff since the end_agbno * of the range has already been trimmed in to not * include that irec. */ if (irec_before_p->ino_startnum < agino) { irec_p = irec_before_p; irec_next_p = next_ino_rec(irec_p); while(irec_next_p != NULL && irec_p->ino_startnum + XFS_INODES_PER_CHUNK == irec_next_p->ino_startnum) { irec_p = irec_next_p; irec_next_p = next_ino_rec(irec_next_p); } start_agbno = XFS_AGINO_TO_AGBNO(mp, irec_p->ino_startnum) + XFS_IALLOC_BLOCKS(mp); /* * we know that the inode we're trying to verify isn't * in an inode chunk so the next ino_rec marks the end * of the gap -- is it within the search range? */ if (irec_next_p != NULL && agino + XFS_IALLOC_INODES(mp) >= irec_next_p->ino_startnum) end_agbno = XFS_AGINO_TO_AGBNO(mp, irec_next_p->ino_startnum); } ASSERT(start_agbno < end_agbno); } /* * if the gap is too small to contain a chunk, we lose. * this means that inode chunks known to be good surround * the inode in question and that the space between them * is too small for a legal inode chunk */ if (end_agbno - start_agbno < XFS_IALLOC_BLOCKS(mp)) return(0); /* * now grunge around the disk, start at the inode block and * go in each direction until you hit a non-inode block or * run into a range boundary. A non-inode block is block * with *no* good inodes in it. Unfortunately, we can't * co-opt bad blocks into inode chunks (which might take * care of disk blocks that turn into zeroes) because the * filesystem could very well allocate two inode chunks * with a one block file in between and we'd zap the file. * We're better off just losing the rest of the * inode chunk instead. */ for (cur_agbno = agbno; cur_agbno >= start_agbno; cur_agbno--) { /* * if the block has no inodes, it's a bad block so * break out now without decrementing cur_agbno so * chunk start blockno will be set to the last good block */ if (!(irec_cnt = check_aginode_block(mp, agno, cur_agbno))) break; ino_cnt += irec_cnt; } chunk_start_agbno = cur_agbno + 1; for (cur_agbno = agbno + 1; cur_agbno < end_agbno; cur_agbno++) { /* * if the block has no inodes, it's a bad block so * break out now without incrementing cur_agbno so * chunk start blockno will be set to the block * immediately after the last good block. */ if (!(irec_cnt = check_aginode_block(mp, agno, cur_agbno))) break; ino_cnt += irec_cnt; } chunk_stop_agbno = cur_agbno; num_blks = chunk_stop_agbno - chunk_start_agbno; if (num_blks < XFS_IALLOC_BLOCKS(mp) || ino_cnt == 0) return(0); /* * XXX - later - if the entire range is selected and they're all * good inodes, keep searching in either direction. * until you the range of inodes end, then split into chunks * for now, just take one chunk's worth starting at the lowest * possible point and hopefully we'll pick the rest up later. * * XXX - if we were going to fix up an inode chunk for * any good inodes in the chunk, this is where we would * do it. For now, keep it simple and lose the rest of * the chunk */ if (num_blks % XFS_IALLOC_BLOCKS(mp) != 0) { num_blks = rounddown(num_blks, XFS_IALLOC_BLOCKS(mp)); chunk_stop_agbno = chunk_start_agbno + num_blks; } /* * ok, we've got a candidate inode chunk. now we have to * verify that we aren't trying to use blocks that are already * in use. If so, mark them as multiply claimed since odds * are very low that we found this chunk by stumbling across * user data -- we're probably here as a result of a directory * entry or an iunlinked pointer */ pthread_mutex_lock(&ag_locks[agno]); for (cur_agbno = chunk_start_agbno; cur_agbno < chunk_stop_agbno; cur_agbno += blen) { state = get_bmap_ext(agno, cur_agbno, chunk_stop_agbno, &blen); switch (state) { case XR_E_MULT: case XR_E_INUSE: case XR_E_INUSE_FS: case XR_E_FS_MAP: do_warn( _("inode block %d/%d multiply claimed, (state %d)\n"), agno, cur_agbno, state); set_bmap_ext(agno, cur_agbno, blen, XR_E_MULT); pthread_mutex_unlock(&ag_locks[agno]); return 0; case XR_E_INO: do_error( _("uncertain inode block overlap, agbno = %d, ino = %" PRIu64 "\n"), agbno, ino); break; default: break; } } pthread_mutex_unlock(&ag_locks[agno]); /* * ok, chunk is good. put the record into the tree if required, * and fill in the bitmap. All inodes will be marked as "free" * except for the one that led us to discover the chunk. That's * ok because we'll override the free setting later if the * contents of the inode indicate it's in use. */ start_agino = XFS_OFFBNO_TO_AGINO(mp, chunk_start_agbno, 0); *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino); ASSERT(find_inode_rec(mp, agno, start_agino) == NULL); irec_p = set_inode_free_alloc(mp, agno, start_agino); for (i = 1; i < XFS_INODES_PER_CHUNK; i++) set_inode_free(irec_p, i); ASSERT(start_agino <= agino && start_agino + XFS_INODES_PER_CHUNK > agino); set_inode_used(irec_p, agino - start_agino); pthread_mutex_lock(&ag_locks[agno]); for (cur_agbno = chunk_start_agbno; cur_agbno < chunk_stop_agbno; cur_agbno += blen) { state = get_bmap_ext(agno, cur_agbno, chunk_stop_agbno, &blen); switch (state) { case XR_E_INO: do_error( _("uncertain inode block %" PRIu64 " already known\n"), XFS_AGB_TO_FSB(mp, agno, cur_agbno)); break; case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: set_bmap_ext(agno, cur_agbno, blen, XR_E_INO); break; case XR_E_MULT: case XR_E_INUSE: case XR_E_INUSE_FS: case XR_E_FS_MAP: do_error( _("inode block %d/%d multiply claimed, (state %d)\n"), agno, cur_agbno, state); break; default: do_warn( _("inode block %d/%d bad state, (state %d)\n"), agno, cur_agbno, state); set_bmap_ext(agno, cur_agbno, blen, XR_E_INO); break; } } pthread_mutex_unlock(&ag_locks[agno]); return(ino_cnt); } /* * same as above only for ag inode chunks */ static int verify_aginode_chunk(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino, xfs_agino_t *agino_start) { xfs_ino_t ino; int res; res = verify_inode_chunk(mp, XFS_AGINO_TO_INO(mp, agno, agino), &ino); if (res) *agino_start = XFS_INO_TO_AGINO(mp, ino); else *agino_start = NULLAGINO; return(res); } /* * this does the same as the two above only it returns a pointer * to the inode record in the good inode tree */ static ino_tree_node_t * verify_aginode_chunk_irec(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agino_t agino) { xfs_agino_t start_agino; ino_tree_node_t *irec = NULL; if (verify_aginode_chunk(mp, agno, agino, &start_agino)) irec = find_inode_rec(mp, agno, start_agino); return(irec); } /* * processes an inode allocation chunk/block, returns 1 on I/O errors, * 0 otherwise * * *bogus is set to 1 if the entire set of inodes is bad. */ /* ARGSUSED */ static int process_inode_chunk( xfs_mount_t *mp, xfs_agnumber_t agno, int num_inos, ino_tree_node_t *first_irec, int ino_discovery, int check_dups, int extra_attr_check, int *bogus) { xfs_ino_t parent; ino_tree_node_t *ino_rec; xfs_buf_t **bplist; xfs_dinode_t *dino; int icnt; int status; int is_used; int state; int ino_dirty; int irec_offset; int ibuf_offset; xfs_agino_t agino; xfs_agblock_t agbno; xfs_ino_t ino; int dirty = 0; int isa_dir = 0; int blks_per_cluster; int cluster_count; int bp_index; int cluster_offset; ASSERT(first_irec != NULL); ASSERT(XFS_AGINO_TO_OFFSET(mp, first_irec->ino_startnum) == 0); *bogus = 0; ASSERT(XFS_IALLOC_BLOCKS(mp) > 0); blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; if (blks_per_cluster == 0) blks_per_cluster = 1; cluster_count = XFS_INODES_PER_CHUNK / inodes_per_cluster; if (cluster_count == 0) cluster_count = 1; /* * get all blocks required to read in this chunk (may wind up * having to process more chunks in a multi-chunk per block fs) */ agbno = XFS_AGINO_TO_AGBNO(mp, first_irec->ino_startnum); /* * set up first irec */ ino_rec = first_irec; bplist = malloc(cluster_count * sizeof(xfs_buf_t *)); if (bplist == NULL) do_error(_("failed to allocate %zd bytes of memory\n"), cluster_count * sizeof(xfs_buf_t *)); for (bp_index = 0; bp_index < cluster_count; bp_index++) { pftrace("about to read off %llu in AG %d", XFS_AGB_TO_DADDR(mp, agno, agbno), agno); bplist[bp_index] = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, blks_per_cluster), 0); if (!bplist[bp_index]) { do_warn(_("cannot read inode %" PRIu64 ", disk block %" PRId64 ", cnt %d\n"), XFS_AGINO_TO_INO(mp, agno, first_irec->ino_startnum), XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, blks_per_cluster)); while (bp_index > 0) { bp_index--; libxfs_putbuf(bplist[bp_index]); } free(bplist); return(1); } agbno += blks_per_cluster; pftrace("readbuf %p (%llu, %d) in AG %d", bplist[bp_index], (long long)XFS_BUF_ADDR(bplist[bp_index]), XFS_BUF_COUNT(bplist[bp_index]), agno); } agbno = XFS_AGINO_TO_AGBNO(mp, first_irec->ino_startnum); /* * initialize counters */ irec_offset = 0; ibuf_offset = 0; cluster_offset = 0; icnt = 0; status = 0; bp_index = 0; /* * verify inode chunk if necessary */ if (ino_discovery) { for (;;) { /* * make inode pointer */ dino = xfs_make_iptr(mp, bplist[bp_index], cluster_offset); agino = irec_offset + ino_rec->ino_startnum; /* * we always think that the root and realtime * inodes are verified even though we may have * to reset them later to keep from losing the * chunk that they're in */ if (verify_dinode(mp, dino, agno, agino) == 0 || (agno == 0 && (mp->m_sb.sb_rootino == agino || mp->m_sb.sb_rsumino == agino || mp->m_sb.sb_rbmino == agino))) status++; irec_offset++; icnt++; cluster_offset++; if (icnt == XFS_IALLOC_INODES(mp) && irec_offset == XFS_INODES_PER_CHUNK) { /* * done! - finished up irec and block * simultaneously */ break; } else if (irec_offset == XFS_INODES_PER_CHUNK) { /* * get new irec (multiple chunks per block fs) */ ino_rec = next_ino_rec(ino_rec); ASSERT(ino_rec->ino_startnum == agino + 1); irec_offset = 0; } if (cluster_offset == inodes_per_cluster) { bp_index++; cluster_offset = 0; } } /* * if chunk/block is bad, blow it off. the inode records * will be deleted by the caller if appropriate. */ if (!status) { *bogus = 1; for (bp_index = 0; bp_index < cluster_count; bp_index++) libxfs_putbuf(bplist[bp_index]); free(bplist); return(0); } /* * reset irec and counters */ ino_rec = first_irec; irec_offset = 0; cluster_offset = 0; bp_index = 0; icnt = 0; status = 0; } /* * mark block as an inode block in the incore bitmap */ pthread_mutex_lock(&ag_locks[agno]); state = get_bmap(agno, agbno); switch (state) { case XR_E_INO: /* already marked */ break; case XR_E_UNKNOWN: case XR_E_FREE: case XR_E_FREE1: set_bmap(agno, agbno, XR_E_INO); break; case XR_E_BAD_STATE: do_error(_("bad state in block map %d\n"), state); break; default: set_bmap(agno, agbno, XR_E_MULT); do_warn(_("inode block %" PRIu64 " multiply claimed, state was %d\n"), XFS_AGB_TO_FSB(mp, agno, agbno), state); break; } pthread_mutex_unlock(&ag_locks[agno]); for (;;) { /* * make inode pointer */ dino = xfs_make_iptr(mp, bplist[bp_index], cluster_offset); agino = irec_offset + ino_rec->ino_startnum; ino = XFS_AGINO_TO_INO(mp, agno, agino); is_used = 3; ino_dirty = 0; parent = 0; status = process_dinode(mp, dino, agno, agino, is_inode_free(ino_rec, irec_offset), &ino_dirty, &is_used,ino_discovery, check_dups, extra_attr_check, &isa_dir, &parent); ASSERT(is_used != 3); if (ino_dirty) dirty = 1; /* * XXX - if we want to try and keep * track of whether we need to bang on * the inode maps (instead of just * blindly reconstructing them like * we do now, this is where to start. */ if (is_used) { if (is_inode_free(ino_rec, irec_offset)) { if (verbose || no_modify) { do_warn( _("imap claims in-use inode %" PRIu64 " is free, "), ino); } if (verbose || !no_modify) do_warn(_("correcting imap\n")); else do_warn(_("would correct imap\n")); } set_inode_used(ino_rec, irec_offset); /* * store on-disk nlink count for comparing in phase 7 */ set_inode_disk_nlinks(ino_rec, irec_offset, dino->di_version > 1 ? be32_to_cpu(dino->di_nlink) : be16_to_cpu(dino->di_onlink)); } else { set_inode_free(ino_rec, irec_offset); } /* * if we lose the root inode, or it turns into * a non-directory, that allows us to double-check * later whether or not we need to reinitialize it. */ if (isa_dir) { set_inode_isadir(ino_rec, irec_offset); /* * we always set the parent but * we may as well wait until * phase 4 (no inode discovery) * because the parent info will * be solid then. */ if (!ino_discovery) { ASSERT(parent != 0); set_inode_parent(ino_rec, irec_offset, parent); ASSERT(parent == get_inode_parent(ino_rec, irec_offset)); } } else { clear_inode_isadir(ino_rec, irec_offset); } if (status) { if (mp->m_sb.sb_rootino == ino) { need_root_inode = 1; if (!no_modify) { do_warn( _("cleared root inode %" PRIu64 "\n"), ino); } else { do_warn( _("would clear root inode %" PRIu64 "\n"), ino); } } else if (mp->m_sb.sb_rbmino == ino) { need_rbmino = 1; if (!no_modify) { do_warn( _("cleared realtime bitmap inode %" PRIu64 "\n"), ino); } else { do_warn( _("would clear realtime bitmap inode %" PRIu64 "\n"), ino); } } else if (mp->m_sb.sb_rsumino == ino) { need_rsumino = 1; if (!no_modify) { do_warn( _("cleared realtime summary inode %" PRIu64 "\n"), ino); } else { do_warn( _("would clear realtime summary inode %" PRIu64 "\n"), ino); } } else if (!no_modify) { do_warn(_("cleared inode %" PRIu64 "\n"), ino); } else { do_warn(_("would have cleared inode %" PRIu64 "\n"), ino); } } irec_offset++; ibuf_offset++; icnt++; cluster_offset++; if (icnt == XFS_IALLOC_INODES(mp) && irec_offset == XFS_INODES_PER_CHUNK) { /* * done! - finished up irec and block simultaneously */ for (bp_index = 0; bp_index < cluster_count; bp_index++) { pftrace("put/writebuf %p (%llu) in AG %d", bplist[bp_index], (long long) XFS_BUF_ADDR(bplist[bp_index]), agno); if (dirty && !no_modify) libxfs_writebuf(bplist[bp_index], 0); else libxfs_putbuf(bplist[bp_index]); } free(bplist); break; } else if (ibuf_offset == mp->m_sb.sb_inopblock) { /* * mark block as an inode block in the incore bitmap * and reset inode buffer offset counter */ ibuf_offset = 0; agbno++; pthread_mutex_lock(&ag_locks[agno]); state = get_bmap(agno, agbno); switch (state) { case XR_E_INO: /* already marked */ break; case XR_E_UNKNOWN: case XR_E_FREE: case XR_E_FREE1: set_bmap(agno, agbno, XR_E_INO); break; case XR_E_BAD_STATE: do_error(_("bad state in block map %d\n"), state); break; default: set_bmap(agno, agbno, XR_E_MULT); do_warn( _("inode block %" PRIu64 " multiply claimed, state was %d\n"), XFS_AGB_TO_FSB(mp, agno, agbno), state); break; } pthread_mutex_unlock(&ag_locks[agno]); } else if (irec_offset == XFS_INODES_PER_CHUNK) { /* * get new irec (multiple chunks per block fs) */ ino_rec = next_ino_rec(ino_rec); ASSERT(ino_rec->ino_startnum == agino + 1); irec_offset = 0; } if (cluster_offset == inodes_per_cluster) { bp_index++; cluster_offset = 0; } } return(0); } /* * check all inodes mentioned in the ag's incore inode maps. * the map may be incomplete. If so, we'll catch the missing * inodes (hopefully) when we traverse the directory tree. * check_dirs is set to 1 if directory inodes should be * processed for internal consistency, parent setting and * discovery of unknown inodes. this only happens * in phase 3. check_dups is set to 1 if we're looking for * inodes that reference duplicate blocks so we can trash * the inode right then and there. this is set only in * phase 4 after we've run through and set the bitmap once. */ void process_aginodes( xfs_mount_t *mp, prefetch_args_t *pf_args, xfs_agnumber_t agno, int ino_discovery, int check_dups, int extra_attr_check) { int num_inos, bogus; ino_tree_node_t *ino_rec, *first_ino_rec, *prev_ino_rec; #ifdef XR_PF_TRACE int count; #endif first_ino_rec = ino_rec = findfirst_inode_rec(agno); while (ino_rec != NULL) { /* * paranoia - step through inode records until we step * through a full allocation of inodes. this could * be an issue in big-block filesystems where a block * can hold more than one inode chunk. make sure to * grab the record corresponding to the beginning of * the next block before we call the processing routines. */ num_inos = XFS_INODES_PER_CHUNK; while (num_inos < XFS_IALLOC_INODES(mp) && ino_rec != NULL) { /* * inodes chunks will always be aligned and sized * correctly */ if ((ino_rec = next_ino_rec(ino_rec)) != NULL) num_inos += XFS_INODES_PER_CHUNK; } ASSERT(num_inos == XFS_IALLOC_INODES(mp)); if (pf_args) { sem_post(&pf_args->ra_count); #ifdef XR_PF_TRACE sem_getvalue(&pf_args->ra_count, &count); pftrace("processing inode chunk %p in AG %d (sem count = %d)", first_ino_rec, agno, count); #endif } if (process_inode_chunk(mp, agno, num_inos, first_ino_rec, ino_discovery, check_dups, extra_attr_check, &bogus)) { /* XXX - i/o error, we've got a problem */ abort(); } if (!bogus) first_ino_rec = ino_rec = next_ino_rec(ino_rec); else { /* * inodes pointed to by this record are * completely bogus, blow the records for * this chunk out. * the inode block(s) will get reclaimed * in phase 4 when the block map is * reconstructed after inodes claiming * duplicate blocks are deleted. */ num_inos = 0; ino_rec = first_ino_rec; while (num_inos < XFS_IALLOC_INODES(mp) && ino_rec != NULL) { prev_ino_rec = ino_rec; if ((ino_rec = next_ino_rec(ino_rec)) != NULL) num_inos += XFS_INODES_PER_CHUNK; get_inode_rec(mp, agno, prev_ino_rec); free_inode_rec(agno, prev_ino_rec); } first_ino_rec = ino_rec; } PROG_RPT_INC(prog_rpt_done[agno], num_inos); } } /* * verify the uncertain inode list for an ag. * Good inodes get moved into the good inode tree. * returns 0 if there are no uncertain inode records to * be processed, 1 otherwise. This routine destroys the * the entire uncertain inode tree for the ag as a side-effect. */ void check_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno) { ino_tree_node_t *irec; ino_tree_node_t *nrec; xfs_agino_t start; xfs_agino_t i; xfs_agino_t agino; int got_some; nrec = NULL; got_some = 0; clear_uncertain_ino_cache(agno); if ((irec = findfirst_uncertain_inode_rec(agno)) == NULL) return; /* * the trick here is to find a contiguous range * of inodes, make sure that it doesn't overlap * with a known to exist chunk, and then make * sure it is a number of entire chunks. * we check on-disk once we have an idea of what's * going on just to double-check. * * process the uncertain inode record list and look * on disk to see if the referenced inodes are good */ do_warn(_("found inodes not in the inode allocation tree\n")); do { /* * check every confirmed (which in this case means * inode that we really suspect to be an inode) inode */ for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (!is_inode_confirmed(irec, i)) continue; agino = i + irec->ino_startnum; if (verify_aginum(mp, agno, agino)) continue; if (nrec != NULL && nrec->ino_startnum <= agino && agino < nrec->ino_startnum + XFS_INODES_PER_CHUNK) continue; if ((nrec = find_inode_rec(mp, agno, agino)) == NULL) if (!verify_aginum(mp, agno, agino)) if (verify_aginode_chunk(mp, agno, agino, &start)) got_some = 1; } get_uncertain_inode_rec(mp, agno, irec); free_inode_rec(agno, irec); irec = findfirst_uncertain_inode_rec(agno); } while (irec != NULL); if (got_some) do_warn(_("found inodes not in the inode allocation tree\n")); return; } /* * verify and process the uncertain inodes for an ag. * this is different from check_ in that we can't just * move the good inodes into the good inode tree and let * process_aginodes() deal with them because this gets called * after process_aginodes() has been run on the ag inode tree. * So we have to process the inodes as well as verify since * we don't want to rerun process_aginodes() on a tree that has * mostly been processed. * * Note that if this routine does process some inodes, it can * add uncertain inodes to any ag which would require that * the routine be called again to process those newly-added * uncertain inodes. * * returns 0 if no inodes were processed and 1 if inodes * were processed (and it is possible that new uncertain * inodes were discovered). * * as a side-effect, this routine tears down the uncertain * inode tree for the ag. */ int process_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno) { ino_tree_node_t *irec; ino_tree_node_t *nrec; xfs_agino_t agino; int i; int bogus; int cnt; int got_some; #ifdef XR_INODE_TRACE fprintf(stderr, "in process_uncertain_aginodes, agno = %d\n", agno); #endif got_some = 0; clear_uncertain_ino_cache(agno); if ((irec = findfirst_uncertain_inode_rec(agno)) == NULL) return(0); nrec = NULL; do { /* * check every confirmed inode */ for (cnt = i = 0; i < XFS_INODES_PER_CHUNK; i++) { if (!is_inode_confirmed(irec, i)) continue; cnt++; agino = i + irec->ino_startnum; #ifdef XR_INODE_TRACE fprintf(stderr, "ag inode = %d (0x%x)\n", agino, agino); #endif /* * skip over inodes already processed (in the * good tree), bad inode numbers, and inode numbers * pointing to bogus inodes */ if (verify_aginum(mp, agno, agino)) continue; if (nrec != NULL && nrec->ino_startnum <= agino && agino < nrec->ino_startnum + XFS_INODES_PER_CHUNK) continue; if ((nrec = find_inode_rec(mp, agno, agino)) != NULL) continue; /* * verify the chunk. if good, it will be * added to the good inode tree. */ if ((nrec = verify_aginode_chunk_irec(mp, agno, agino)) == NULL) continue; got_some = 1; /* * process the inode record we just added * to the good inode tree. The inode * processing may add more records to the * uncertain inode lists. */ if (process_inode_chunk(mp, agno, XFS_IALLOC_INODES(mp), nrec, 1, 0, 0, &bogus)) { /* XXX - i/o error, we've got a problem */ abort(); } } ASSERT(cnt != 0); /* * now return the uncertain inode record to the free pool * and pull another one off the list for processing */ get_uncertain_inode_rec(mp, agno, irec); free_inode_rec(agno, irec); irec = findfirst_uncertain_inode_rec(agno); } while (irec != NULL); if (got_some) do_warn(_("found inodes not in the inode allocation tree\n")); return(1); } xfsprogs-3.1.9ubuntu2/repair/attr_repair.c0000664000000000000000000007762712062210562015575 0ustar /* * Copyright (c) 2000-2002,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "globals.h" #include "err_protos.h" #include "attr_repair.h" #include "dir.h" #include "dinode.h" #include "bmap.h" #include "protos.h" static int xfs_acl_valid(xfs_acl_disk_t *daclp); static int xfs_mac_valid(xfs_mac_label_t *lp); /* * For attribute repair, there are 3 formats to worry about. First, is * shortform attributes which reside in the inode. Second is the leaf * form, and lastly the btree. Much of this models after the directory * structure so code resembles the directory repair cases. * For shortform case, if an attribute looks corrupt, it is removed. * If that leaves the shortform down to 0 attributes, it's okay and * will appear to just have a null attribute fork. Some checks are done * for validity of the value field based on what the security needs are. * Calls will be made to xfs_mac_valid or xfs_acl_valid routines if the * security attributes exist. They will be cleared if invalid. * No other values will be checked. The DMF folks do not have current * requirements, but may in the future. * * For leaf block attributes, it requires more processing. One sticky * point is that the attributes can be local (within the leaf) or * remote (outside the leaf in other blocks). Thinking of local only * if you get a bad attribute, and want to delete just one, it's a-okay * if it remains large enough to still be a leaf block attribute. Otherwise, * it may have to be converted to shortform. How to convert this and when * is an issue. This call is happening in Phase3. Phase5 will capture empty * blocks, but Phase6 allows you to use the libxfs library which knows * how to handle attributes in the kernel for converting formats. What we * could do is mark an attribute to be cleared now, but in phase6 somehow * have it cleared for real and then the format changed to shortform if * applicable. Since this requires more work than I anticipate can be * accomplished for the next release, we will instead just say any bad * attribute in the leaf block will make the entire attribute fork be * cleared. The simplest way to do that is to ignore the leaf format, and * call clear_dinode_attr to just make a shortform attribute fork with * zero entries. * * Another issue with handling repair on leaf attributes is the remote * blocks. To make sure that they look good and are not used multiple times * by the attribute fork, some mechanism to keep track of all them is necessary. * Do this in the future, time permitting. For now, note that there is no * check for remote blocks and their allocations. * * For btree formatted attributes, the model can follow directories. That * would mean go down the tree to the leftmost leaf. From there moving down * the links and processing each. They would call back up the tree, to verify * that the tree structure is okay. Any problems will result in the attribute * fork being emptied and put in shortform format. */ /* * This routine just checks what security needs are for attribute values * only called when root flag is set, otherwise these names could exist in * in user attribute land without a conflict. * If value is non-zero, then a remote attribute is being passed in */ static int valuecheck(char *namevalue, char *value, int namelen, int valuelen) { /* for proper alignment issues, get the structs and memmove the values */ xfs_mac_label_t macl; xfs_acl_t thisacl; void *valuep; int clearit = 0; if ((strncmp(namevalue, SGI_ACL_FILE, SGI_ACL_FILE_SIZE) == 0) || (strncmp(namevalue, SGI_ACL_DEFAULT, SGI_ACL_DEFAULT_SIZE) == 0)) { if (value == NULL) { memset(&thisacl, 0, sizeof(xfs_acl_t)); memmove(&thisacl, namevalue+namelen, valuelen); valuep = &thisacl; } else valuep = value; if (xfs_acl_valid((xfs_acl_disk_t *)valuep) != 0) { clearit = 1; do_warn( _("entry contains illegal value in attribute named SGI_ACL_FILE " "or SGI_ACL_DEFAULT\n")); } } else if (strncmp(namevalue, SGI_MAC_FILE, SGI_MAC_FILE_SIZE) == 0) { if (value == NULL) { memset(&macl, 0, sizeof(xfs_mac_label_t)); memmove(&macl, namevalue+namelen, valuelen); valuep = &macl; } else valuep = value; if (xfs_mac_valid((xfs_mac_label_t *)valuep) != 1) { /* 1 is valid */ /* * if sysconf says MAC enabled, * temp = mac_from_text("msenhigh/mintlow", NULL) * copy it to value, update valuelen, totsize * This causes pushing up or down of all following * attributes, forcing a attribute format change!! * else clearit = 1; */ clearit = 1; do_warn( _("entry contains illegal value in attribute named SGI_MAC_LABEL\n")); } } else if (strncmp(namevalue, SGI_CAP_FILE, SGI_CAP_FILE_SIZE) == 0) { if ( valuelen != sizeof(xfs_cap_set_t)) { clearit = 1; do_warn( _("entry contains illegal value in attribute named SGI_CAP_FILE\n")); } } return(clearit); } /* * this routine validates the attributes in shortform format. * a non-zero return repair value means certain attributes are bogus * and were cleared if possible. Warnings do not generate error conditions * if you cannot modify the structures. repair is set to 1, if anything * was fixed. */ static int process_shortform_attr( xfs_ino_t ino, xfs_dinode_t *dip, int *repair) { xfs_attr_shortform_t *asf; xfs_attr_sf_entry_t *currententry, *nextentry, *tempentry; int i, junkit; int currentsize, remainingspace; *repair = 0; asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip); /* Assumption: hdr.totsize is less than a leaf block and was checked * by lclinode for valid sizes. Check the count though. */ if (asf->hdr.count == 0) /* then the total size should just be the header length */ if (be16_to_cpu(asf->hdr.totsize) != sizeof(xfs_attr_sf_hdr_t)) { /* whoops there's a discrepancy. Clear the hdr */ if (!no_modify) { do_warn( _("there are no attributes in the fork for inode %" PRIu64 "\n"), ino); asf->hdr.totsize = cpu_to_be16(sizeof(xfs_attr_sf_hdr_t)); *repair = 1; return(1); } else { do_warn( _("would junk the attribute fork since count is 0 for inode %" PRIu64 "\n"), ino); return(1); } } currentsize = sizeof(xfs_attr_sf_hdr_t); remainingspace = be16_to_cpu(asf->hdr.totsize) - currentsize; nextentry = &asf->list[0]; for (i = 0; i < asf->hdr.count; i++) { currententry = nextentry; junkit = 0; /* don't go off the end if the hdr.count was off */ if ((currentsize + (sizeof(xfs_attr_sf_entry_t) - 1)) > be16_to_cpu(asf->hdr.totsize)) break; /* get out and reset count and totSize */ /* if the namelen is 0, can't get to the rest of the entries */ if (currententry->namelen == 0) { do_warn(_("zero length name entry in attribute fork,")); if (!no_modify) { do_warn( _(" truncating attributes for inode %" PRIu64 " to %d\n"), ino, i); *repair = 1; break; /* and then update hdr fields */ } else { do_warn( _(" would truncate attributes for inode %" PRIu64 " to %d\n"), ino, i); break; } } else { /* It's okay to have a 0 length valuelen, but do a * rough check to make sure we haven't gone outside of * totsize. */ if (remainingspace < currententry->namelen || ((remainingspace - currententry-> namelen) < currententry->valuelen)) { do_warn( _("name or value attribute lengths are too large,\n")); if (!no_modify) { do_warn( _(" truncating attributes for inode %" PRIu64 " to %d\n"), ino, i); *repair = 1; break; /* and then update hdr fields */ } else { do_warn( _(" would truncate attributes for inode %" PRIu64 " to %d\n"), ino, i); break; } } } /* namecheck checks for / and null terminated for file names. * attributes names currently follow the same rules. */ if (namecheck((char *)¤tentry->nameval[0], currententry->namelen)) { do_warn( _("entry contains illegal character in shortform attribute name\n")); junkit = 1; } if (currententry->flags & XFS_ATTR_INCOMPLETE) { do_warn( _("entry has INCOMPLETE flag on in shortform attribute\n")); junkit = 1; } /* Only check values for root security attributes */ if (currententry->flags & XFS_ATTR_ROOT) junkit = valuecheck((char *)¤tentry->nameval[0], NULL, currententry->namelen, currententry->valuelen); remainingspace = remainingspace - XFS_ATTR_SF_ENTSIZE(currententry); if (junkit) { if (!no_modify) { /* get rid of only this entry */ do_warn( _("removing attribute entry %d for inode %" PRIu64 "\n"), i, ino); tempentry = (xfs_attr_sf_entry_t *) ((__psint_t) currententry + XFS_ATTR_SF_ENTSIZE(currententry)); memmove(currententry,tempentry,remainingspace); asf->hdr.count -= 1; i--; /* no worries, it will wrap back to 0 */ *repair = 1; continue; /* go back up now */ } else { do_warn( _("would remove attribute entry %d for inode %" PRIu64 "\n"), i, ino); } } /* Let's get ready for the next entry... */ nextentry = (xfs_attr_sf_entry_t *)((__psint_t) nextentry + XFS_ATTR_SF_ENTSIZE(currententry)); currentsize = currentsize + XFS_ATTR_SF_ENTSIZE(currententry); } /* end the loop */ if (asf->hdr.count != i) { if (no_modify) { do_warn( _("would have corrected attribute entry count in inode %" PRIu64 " from %d to %d\n"), ino, asf->hdr.count, i); } else { do_warn( _("corrected attribute entry count in inode %" PRIu64 ", was %d, now %d\n"), ino, asf->hdr.count, i); asf->hdr.count = i; *repair = 1; } } /* ASSUMPTION: currentsize <= totsize */ if (be16_to_cpu(asf->hdr.totsize) != currentsize) { if (no_modify) { do_warn( _("would have corrected attribute totsize in inode %" PRIu64 " from %d to %d\n"), ino, be16_to_cpu(asf->hdr.totsize), currentsize); } else { do_warn( _("corrected attribute entry totsize in inode %" PRIu64 ", was %d, now %d\n"), ino, be16_to_cpu(asf->hdr.totsize), currentsize); asf->hdr.totsize = cpu_to_be16(currentsize); *repair = 1; } } return(*repair); } /* This routine brings in blocks from disk one by one and assembles them * in the value buffer. If get_bmapi gets smarter later to return an extent * or list of extents, that would be great. For now, we don't expect too * many blocks per remote value, so one by one is sufficient. */ static int rmtval_get(xfs_mount_t *mp, xfs_ino_t ino, blkmap_t *blkmap, xfs_dablk_t blocknum, int valuelen, char* value) { xfs_dfsbno_t bno; xfs_buf_t *bp; int clearit = 0, i = 0, length = 0, amountdone = 0; /* ASSUMPTION: valuelen is a valid number, so use it for looping */ /* Note that valuelen is not a multiple of blocksize */ while (amountdone < valuelen) { bno = blkmap_get(blkmap, blocknum + i); if (bno == NULLDFSBNO) { do_warn( _("remote block for attributes of inode %" PRIu64 " is missing\n"), ino); clearit = 1; break; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read remote block for attributes of inode %" PRIu64 "\n"), ino); clearit = 1; break; } ASSERT(mp->m_sb.sb_blocksize == XFS_BUF_COUNT(bp)); length = MIN(XFS_BUF_COUNT(bp), valuelen - amountdone); memmove(value, XFS_BUF_PTR(bp), length); amountdone += length; value += length; i++; libxfs_putbuf(bp); } return (clearit); } /* The block is read in. The magic number and forward / backward * links are checked by the caller process_leaf_attr. * If any problems occur the routine returns with non-zero. In * this case the next step is to clear the attribute fork, by * changing it to shortform and zeroing it out. Forkoff need not * be changed. */ static int process_leaf_attr_local( xfs_attr_leafblock_t *leaf, int i, xfs_attr_leaf_entry_t *entry, xfs_dahash_t last_hashval, xfs_dablk_t da_bno, xfs_ino_t ino) { xfs_attr_leaf_name_local_t *local; local = xfs_attr_leaf_name_local(leaf, i); if (local->namelen == 0 || namecheck((char *)&local->nameval[0], local->namelen)) { do_warn( _("attribute entry %d in attr block %u, inode %" PRIu64 " has bad name (namelen = %d)\n"), i, da_bno, ino, local->namelen); return -1; } /* Check on the hash value. Checking order of values * is not necessary, since one wrong clears the whole * fork. If the ordering's wrong, it's caught here or * the kernel code has a bug with transaction logging * or attributes itself. Being paranoid, let's check * ordering anyway in case both the name value and the * hashvalue were wrong but matched. Unlikely, however. */ if (be32_to_cpu(entry->hashval) != libxfs_da_hashname( &local->nameval[0], local->namelen) || be32_to_cpu(entry->hashval) < last_hashval) { do_warn( _("bad hashvalue for attribute entry %d in attr block %u, inode %" PRIu64 "\n"), i, da_bno, ino); return -1; } /* Only check values for root security attributes */ if (entry->flags & XFS_ATTR_ROOT) { if (valuecheck((char *)&local->nameval[0], NULL, local->namelen, be16_to_cpu(local->valuelen))) { do_warn( _("bad security value for attribute entry %d in attr block %u, inode %" PRIu64 "\n"), i, da_bno, ino); return -1; } } return xfs_attr_leaf_entsize_local(local->namelen, be16_to_cpu(local->valuelen)); } static int process_leaf_attr_remote( xfs_attr_leafblock_t *leaf, int i, xfs_attr_leaf_entry_t *entry, xfs_dahash_t last_hashval, xfs_dablk_t da_bno, xfs_ino_t ino, xfs_mount_t *mp, blkmap_t *blkmap) { xfs_attr_leaf_name_remote_t *remotep; char* value; remotep = xfs_attr_leaf_name_remote(leaf, i); if (remotep->namelen == 0 || namecheck((char *)&remotep->name[0], remotep->namelen) || be32_to_cpu(entry->hashval) != libxfs_da_hashname((uchar_t *)&remotep->name[0], remotep->namelen) || be32_to_cpu(entry->hashval) < last_hashval || be32_to_cpu(remotep->valueblk) == 0) { do_warn( _("inconsistent remote attribute entry %d in attr block %u, ino %" PRIu64 "\n"), i, da_bno, ino); return -1; } if (!(entry->flags & XFS_ATTR_ROOT)) goto out; value = malloc(be32_to_cpu(remotep->valuelen)); if (value == NULL) { do_warn( _("cannot malloc enough for remotevalue attribute for inode %" PRIu64 "\n"), ino); do_warn(_("SKIPPING this remote attribute\n")); goto out; } if (rmtval_get(mp, ino, blkmap, be32_to_cpu(remotep->valueblk), be32_to_cpu(remotep->valuelen), value)) { do_warn( _("remote attribute get failed for entry %d, inode %" PRIu64 "\n"), i, ino); goto bad_free_out; } if (valuecheck((char *)&remotep->name[0], value, remotep->namelen, be32_to_cpu(remotep->valuelen))) { do_warn( _("remote attribute value check failed for entry %d, inode %" PRIu64 "\n"), i, ino); goto bad_free_out; } free(value); out: return xfs_attr_leaf_entsize_remote(remotep->namelen); bad_free_out: free(value); return -1; } static int process_leaf_attr_block( xfs_mount_t *mp, xfs_attr_leafblock_t *leaf, xfs_dablk_t da_bno, xfs_ino_t ino, blkmap_t *blkmap, xfs_dahash_t last_hashval, xfs_dahash_t *current_hashval, int *repair) { xfs_attr_leaf_entry_t *entry; int i, start, stop, clearit, usedbs, firstb, thissize; da_freemap_t *attr_freemap; clearit = usedbs = 0; *repair = 0; firstb = mp->m_sb.sb_blocksize; stop = sizeof(xfs_attr_leaf_hdr_t); /* does the count look sorta valid? */ if (be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { do_warn( _("bad attribute count %d in attr block %u, inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.count), da_bno, ino); return (1); } attr_freemap = alloc_da_freemap(mp); (void) set_da_freemap(mp, attr_freemap, 0, stop); /* go thru each entry checking for problems */ for (i = 0, entry = &leaf->entries[0]; i < be16_to_cpu(leaf->hdr.count); i++, entry++) { /* check if index is within some boundary. */ if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { do_warn( _("bad attribute nameidx %d in attr block %u, inode %" PRIu64 "\n"), be16_to_cpu(entry->nameidx), da_bno, ino); clearit = 1; break; } if (entry->flags & XFS_ATTR_INCOMPLETE) { /* we are inconsistent state. get rid of us */ do_warn( _("attribute entry #%d in attr block %u, inode %" PRIu64 " is INCOMPLETE\n"), i, da_bno, ino); clearit = 1; break; } /* mark the entry used */ start = (__psint_t)&leaf->entries[i] - (__psint_t)leaf; stop = start + sizeof(xfs_attr_leaf_entry_t); if (set_da_freemap(mp, attr_freemap, start, stop)) { do_warn( _("attribute entry %d in attr block %u, inode %" PRIu64 " claims already used space\n"), i, da_bno, ino); clearit = 1; break; /* got an overlap */ } if (entry->flags & XFS_ATTR_LOCAL) thissize = process_leaf_attr_local(leaf, i, entry, last_hashval, da_bno, ino); else thissize = process_leaf_attr_remote(leaf, i, entry, last_hashval, da_bno, ino, mp, blkmap); if (thissize < 0) { clearit = 1; break; } *current_hashval = last_hashval = be32_to_cpu(entry->hashval); if (set_da_freemap(mp, attr_freemap, be16_to_cpu(entry->nameidx), be16_to_cpu(entry->nameidx) + thissize)) { do_warn( _("attribute entry %d in attr block %u, inode %" PRIu64 " claims used space\n"), i, da_bno, ino); clearit = 1; break; /* got an overlap */ } usedbs += thissize; if (be16_to_cpu(entry->nameidx) < firstb) firstb = be16_to_cpu(entry->nameidx); } /* end the loop */ if (!clearit) { /* verify the header information is correct */ /* if the holes flag is set, don't reset first_used unless it's * pointing to used bytes. we're being conservative here * since the block will get compacted anyhow by the kernel. */ if ((leaf->hdr.holes == 0 && firstb != be16_to_cpu(leaf->hdr.firstused)) || be16_to_cpu(leaf->hdr.firstused) > firstb) { if (!no_modify) { do_warn( _("- resetting first used heap value from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.firstused), firstb, da_bno, ino); leaf->hdr.firstused = cpu_to_be16(firstb); *repair = 1; } else { do_warn( _("- would reset first used value from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.firstused), firstb, da_bno, ino); } } if (usedbs != be16_to_cpu(leaf->hdr.usedbytes)) { if (!no_modify) { do_warn( _("- resetting usedbytes cnt from %d to %d in " "block %u of attribute fork of inode %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.usedbytes), usedbs, da_bno, ino); leaf->hdr.usedbytes = cpu_to_be16(usedbs); *repair = 1; } else { do_warn( _("- would reset usedbytes cnt from %d to %d in " "block %u of attribute fork of %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.usedbytes), usedbs, da_bno, ino); } } /* there's a lot of work in process_leaf_dir_block to go thru * checking for holes and compacting if appropiate. I don't think * attributes need all that, so let's just leave the holes. If * we discover later that this is a good place to do compaction * we can add it then. */ } free(attr_freemap); return (clearit); /* and repair */ } /* * returns 0 if the attribute fork is ok, 1 if it has to be junked. */ static int process_leaf_attr_level(xfs_mount_t *mp, da_bt_cursor_t *da_cursor) { int repair; xfs_attr_leafblock_t *leaf; xfs_buf_t *bp; xfs_ino_t ino; xfs_dfsbno_t dev_bno; xfs_dablk_t da_bno; xfs_dablk_t prev_bno; xfs_dahash_t current_hashval = 0; xfs_dahash_t greatest_hashval; da_bno = da_cursor->level[0].bno; ino = da_cursor->ino; prev_bno = 0; do { repair = 0; dev_bno = blkmap_get(da_cursor->blkmap, da_bno); /* * 0 is the root block and no block * pointer can point to the root block of the btree */ ASSERT(da_bno != 0); if (dev_bno == NULLDFSBNO) { do_warn( _("can't map block %u for attribute fork for inode %" PRIu64 "\n"), da_bno, ino); goto error_out; } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, dev_bno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read file block %u (fsbno %" PRIu64 ") for attribute fork of inode %" PRIu64 "\n"), da_bno, dev_bno, ino); goto error_out; } leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); /* check magic number for leaf directory btree block */ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { do_warn( _("bad attribute leaf magic %#x for inode %" PRIu64 "\n"), leaf->hdr.info.magic, ino); libxfs_putbuf(bp); goto error_out; } /* * for each block, process the block, verify its path, * then get next block. update cursor values along the way */ if (process_leaf_attr_block(mp, leaf, da_bno, ino, da_cursor->blkmap, current_hashval, &greatest_hashval, &repair)) { libxfs_putbuf(bp); goto error_out; } /* * index can be set to hdr.count so match the * indexes of the interior blocks -- which at the * end of the block will point to 1 after the final * real entry in the block */ da_cursor->level[0].hashval = greatest_hashval; da_cursor->level[0].bp = bp; da_cursor->level[0].bno = da_bno; da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count); da_cursor->level[0].dirty = repair; if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) { do_warn( _("bad sibling back pointer for block %u in attribute fork for inode %" PRIu64 "\n"), da_bno, ino); libxfs_putbuf(bp); goto error_out; } prev_bno = da_bno; da_bno = be32_to_cpu(leaf->hdr.info.forw); if (da_bno != 0 && verify_da_path(mp, da_cursor, 0)) { libxfs_putbuf(bp); goto error_out; } current_hashval = greatest_hashval; if (repair && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); } while (da_bno != 0); if (verify_final_da_path(mp, da_cursor, 0)) { /* * verify the final path up (right-hand-side) if still ok */ do_warn( _("bad hash path in attribute fork for inode %" PRIu64 "\n"), da_cursor->ino); goto error_out; } /* releases all buffers holding interior btree blocks */ release_da_cursor(mp, da_cursor, 0); return(0); error_out: /* release all buffers holding interior btree blocks */ err_release_da_cursor(mp, da_cursor, 0); return(1); } /* * a node directory is a true btree -- where the attribute fork * has gotten big enough that it is represented as a non-trivial (e.g. * has more than just a block) btree. * * Note that if we run into any problems, we will trash the attribute fork. * * returns 0 if things are ok, 1 if bad * Note this code has been based off process_node_dir. */ static int process_node_attr( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, blkmap_t *blkmap) { xfs_dablk_t bno; int error = 0; da_bt_cursor_t da_cursor; /* * try again -- traverse down left-side of tree until we hit * the left-most leaf block setting up the btree cursor along * the way. Then walk the leaf blocks left-to-right, calling * a parent-verification routine each time we traverse a block. */ memset(&da_cursor, 0, sizeof(da_bt_cursor_t)); da_cursor.active = 0; da_cursor.type = 0; da_cursor.ino = ino; da_cursor.dip = dip; da_cursor.greatest_bno = 0; da_cursor.blkmap = blkmap; /* * now process interior node. don't have any buffers held in this path. */ error = traverse_int_dablock(mp, &da_cursor, &bno, XFS_ATTR_FORK); if (error == 0) return(1); /* 0 means unsuccessful */ /* * now pass cursor and bno into leaf-block processing routine * the leaf dir level routine checks the interior paths * up to the root including the final right-most path. */ return (process_leaf_attr_level(mp, &da_cursor)); } /* * Start processing for a leaf or fuller btree. * A leaf directory is one where the attribute fork is too big for * the inode but is small enough to fit into one btree block * outside the inode. This code is modelled after process_leaf_dir_block. * * returns 0 if things are ok, 1 if bad (attributes needs to be junked) * repair is set, if anything was changed, but attributes can live thru it */ static int process_longform_attr( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, blkmap_t *blkmap, int *repair) /* out - 1 if something was fixed */ { xfs_attr_leafblock_t *leaf; xfs_dfsbno_t bno; xfs_buf_t *bp; xfs_dahash_t next_hashval; int repairlinks = 0; *repair = 0; bno = blkmap_get(blkmap, 0); if ( bno == NULLDFSBNO ) { if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS && be16_to_cpu(dip->di_anextents) == 0) return(0); /* the kernel can handle this state */ do_warn( _("block 0 of inode %" PRIu64 " attribute fork is missing\n"), ino); return(1); } /* FIX FOR bug 653709 -- EKN */ if (mp->m_sb.sb_agcount < XFS_FSB_TO_AGNO(mp, bno)) { do_warn( _("agno of attribute fork of inode %" PRIu64 " out of regular partition\n"), ino); return(1); } bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1), 0); if (!bp) { do_warn( _("can't read block 0 of inode %" PRIu64 " attribute fork\n"), ino); return(1); } /* verify leaf block */ leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); /* check sibling pointers in leaf block or root block 0 before * we have to release the btree block */ if (be32_to_cpu(leaf->hdr.info.forw) != 0 || be32_to_cpu(leaf->hdr.info.back) != 0) { if (!no_modify) { do_warn( _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino); repairlinks = 1; leaf->hdr.info.forw = cpu_to_be32(0); leaf->hdr.info.back = cpu_to_be32(0); } else { do_warn( _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino); } } /* * use magic number to tell us what type of attribute this is. * it's possible to have a node or leaf attribute in either an * extent format or btree format attribute fork. */ switch (be16_to_cpu(leaf->hdr.info.magic)) { case XFS_ATTR_LEAF_MAGIC: /* leaf-form attribute */ if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap, 0, &next_hashval, repair)) { /* the block is bad. lose the attribute fork. */ libxfs_putbuf(bp); return(1); } *repair = *repair || repairlinks; break; case XFS_DA_NODE_MAGIC: /* btree-form attribute */ /* must do this now, to release block 0 before the traversal */ if (repairlinks) { *repair = 1; libxfs_writebuf(bp, 0); } else libxfs_putbuf(bp); return (process_node_attr(mp, ino, dip, blkmap)); /* + repair */ default: do_warn( _("bad attribute leaf magic # %#x for dir ino %" PRIu64 "\n"), be16_to_cpu(leaf->hdr.info.magic), ino); libxfs_putbuf(bp); return(1); } if (*repair && !no_modify) libxfs_writebuf(bp, 0); else libxfs_putbuf(bp); return(0); /* repair may be set */ } static int xfs_acl_from_disk(struct xfs_acl **aclp, struct xfs_acl_disk *dacl) { int count; xfs_acl_t *acl; xfs_acl_entry_t *ace; xfs_acl_entry_disk_t *dace, *end; count = be32_to_cpu(dacl->acl_cnt); if (count > XFS_ACL_MAX_ENTRIES) { do_warn(_("Too many ACL entries, count %d\n"), count); *aclp = NULL; return EINVAL; } end = &dacl->acl_entry[0] + count; acl = malloc((int)((char *)end - (char *)dacl)); if (!acl) { do_warn(_("cannot malloc enough for ACL attribute\n")); do_warn(_("SKIPPING this ACL\n")); *aclp = NULL; return ENOMEM; } acl->acl_cnt = count; ace = &acl->acl_entry[0]; for (dace = &dacl->acl_entry[0]; dace < end; ace++, dace++) { ace->ae_tag = be32_to_cpu(dace->ae_tag); ace->ae_id = be32_to_cpu(dace->ae_id); ace->ae_perm = be16_to_cpu(dace->ae_perm); } *aclp = acl; return 0; } /* * returns 1 if attributes got cleared * and 0 if things are ok. */ int process_attributes( xfs_mount_t *mp, xfs_ino_t ino, xfs_dinode_t *dip, blkmap_t *blkmap, int *repair) /* returned if we did repair */ { int err; __u8 aformat = dip->di_aformat; xfs_attr_shortform_t *asf; asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip); if (aformat == XFS_DINODE_FMT_LOCAL) { ASSERT(be16_to_cpu(asf->hdr.totsize) <= XFS_DFORK_ASIZE(dip, mp)); err = process_shortform_attr(ino, dip, repair); } else if (aformat == XFS_DINODE_FMT_EXTENTS || aformat == XFS_DINODE_FMT_BTREE) { err = process_longform_attr(mp, ino, dip, blkmap, repair); /* if err, convert this to shortform and clear it */ /* if repair and no error, it's taken care of */ } else { do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"), aformat, ino); err = 1; } return (err); /* and repair */ } /* * Validate an ACL */ static int xfs_acl_valid(xfs_acl_disk_t *daclp) { xfs_acl_t *aclp; xfs_acl_entry_t *entry, *e; int user = 0, group = 0, other = 0, mask = 0, mask_required = 0; int i, j; if (daclp == NULL) goto acl_invalid; switch (xfs_acl_from_disk(&aclp, daclp)) { case ENOMEM: return 0; case EINVAL: goto acl_invalid; default: break; } for (i = 0; i < aclp->acl_cnt; i++) { entry = &aclp->acl_entry[i]; if (entry->ae_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) goto acl_invalid; switch (entry->ae_tag) { case ACL_USER_OBJ: if (user++) goto acl_invalid; break; case ACL_GROUP_OBJ: if (group++) goto acl_invalid; break; case ACL_OTHER: if (other++) goto acl_invalid; break; case ACL_USER: case ACL_GROUP: for (j = i + 1; j < aclp->acl_cnt; j++) { e = &aclp->acl_entry[j]; if (e->ae_id == entry->ae_id && e->ae_tag == entry->ae_tag) goto acl_invalid; } mask_required++; break; case ACL_MASK: if (mask++) goto acl_invalid; break; default: goto acl_invalid; } } if (!user || !group || !other || (mask_required && !mask)) goto acl_invalid; free(aclp); return 0; acl_invalid: free(aclp); errno = EINVAL; return (-1); } /* * Check a category or division set to ensure that all values are in * ascending order and each division or category appears only once. */ static int __check_setvalue(const unsigned short *list, unsigned short count) { unsigned short i; for (i = 1; i < count ; i++) if (list[i] <= list[i-1]) return -1; return 0; } /* * xfs_mac_valid(lp) * Check the validity of a MAC label. */ static int xfs_mac_valid(xfs_mac_label_t *lp) { if (lp == NULL) return (0); /* * if the total category set and division set is greater than 250 * report error */ if ((lp->ml_catcount + lp->ml_divcount) > XFS_MAC_MAX_SETS) return(0); /* * check whether the msentype value is valid, and do they have * appropriate level, category association. */ switch (lp->ml_msen_type) { case XFS_MSEN_ADMIN_LABEL: case XFS_MSEN_EQUAL_LABEL: case XFS_MSEN_HIGH_LABEL: case XFS_MSEN_MLD_HIGH_LABEL: case XFS_MSEN_LOW_LABEL: case XFS_MSEN_MLD_LOW_LABEL: if (lp->ml_level != 0 || lp->ml_catcount > 0 ) return (0); break; case XFS_MSEN_TCSEC_LABEL: case XFS_MSEN_MLD_LABEL: if (lp->ml_catcount > 0 && __check_setvalue(lp->ml_list, lp->ml_catcount) == -1) return (0); break; case XFS_MSEN_UNKNOWN_LABEL: default: return (0); } /* * check whether the minttype value is valid, and do they have * appropriate grade, division association. */ switch (lp->ml_mint_type) { case XFS_MINT_BIBA_LABEL: if (lp->ml_divcount > 0 && __check_setvalue(lp->ml_list + lp->ml_catcount, lp->ml_divcount) == -1) return(0); break; case XFS_MINT_EQUAL_LABEL: case XFS_MINT_HIGH_LABEL: case XFS_MINT_LOW_LABEL: if (lp->ml_grade != 0 || lp->ml_divcount > 0 ) return(0); break; default: return(0); } return (1); } xfsprogs-3.1.9ubuntu2/repair/attr_repair.h0000664000000000000000000001001211140033220015537 0ustar /* * Copyright (c) 2000-2002,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_ATTRREPAIR_H #define _XR_ATTRREPAIR_H /* * Access Control Lists */ #define ACL_USER_OBJ 0x01 /* owner */ #define ACL_USER 0x02 /* additional users */ #define ACL_GROUP_OBJ 0x04 /* group */ #define ACL_GROUP 0x08 /* additional groups */ #define ACL_MASK 0x10 /* mask entry */ #define ACL_OTHER 0x20 /* other entry */ #define ACL_READ 04 #define ACL_WRITE 02 #define ACL_EXECUTE 01 typedef __uint16_t xfs_acl_perm_t; typedef __int32_t xfs_acl_type_t; typedef __int32_t xfs_acl_tag_t; typedef __int32_t xfs_acl_id_t; typedef struct xfs_acl_entry { xfs_acl_tag_t ae_tag; xfs_acl_id_t ae_id; xfs_acl_perm_t ae_perm; } xfs_acl_entry_t; #define XFS_ACL_MAX_ENTRIES 25 typedef struct xfs_acl { __int32_t acl_cnt; xfs_acl_entry_t acl_entry[XFS_ACL_MAX_ENTRIES]; } xfs_acl_t; typedef struct xfs_acl_entry_disk { __be32 ae_tag; __be32 ae_id; __be16 ae_perm; } xfs_acl_entry_disk_t; typedef struct xfs_acl_disk { __be32 acl_cnt; xfs_acl_entry_disk_t acl_entry[XFS_ACL_MAX_ENTRIES]; } xfs_acl_disk_t; #define SGI_ACL_FILE "SGI_ACL_FILE" #define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT" #define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1) #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) /* * Mandatory Access Control Labels (IRIX) */ #define XFS_MAC_MAX_SETS 250 typedef struct xfs_mac_label { __uint8_t ml_msen_type; /* MSEN label type */ __uint8_t ml_mint_type; /* MINT label type */ __uint8_t ml_level; /* Hierarchical level */ __uint8_t ml_grade; /* Hierarchical grade */ __uint16_t ml_catcount; /* Category count */ __uint16_t ml_divcount; /* Division count */ /* Category set, then Division set */ __uint16_t ml_list[XFS_MAC_MAX_SETS]; } xfs_mac_label_t; /* MSEN label type names. Choose an upper case ASCII character. */ #define XFS_MSEN_ADMIN_LABEL 'A' /* Admin: low 100% */ #define XR_BAD_INO_ALIGN 15 /* bad inode alignment value */ #define XR_INSUFF_SEC_SB 16 /* not enough matching secondary sbs */ #define XR_BAD_SB_UNIT 17 /* bad stripe unit */ #define XR_BAD_SB_WIDTH 18 /* bad stripe width */ #define XR_BAD_SVN 19 /* bad shared version number */ #define XR_BAD_ERR_CODE 20 /* Bad error code */ /* XFS filesystem (il)legal values */ #define XR_LOG2BSIZE_MIN 9 /* min/max fs blocksize (log2) */ #define XR_LOG2BSIZE_MAX 16 /* 2^XR_* == blocksize */ #define NUM_SBS 8 /* max # of sbs to verify */ #define NUM_AGH_SECTS 4 /* # of components in an ag header */ /* * secondary sb mask -- if the secondary sb feature bits has a * the partial sb mask bit set, then you depend on the fields * in it up to and including sb_inoalignmt but the unused part of the * sector may have trash in it. If the sb has any bits set that are in * the good mask, then the entire sb and sector are good (was zero'ed * by mkfs). The third mask is for filesystems made by pre-6.5 campus * alpha mkfs's. Those are rare so we'll check for those under * a special option. */ #define XR_PART_SECSB_VNMASK 0x0F80 /* >= XFS_SB_VERSION_ALIGNBIT */ #define XR_GOOD_SECSB_VNMASK 0x0F00 /* >= XFS_SB_VERSION_DALIGNBIT */ #define XR_ALPHA_SECSB_VNMASK 0x0180 /* DALIGN|ALIGN bits */ /* global variables for xfs_repair */ /* arguments and argument flag variables */ EXTERN char *fs_name; /* name of filesystem */ EXTERN int verbose; /* verbose flag, mostly for debugging */ /* for reading stuff in manually (bypassing libsim) */ EXTERN char *iobuf; /* large buffer */ EXTERN int iobuf_size; EXTERN char *smallbuf; /* small (1-4 page) buffer */ EXTERN int smallbuf_size; EXTERN char *sb_bufs[NUM_SBS]; /* superblock buffers */ EXTERN int sbbuf_size; /* direct I/O info */ EXTERN int minio_align; /* min I/O size and alignment */ EXTERN int mem_align; /* memory alignment */ EXTERN int max_iosize; /* max I/O size */ /* file descriptors */ EXTERN int fs_fd; /* filesystem fd */ /* command-line flags */ EXTERN int verbose; EXTERN int no_modify; EXTERN int dangerously; /* live dangerously ... fix ro mount */ EXTERN int isa_file; EXTERN int zap_log; EXTERN int dumpcore; /* abort, not exit on fatal errs */ EXTERN int delete_attr_ok; /* can clear attrs w/o clearing files */ EXTERN int force_geo; /* can set geo on low confidence info */ EXTERN int assume_xfs; /* assume we have an xfs fs */ EXTERN int pre_65_beta; /* fs was mkfs'ed by a version earlier * than 6.5-beta */ EXTERN char *log_name; /* Name of log device */ EXTERN int log_spec; /* Log dev specified as option */ EXTERN char *rt_name; /* Name of realtime device */ EXTERN int rt_spec; /* Realtime dev specified as option */ EXTERN int convert_lazy_count; /* Convert lazy-count mode on/off */ EXTERN int lazy_count; /* What to set if to if converting */ /* misc status variables */ EXTERN int primary_sb_modified; EXTERN int bad_ino_btree; EXTERN int clear_sunit; EXTERN int fs_is_dirty; /* for hunting down the root inode */ EXTERN int need_root_inode; EXTERN int need_root_dotdot; EXTERN int need_rbmino; EXTERN int need_rsumino; EXTERN int lost_quotas; EXTERN int have_uquotino; EXTERN int have_gquotino; EXTERN int lost_uquotino; EXTERN int lost_gquotino; EXTERN int lost_pquotino; EXTERN xfs_agino_t first_prealloc_ino; EXTERN xfs_agino_t last_prealloc_ino; EXTERN xfs_agblock_t bnobt_root; EXTERN xfs_agblock_t bcntbt_root; EXTERN xfs_agblock_t inobt_root; /* configuration vars -- fs geometry dependent */ EXTERN int inodes_per_block; EXTERN int inodes_per_cluster; EXTERN unsigned int glob_agcount; EXTERN int chunks_pblock; /* # of 64-ino chunks per allocation */ EXTERN int max_symlink_blocks; EXTERN __int64_t fs_max_file_offset; /* realtime info */ EXTERN xfs_rtword_t *btmcompute; EXTERN xfs_suminfo_t *sumcompute; /* inode tree records have full or partial backptr fields ? */ EXTERN int full_ino_ex_data;/* * if 1, use ino_ex_data_t component * of ino_un union, if 0, use * parent_list_t component. see * incore.h for more details */ #define ORPHANAGE "lost+found" /* superblock counters */ EXTERN __uint64_t sb_icount; /* allocated (made) inodes */ EXTERN __uint64_t sb_ifree; /* free inodes */ EXTERN __uint64_t sb_fdblocks; /* free data blocks */ EXTERN __uint64_t sb_frextents; /* free realtime extents */ /* superblock geometry info */ EXTERN xfs_extlen_t sb_inoalignmt; EXTERN __uint32_t sb_unit; EXTERN __uint32_t sb_width; EXTERN pthread_mutex_t *ag_locks; EXTERN int report_interval; EXTERN __uint64_t *prog_rpt_done; EXTERN int ag_stride; EXTERN int thread_count; #endif /* _XFS_REPAIR_GLOBAL_H */ xfsprogs-3.1.9ubuntu2/repair/init.c0000664000000000000000000000520712062210562014205 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "globals.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" #include "pthread.h" #include "avl.h" #include "dir.h" #include "bmap.h" #include "incore.h" #include "prefetch.h" #include static void ts_create(void) { pthread_key_create(&dblkmap_key, NULL); pthread_key_create(&ablkmap_key, NULL); } static void increase_rlimit(void) { struct rlimit rl; /* Increase limits */ if (getrlimit(RLIMIT_FSIZE, &rl) == -1) { perror("getrlimit"); fprintf(stderr, _("getrlimit(RLIMIT_FSIZE) failed!\n")); exit(1); } if (rl.rlim_cur != RLIM_INFINITY) { rl.rlim_max = rl.rlim_cur = RLIM_INFINITY; if (setrlimit(RLIMIT_FSIZE, &rl) == -1) { perror("setrlimit"); fprintf(stderr, _("setrlimit failed - current: %lld, max: %lld\n"), (unsigned long long)rl.rlim_cur, (unsigned long long)rl.rlim_max); exit(1); } } } void xfs_init(libxfs_init_t *args) { memset(args, 0, sizeof(libxfs_init_t)); if (isa_file) { args->disfile = 1; args->dname = fs_name; args->volname = NULL; } else { args->disfile = 0; args->volname = fs_name; args->dname = NULL; } if (log_spec) { /* External log specified */ args->logname = log_name; args->lisfile = (isa_file?1:0); /* XXX assume data file also means log file */ /* REVISIT: Need to do fs sanity / log validity checking */ } if (rt_spec) { /* RT device specified */ args->rtname = rt_name; args->risfile = (isa_file?1:0); /* XXX assume data file also means rt file */ } args->usebuflock = do_prefetch; args->setblksize = 0; args->isdirect = LIBXFS_DIRECT; if (no_modify) args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE); else if (dangerously) args->isreadonly = (LIBXFS_ISINACTIVE | LIBXFS_DANGEROUSLY); else args->isreadonly = LIBXFS_EXCLUSIVELY; if (!libxfs_init(args)) do_error(_("couldn't initialize XFS library\n")); ts_create(); increase_rlimit(); pftrace_init(); } xfsprogs-3.1.9ubuntu2/repair/versions.c0000664000000000000000000001757311140033220015111 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #define EXTERN #include "versions.h" #undef EXTERN #include "err_protos.h" #include "globals.h" void update_sb_version(xfs_mount_t *mp) { xfs_sb_t *sb; __uint16_t vn; sb = &mp->m_sb; if (fs_attributes && !xfs_sb_version_hasattr(sb)) { ASSERT(fs_attributes_allowed); xfs_sb_version_addattr(sb); } if (fs_attributes2 && !xfs_sb_version_hasattr2(sb)) { ASSERT(fs_attributes2_allowed); xfs_sb_version_addattr2(sb); } if (fs_inode_nlink && !xfs_sb_version_hasnlink(sb)) { ASSERT(fs_inode_nlink_allowed); xfs_sb_version_addnlink(sb); } /* * fix up the superblock version number and feature bits, * turn off quota bits and flags if the filesystem doesn't * have quotas. */ if (fs_quotas) { if (!xfs_sb_version_hasquota(sb)) { ASSERT(fs_quotas_allowed); xfs_sb_version_addquota(sb); } /* * protect against stray bits in the quota flag field */ if (sb->sb_qflags & ~(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| XFS_PQUOTA_ACCT)) { /* * update the incore superblock, if we're in * no_modify mode, it'll never get flushed out * so this is ok. */ do_warn(_("bogus quota flags 0x%x set in superblock"), sb->sb_qflags & ~(XFS_UQUOTA_ACCT| XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| XFS_PQUOTA_ACCT)); sb->sb_qflags &= (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD| XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT| XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD| XFS_PQUOTA_ACCT); if (!no_modify) do_warn(_(", bogus flags will be cleared\n")); else do_warn(_(", bogus flags would be cleared\n")); } } else { sb->sb_qflags = 0; if (xfs_sb_version_hasquota(sb)) { lost_quotas = 1; vn = sb->sb_versionnum; vn &= ~XFS_SB_VERSION_QUOTABIT; if (!(vn & XFS_SB_VERSION_ALLFBITS)) vn = xfs_sb_version_toold(vn); ASSERT(vn != 0); sb->sb_versionnum = vn; } } if (!fs_aligned_inodes && xfs_sb_version_hasalign(sb)) sb->sb_versionnum &= ~XFS_SB_VERSION_ALIGNBIT; } /* * returns 0 if things are fine, 1 if we don't understand * this superblock version. Sets superblock geometry-dependent * global variables. */ int parse_sb_version(xfs_sb_t *sb) { int issue_warning; fs_attributes = 0; fs_attributes2 = 0; fs_inode_nlink = 0; fs_quotas = 0; fs_aligned_inodes = 0; fs_sb_feature_bits = 0; fs_ino_alignment = 0; fs_has_extflgbit = 0; have_uquotino = 0; have_gquotino = 0; issue_warning = 0; /* * ok, check to make sure that the sb isn't newer * than we are */ if (xfs_sb_version_hasextflgbit(sb)) { fs_has_extflgbit = 1; if (!fs_has_extflgbit_allowed) { issue_warning = 1; do_warn( _("This filesystem has uninitialized extent flags.\n")); } } if (xfs_sb_version_hasshared(sb)) { fs_shared = 1; if (!fs_shared_allowed) { issue_warning = 1; do_warn(_("This filesystem is marked shared.\n")); } } if (issue_warning) { do_warn( _("This filesystem uses feature(s) not yet supported in this release.\n" "Please run a more recent version of xfs_repair.\n")); return(1); } if (!xfs_sb_good_version(sb)) { do_warn(_("WARNING: unknown superblock version %d\n"), XFS_SB_VERSION_NUM(sb)); do_warn( _("This filesystem contains features not understood by this program.\n")); return(1); } if (XFS_SB_VERSION_NUM(sb) == XFS_SB_VERSION_4) { if (!fs_sb_feature_bits_allowed) { if (!no_modify) { do_warn( _("WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twill be downgraded. This may cause loss of filesystem meta-data\n")); } else { do_warn( _("WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twould be downgraded. This might cause loss of filesystem\n" "\tmeta-data.\n")); } } else { fs_sb_feature_bits = 1; } } if (xfs_sb_version_hasattr(sb)) { if (!fs_attributes_allowed) { if (!no_modify) { do_warn( _("WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attributes will be removed.\n")); } else { do_warn( _("WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attributes would be removed.\n")); } } else { fs_attributes = 1; } } if (xfs_sb_version_hasattr2(sb)) { if (!fs_attributes2_allowed) { if (!no_modify) { do_warn( _("WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attr2 attributes will be removed.\n")); } else { do_warn( _("WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attr2 attributes would be removed.\n")); } } else { fs_attributes2 = 1; } } if (xfs_sb_version_hasnlink(sb)) { if (!fs_inode_nlink_allowed) { if (!no_modify) { do_warn( _("WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem will be downgraded and\n" "\tall version 2 inodes will be converted to version 1 inodes.\n" "\tThis may cause some hard links to files to be destroyed\n")); } else { do_warn( _("WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem would be downgraded and\n" "\tall version 2 inodes would be converted to version 1 inodes.\n" "\tThis might cause some hard links to files to be destroyed\n")); } } else { fs_inode_nlink = 1; } } if (xfs_sb_version_hasquota(sb)) { if (!fs_quotas_allowed) { if (!no_modify) { do_warn( _("WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem will be downgraded and\n" "\tall quota information will be removed.\n")); } else { do_warn( _("WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem would be downgraded and\n" "\tall quota information would be removed.\n")); } } else { fs_quotas = 1; if (sb->sb_uquotino != 0 && sb->sb_uquotino != NULLFSINO) have_uquotino = 1; if (sb->sb_gquotino != 0 && sb->sb_gquotino != NULLFSINO) have_gquotino = 1; } } if (xfs_sb_version_hasalign(sb)) { if (fs_aligned_inodes_allowed) { fs_aligned_inodes = 1; fs_ino_alignment = sb->sb_inoalignmt; } else { if (!no_modify) { do_warn( _("WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem will be downgraded.\n" "\tThis will permanently degrade the performance of this filesystem.\n")); } else { do_warn( _("WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem would be downgraded.\n" "\tThis would permanently degrade the performance of this filesystem.\n")); } } } /* * calculate maximum file offset for this geometry */ fs_max_file_offset = 0x7fffffffffffffffLL >> sb->sb_blocklog; return(0); } xfsprogs-3.1.9ubuntu2/repair/incore.c0000664000000000000000000001644011650373061014530 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "avl.h" #include "btree.h" #include "globals.h" #include "incore.h" #include "agheader.h" #include "protos.h" #include "err_protos.h" #include "threads.h" /* * The following manages the in-core bitmap of the entire filesystem * using extents in a btree. * * The btree items will point to one of the state values below, * rather than storing the value itself in the pointer. */ static int states[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; static struct btree_root **ag_bmap; static void update_bmap( struct btree_root *bmap, unsigned long offset, xfs_extlen_t blen, void *new_state) { unsigned long end = offset + blen; int *cur_state; unsigned long cur_key; int *next_state; unsigned long next_key; int *prev_state; cur_state = btree_find(bmap, offset, &cur_key); if (!cur_state) return; if (offset == cur_key) { /* if the start is the same as the "item" extent */ if (cur_state == new_state) return; /* * Note: this may be NULL if we are updating the map for * the superblock. */ prev_state = btree_peek_prev(bmap, NULL); next_state = btree_peek_next(bmap, &next_key); if (next_key > end) { /* different end */ if (new_state == prev_state) { /* #1: prev has same state, move offset up */ btree_update_key(bmap, offset, end); return; } /* #4: insert new extent after, update current value */ btree_update_value(bmap, offset, new_state); btree_insert(bmap, end, cur_state); return; } /* same end (and same start) */ if (new_state == next_state) { /* next has same state */ if (new_state == prev_state) { /* #3: merge prev & next */ btree_delete(bmap, offset); btree_delete(bmap, end); return; } /* #8: merge next */ btree_update_value(bmap, offset, new_state); btree_delete(bmap, end); return; } /* same start, same end, next has different state */ if (new_state == prev_state) { /* #5: prev has same state */ btree_delete(bmap, offset); return; } /* #6: update value only */ btree_update_value(bmap, offset, new_state); return; } /* different start, offset is in the middle of "cur" */ prev_state = btree_peek_prev(bmap, NULL); ASSERT(prev_state != NULL); if (prev_state == new_state) return; if (end == cur_key) { /* end is at the same point as the current extent */ if (new_state == cur_state) { /* #7: move next extent down */ btree_update_key(bmap, end, offset); return; } /* #9: different start, same end, add new extent */ btree_insert(bmap, offset, new_state); return; } /* #2: insert an extent into the middle of another extent */ btree_insert(bmap, offset, new_state); btree_insert(bmap, end, prev_state); } void set_bmap_ext( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t blen, int state) { update_bmap(ag_bmap[agno], agbno, blen, &states[state]); } int get_bmap_ext( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_agblock_t maxbno, xfs_extlen_t *blen) { int *statep; unsigned long key; statep = btree_find(ag_bmap[agno], agbno, &key); if (!statep) return -1; if (key == agbno) { if (blen) { if (!btree_peek_next(ag_bmap[agno], &key)) return -1; *blen = MIN(maxbno, key) - agbno; } return *statep; } statep = btree_peek_prev(ag_bmap[agno], NULL); if (!statep) return -1; if (blen) *blen = MIN(maxbno, key) - agbno; return *statep; } static uint64_t *rt_bmap; static size_t rt_bmap_size; /* block records fit into __uint64_t's units */ #define XR_BB_UNIT 64 /* number of bits/unit */ #define XR_BB 4 /* bits per block record */ #define XR_BB_NUM (XR_BB_UNIT/XR_BB) /* number of records per unit */ #define XR_BB_MASK 0xF /* block record mask */ /* * these work in real-time extents (e.g. fsbno == rt extent number) */ int get_rtbmap( xfs_drtbno_t bno) { return (*(rt_bmap + bno / XR_BB_NUM) >> ((bno % XR_BB_NUM) * XR_BB)) & XR_BB_MASK; } void set_rtbmap( xfs_drtbno_t bno, int state) { *(rt_bmap + bno / XR_BB_NUM) = ((*(rt_bmap + bno / XR_BB_NUM) & (~((__uint64_t) XR_BB_MASK << ((bno % XR_BB_NUM) * XR_BB)))) | (((__uint64_t) state) << ((bno % XR_BB_NUM) * XR_BB))); } static void reset_rt_bmap(void) { if (rt_bmap) memset(rt_bmap, 0x22, rt_bmap_size); /* XR_E_FREE */ } static void init_rt_bmap( xfs_mount_t *mp) { if (mp->m_sb.sb_rextents == 0) return; rt_bmap_size = roundup(mp->m_sb.sb_rextents / (NBBY / XR_BB), sizeof(__uint64_t)); rt_bmap = memalign(sizeof(__uint64_t), rt_bmap_size); if (!rt_bmap) { do_error( _("couldn't allocate realtime block map, size = %" PRIu64 "\n"), mp->m_sb.sb_rextents); return; } } static void free_rt_bmap(xfs_mount_t *mp) { free(rt_bmap); rt_bmap = NULL; } void reset_bmaps(xfs_mount_t *mp) { xfs_agnumber_t agno; xfs_agblock_t ag_size; int ag_hdr_block; ag_hdr_block = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); ag_size = mp->m_sb.sb_agblocks; for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { if (agno == mp->m_sb.sb_agcount - 1) ag_size = (xfs_extlen_t)(mp->m_sb.sb_dblocks - (xfs_drfsbno_t)mp->m_sb.sb_agblocks * agno); #ifdef BTREE_STATS if (btree_find(ag_bmap[agno], 0, NULL)) { printf("ag_bmap[%d] btree stats:\n", i); btree_print_stats(ag_bmap[agno], stdout); } #endif /* * We always insert an item for the first block having a * given state. So the code below means: * * block 0..ag_hdr_block-1: XR_E_INUSE_FS * ag_hdr_block..ag_size: XR_E_UNKNOWN * ag_size... XR_E_BAD_STATE */ btree_clear(ag_bmap[agno]); btree_insert(ag_bmap[agno], 0, &states[XR_E_INUSE_FS]); btree_insert(ag_bmap[agno], ag_hdr_block, &states[XR_E_UNKNOWN]); btree_insert(ag_bmap[agno], ag_size, &states[XR_E_BAD_STATE]); } if (mp->m_sb.sb_logstart != 0) { set_bmap_ext(XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart), XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart), mp->m_sb.sb_logblocks, XR_E_INUSE_FS); } reset_rt_bmap(); } void init_bmaps(xfs_mount_t *mp) { xfs_agnumber_t i; ag_bmap = calloc(mp->m_sb.sb_agcount, sizeof(struct btree_root *)); if (!ag_bmap) do_error(_("couldn't allocate block map btree roots\n")); ag_locks = calloc(mp->m_sb.sb_agcount, sizeof(pthread_mutex_t)); if (!ag_locks) do_error(_("couldn't allocate block map locks\n")); for (i = 0; i < mp->m_sb.sb_agcount; i++) { btree_init(&ag_bmap[i]); pthread_mutex_init(&ag_locks[i], NULL); } init_rt_bmap(mp); reset_bmaps(mp); } void free_bmaps(xfs_mount_t *mp) { xfs_agnumber_t i; for (i = 0; i < mp->m_sb.sb_agcount; i++) btree_destroy(ag_bmap[i]); free(ag_bmap); ag_bmap = NULL; free_rt_bmap(mp); } xfsprogs-3.1.9ubuntu2/repair/scan.h0000664000000000000000000000321711540521300014165 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XR_SCAN_H #define _XR_SCAN_H struct blkmap; int scan_lbtree( xfs_dfsbno_t root, int nlevels, int (*func)(struct xfs_btree_block *block, int level, int type, int whichfork, xfs_dfsbno_t bno, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups, int *dirty), int type, int whichfork, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups); int scanfunc_bmap( struct xfs_btree_block *block, int level, int type, int whichfork, xfs_dfsbno_t bno, xfs_ino_t ino, xfs_drfsbno_t *tot, __uint64_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, int isroot, int check_dups, int *dirty); void scan_ags( struct xfs_mount *mp, int scan_threads); #endif /* _XR_SCAN_H */ xfsprogs-3.1.9ubuntu2/config.guess0000775000000000000000000012673011711735051014146 0ustar #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. timestamp='2011-05-11' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-tilera-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: xfsprogs-3.1.9ubuntu2/aclocal.m40000664000000000000000000000211311711735053013454 0ustar # generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/manual_format.m4]) m4_include([m4/multilib.m4]) m4_include([m4/package_aiodev.m4]) m4_include([m4/package_blkid.m4]) m4_include([m4/package_globals.m4]) m4_include([m4/package_libcdev.m4]) m4_include([m4/package_pthread.m4]) m4_include([m4/package_types.m4]) m4_include([m4/package_utilies.m4]) m4_include([m4/package_uuiddev.m4]) xfsprogs-3.1.9ubuntu2/estimate/0000775000000000000000000000000012062211564013426 5ustar xfsprogs-3.1.9ubuntu2/estimate/Makefile0000664000000000000000000000055111330256617015074 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_estimate CFILES = xfs_estimate.c default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/estimate/xfs_estimate.c0000664000000000000000000001464111140033220016256 0ustar /* * Copyright (c) 2000-2002 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Estimate space of an XFS filesystem */ #include #include #include unsigned long long cvtnum(char *s) { unsigned long long i; char *sp; i = strtoll(s, &sp, 0); if (i == 0 && sp == s) return 0LL; if (*sp == '\0') return i; if (*sp =='k' && sp[1] == '\0') return 1024LL * i; if (*sp =='m' && sp[1] == '\0') return 1024LL * 1024LL * i; if (*sp =='g' && sp[1] == '\0') return 1024LL * 1024LL * 1024LL * i; return 0LL; } int ffn(const char *, const struct stat64 *, int, struct FTW *); #define BLOCKSIZE 4096 #define INODESIZE 256 #define PERDIRENTRY \ (sizeof(xfs_dir_leaf_entry_t) + sizeof(xfs_dir_leaf_name_t)) #define LOGSIZE 1000 #define FBLOCKS(n) ((n)/blocksize) #define RFBYTES(n) ((n) - (FBLOCKS(n) * blocksize)) unsigned long long dirsize=0; /* bytes */ unsigned long long logsize=LOGSIZE*BLOCKSIZE; /* bytes */ unsigned long long fullblocks=0; /* FS blocks */ unsigned long long isize=0; /* inodes bytes */ unsigned long long blocksize=BLOCKSIZE; unsigned long long nslinks=0; /* number of symbolic links */ unsigned long long nfiles=0; /* number of regular files */ unsigned long long ndirs=0; /* number of directories */ unsigned long long nspecial=0; /* number of special files */ unsigned long long verbose=0; /* verbose mode TRUE/FALSE */ int __debug = 0; int ilog = 0; int elog = 0; void usage(char *progname) { fprintf(stderr, _("Usage: %s [opts] directory [directory ...]\n" "\t-b blocksize (fundamental filesystem blocksize)\n" "\t-i logsize (internal log size)\n" "\t-e logsize (external log size)\n" "\t-v prints more verbose messages\n" "\t-h prints this usage message\n\n" "Note:\tblocksize may have 'k' appended to indicate x1024\n" "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n"), basename(progname)); exit(1); } int main(int argc, char **argv) { unsigned long long est; extern int optind; extern char *optarg; char dname[40]; int c; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt (argc, argv, "b:hdve:i:V")) != EOF) { switch (c) { case 'b': blocksize=cvtnum(optarg); if (blocksize <= 0LL) { fprintf(stderr, _("blocksize %llu too small\n"), blocksize); usage(argv[0]); } else if (blocksize > 64LL * 1024LL) { fprintf(stderr, _("blocksize %llu too large\n"), blocksize); usage(argv[0]); } break; case 'i': if (elog) { fprintf(stderr, _("already have external log " "noted, can't have both\n")); usage(argv[0]); } logsize=cvtnum(optarg); ilog++; break; case 'e': if (ilog) { fprintf(stderr, _("already have internal log " "noted, can't have both\n")); usage(argv[0]); } logsize=cvtnum(optarg); elog++; break; case 'v': verbose = 1; break; case 'd': __debug++; break; case 'V': printf(_("%s version %s\n"), basename(argv[0]), VERSION); exit(0); default: case 'h': usage(argv[0]); } } if (optind == argc) usage(argv[0]); if (!elog && !ilog) { ilog=1; logsize=LOGSIZE * blocksize; } if (verbose) printf(_("directory bsize blocks megabytes logsize\n")); for ( ; optind < argc; optind++) { dirsize=0LL; /* bytes */ fullblocks=0LL; /* FS blocks */ isize=0LL; /* inodes bytes */ nslinks=0LL; /* number of symbolic links */ nfiles=0LL; /* number of regular files */ ndirs=0LL; /* number of directories */ nspecial=0LL; /* number of special files */ nftw64(argv[optind], ffn, 40, FTW_PHYS | FTW_MOUNT); if (__debug) { printf(_("dirsize=%llu\n"), dirsize); printf(_("fullblocks=%llu\n"), fullblocks); printf(_("isize=%llu\n"), isize); printf(_("%llu regular files\n"), nfiles); printf(_("%llu symbolic links\n"), nslinks); printf(_("%llu directories\n"), ndirs); printf(_("%llu special files\n"), nspecial); } est = FBLOCKS(isize) + 8 /* blocks for inodes */ + FBLOCKS(dirsize) + 1 /* blocks for directories */ + fullblocks /* blocks for file contents */ + (8 * 16) /* fudge for overhead blks (per ag) */ + FBLOCKS(isize / INODESIZE); /* 1 byte/inode for map */ if (ilog) est += (logsize / blocksize); if (!verbose) { printf(_("%s will take about %.1f megabytes\n"), argv[optind], (double)est*(double)blocksize/(1024.0*1024.0)); } else { /* avoid running over 39 characters in field */ strncpy(dname, argv[optind], 40); dname[39] = '\0'; printf(_("%-39s %5llu %8llu %10.1fMB %10llu\n"), dname, blocksize, est, (double)est*(double)blocksize/(1024.0*1024.0), logsize); } if (!verbose && elog) { printf(_("\twith the external log using %llu blocks "), logsize/blocksize); printf(_("or about %.1f megabytes\n"), (double)logsize/(1024.0*1024.0)); } } return 0; } int ffn(const char *path, const struct stat64 *stb, int flags, struct FTW *f) { /* cases are in most-encountered to least-encountered order */ dirsize+=PERDIRENTRY+strlen(path); isize+=INODESIZE; switch (S_IFMT & stb->st_mode) { case S_IFREG: /* regular files */ fullblocks+=FBLOCKS(stb->st_blocks * 512 + blocksize-1); if (stb->st_blocks * 512 < stb->st_size) fullblocks++; /* add one bmap block here */ nfiles++; break; case S_IFLNK: /* symbolic links */ if (stb->st_size >= (INODESIZE - (sizeof(xfs_dinode_t)+4))) fullblocks+=FBLOCKS(stb->st_size + blocksize-1); nslinks++; break; case S_IFDIR: /* directories */ dirsize+=blocksize; /* fudge upwards */ if (stb->st_size >= blocksize) dirsize+=blocksize; ndirs++; break; case S_IFIFO: /* named pipes */ case S_IFCHR: /* Character Special device */ case S_IFBLK: /* Block Special device */ case S_IFSOCK: /* socket */ nspecial++; break; } return 0; } xfsprogs-3.1.9ubuntu2/README0000664000000000000000000000055611307015331012474 0ustar XFS User Tools README _____________________ See the file doc/INSTALL for build, installation and post- install configuration steps. Refer to the xfs(5) manual page for general XFS information and references to other XFS manual pages. For more information and details on how to contribute to the XFS project see the web pages at: http://oss.sgi.com/projects/xfs/ xfsprogs-3.1.9ubuntu2/libxlog/0000775000000000000000000000000012062211563013252 5ustar xfsprogs-3.1.9ubuntu2/libxlog/util.c0000664000000000000000000000600611140033220014361 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include int print_exit; int print_skip_uuid; int print_record_header; libxfs_init_t x; static int header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) { char uu_log[64], uu_sb[64]; if (print_skip_uuid) return 0; if (!platform_uuid_compare(&mp->m_sb.sb_uuid, &head->h_fs_uuid)) return 0; platform_uuid_unparse(&mp->m_sb.sb_uuid, uu_sb); platform_uuid_unparse(&head->h_fs_uuid, uu_log); printf(_("* ERROR: mismatched uuid in log\n" "* SB : %s\n* log: %s\n"), uu_sb, uu_log); memcpy(&mp->m_sb.sb_uuid, &head->h_fs_uuid, sizeof(uuid_t)); return 0; } int xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head) { if (print_record_header) printf(_("\nLOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n"), CYCLE_LSN(be64_to_cpu(head->h_lsn)), BLOCK_LSN(be64_to_cpu(head->h_lsn)), CYCLE_LSN(be64_to_cpu(head->h_lsn)), BLOCK_LSN(be64_to_cpu(head->h_lsn))); if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { printf(_("* ERROR: bad magic number in log header: 0x%x\n"), be32_to_cpu(head->h_magicno)); } else if (header_check_uuid(mp, head)) { /* failed - fall through */ } else if (be32_to_cpu(head->h_fmt) != XLOG_FMT) { printf(_("* ERROR: log format incompatible (log=%d, ours=%d)\n"), be32_to_cpu(head->h_fmt), XLOG_FMT); } else { /* everything is ok */ return 0; } /* bail out now or just carry on regardless */ if (print_exit) xlog_exit(_("Bad log")); return 0; } int xlog_header_check_mount(xfs_mount_t *mp, xlog_rec_header_t *head) { if (platform_uuid_is_null(&head->h_fs_uuid)) return 0; if (header_check_uuid(mp, head)) { /* bail out now or just carry on regardless */ if (print_exit) xlog_exit(_("Bad log")); } return 0; } /* * Userspace versions of common diagnostic routines (varargs fun). */ void xlog_warn(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fputs("\n", stderr); va_end(ap); } void xlog_exit(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fputs("\n", stderr); va_end(ap); exit(1); } void xlog_panic(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fputs("\n", stderr); va_end(ap); abort(); } xfsprogs-3.1.9ubuntu2/libxlog/Makefile0000664000000000000000000000063211432652134014716 0ustar # # Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTLIBRARY = libxlog.la LT_CURRENT = 0 LT_REVISION = 0 LT_AGE = 0 CFILES = xfs_log_recover.c util.c # don't want to link xfs_repair with a debug libxlog. DEBUG = -DNDEBUG default: ltdepend $(LTLIBRARY) include $(BUILDRULES) install install-dev install-qa: default -include .ltdep xfsprogs-3.1.9ubuntu2/libxlog/xfs_log_recover.c0000664000000000000000000012771711650373061016627 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #define xlog_unpack_data_checksum(rhead, dp, log) ((void)0) #define xlog_clear_stale_blocks(log, tail_lsn) (0) #define xfs_readonly_buftarg(buftarg) (0) /* * Verify the given count of basic blocks is valid number of blocks * to specify for an operation involving the given XFS log buffer. * Returns nonzero if the count is valid, 0 otherwise. */ static inline int xlog_buf_bbcount_valid( xlog_t *log, int bbcount) { return bbcount > 0 && bbcount <= log->l_logBBsize; } /* * Allocate a buffer to hold log data. The buffer needs to be able * to map to a range of nbblks basic blocks at any valid (basic * block) offset within the log. */ xfs_buf_t * xlog_get_bp( xlog_t *log, int nbblks) { if (!xlog_buf_bbcount_valid(log, nbblks)) { xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return NULL; } /* * We do log I/O in units of log sectors (a power-of-2 * multiple of the basic block size), so we round up the * requested size to acommodate the basic blocks required * for complete log sectors. * * In addition, the buffer may be used for a non-sector- * aligned block offset, in which case an I/O of the * requested size could extend beyond the end of the * buffer. If the requested size is only 1 basic block it * will never straddle a sector boundary, so this won't be * an issue. Nor will this be a problem if the log I/O is * done in basic blocks (sector size 1). But otherwise we * extend the buffer by one extra log sector to ensure * there's space to accomodate this possiblility. */ if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; if (log->l_sectBBsize) nbblks = round_up(nbblks, log->l_sectBBsize); return libxfs_getbufr(log->l_dev, (xfs_daddr_t)-1, nbblks); } void xlog_put_bp( xfs_buf_t *bp) { libxfs_putbufr(bp); } /* * Return the address of the start of the given block number's data * in a log buffer. The buffer covers a log sector-aligned region. */ STATIC xfs_caddr_t xlog_align( xlog_t *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp) { xfs_daddr_t offset = 0; if (log->l_sectBBsize) offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); return XFS_BUF_PTR(bp) + BBTOB(offset); } /* * nbblks should be uint, but oh well. Just want to catch that 32-bit length. */ int xlog_bread_noalign( xlog_t *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp) { if (!xlog_buf_bbcount_valid(log, nbblks)) { xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return EFSCORRUPTED; } if (log->l_sectBBsize > 1) { blk_no = round_down(blk_no, log->l_sectBBsize); nbblks = round_up(nbblks, log->l_sectBBsize); } ASSERT(nbblks > 0); ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp)); XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); return libxfs_readbufr(log->l_dev, XFS_BUF_ADDR(bp), bp, nbblks, 0); } int xlog_bread( xlog_t *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp, xfs_caddr_t *offset) { int error; error = xlog_bread_noalign(log, blk_no, nbblks, bp); if (error) return error; *offset = xlog_align(log, blk_no, nbblks, bp); return 0; } /* * This routine finds (to an approximation) the first block in the physical * log which contains the given cycle. It uses a binary search algorithm. * Note that the algorithm can not be perfect because the disk will not * necessarily be perfect. */ int xlog_find_cycle_start( xlog_t *log, xfs_buf_t *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle) { xfs_caddr_t offset; xfs_daddr_t mid_blk; xfs_daddr_t end_blk; uint mid_cycle; int error; end_blk = *last_blk; mid_blk = BLK_AVG(first_blk, end_blk); while (mid_blk != first_blk && mid_blk != end_blk) { error = xlog_bread(log, mid_blk, 1, bp, &offset); if (error) return error; mid_cycle = xlog_get_cycle(offset); if (mid_cycle == cycle) end_blk = mid_blk; /* last_half_cycle == mid_cycle */ else first_blk = mid_blk; /* first_half_cycle == mid_cycle */ mid_blk = BLK_AVG(first_blk, end_blk); } ASSERT((mid_blk == first_blk && mid_blk+1 == end_blk) || (mid_blk == end_blk && mid_blk-1 == first_blk)); *last_blk = end_blk; return 0; } /* * Check that a range of blocks does not contain stop_on_cycle_no. * Fill in *new_blk with the block offset where such a block is * found, or with -1 (an invalid block number) if there is no such * block in the range. The scan needs to occur from front to back * and the pointer into the region must be updated since a later * routine will need to perform another test. */ STATIC int xlog_find_verify_cycle( xlog_t *log, xfs_daddr_t start_blk, int nbblks, uint stop_on_cycle_no, xfs_daddr_t *new_blk) { xfs_daddr_t i, j; uint cycle; xfs_buf_t *bp; xfs_daddr_t bufblks; xfs_caddr_t buf = NULL; int error = 0; /* * Greedily allocate a buffer big enough to handle the full * range of basic blocks we'll be examining. If that fails, * try a smaller size. We need to be able to read at least * a log sector, or we're out of luck. */ bufblks = 1 << ffs(nbblks); while (!(bp = xlog_get_bp(log, bufblks))) { bufblks >>= 1; if (bufblks < MAX(log->l_sectBBsize, 1)) return ENOMEM; } for (i = start_blk; i < start_blk + nbblks; i += bufblks) { int bcount; bcount = min(bufblks, (start_blk + nbblks - i)); error = xlog_bread(log, i, bcount, bp, &buf); if (error) goto out; for (j = 0; j < bcount; j++) { cycle = xlog_get_cycle(buf); if (cycle == stop_on_cycle_no) { *new_blk = i+j; goto out; } buf += BBSIZE; } } *new_blk = -1; out: xlog_put_bp(bp); return error; } /* * Potentially backup over partial log record write. * * In the typical case, last_blk is the number of the block directly after * a good log record. Therefore, we subtract one to get the block number * of the last block in the given buffer. extra_bblks contains the number * of blocks we would have read on a previous read. This happens when the * last log record is split over the end of the physical log. * * extra_bblks is the number of blocks potentially verified on a previous * call to this routine. */ STATIC int xlog_find_verify_log_record( xlog_t *log, xfs_daddr_t start_blk, xfs_daddr_t *last_blk, int extra_bblks) { xfs_daddr_t i; xfs_buf_t *bp; xfs_caddr_t offset = NULL; xlog_rec_header_t *head = NULL; int error = 0; int smallmem = 0; int num_blks = *last_blk - start_blk; int xhdrs; ASSERT(start_blk != 0 || *last_blk != start_blk); if (!(bp = xlog_get_bp(log, num_blks))) { if (!(bp = xlog_get_bp(log, 1))) return ENOMEM; smallmem = 1; } else { error = xlog_bread(log, start_blk, num_blks, bp, &offset); if (error) goto out; offset += ((num_blks - 1) << BBSHIFT); } for (i = (*last_blk) - 1; i >= 0; i--) { if (i < start_blk) { /* valid log record not found */ xlog_warn( "XFS: Log inconsistent (didn't find previous header)"); ASSERT(0); error = XFS_ERROR(EIO); goto out; } if (smallmem) { error = xlog_bread(log, i, 1, bp, &offset); if (error) goto out; } head = (xlog_rec_header_t *)offset; if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) break; if (!smallmem) offset -= BBSIZE; } /* * We hit the beginning of the physical log & still no header. Return * to caller. If caller can handle a return of -1, then this routine * will be called again for the end of the physical log. */ if (i == -1) { error = -1; goto out; } /* * We have the final block of the good log (the first block * of the log record _before_ the head. So we check the uuid. */ if ((error = xlog_header_check_mount(log->l_mp, head))) goto out; /* * We may have found a log record header before we expected one. * last_blk will be the 1st block # with a given cycle #. We may end * up reading an entire log record. In this case, we don't want to * reset last_blk. Only when last_blk points in the middle of a log * record do we update last_blk. */ if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { uint h_size = be32_to_cpu(head->h_size); xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; if (h_size % XLOG_HEADER_CYCLE_SIZE) xhdrs++; } else { xhdrs = 1; } if (*last_blk - i + extra_bblks != BTOBB(be32_to_cpu(head->h_len)) + xhdrs) *last_blk = i; out: xlog_put_bp(bp); return error; } /* * Head is defined to be the point of the log where the next log write * write could go. This means that incomplete LR writes at the end are * eliminated when calculating the head. We aren't guaranteed that previous * LR have complete transactions. We only know that a cycle number of * current cycle number -1 won't be present in the log if we start writing * from our current block number. * * last_blk contains the block number of the first block with a given * cycle number. * * Return: zero if normal, non-zero if error. */ STATIC int xlog_find_head( xlog_t *log, xfs_daddr_t *return_head_blk) { xfs_buf_t *bp; xfs_caddr_t offset; xfs_daddr_t new_blk, first_blk, start_blk, last_blk, head_blk; int num_scan_bblks; uint first_half_cycle, last_half_cycle; uint stop_on_cycle; int error, log_bbnum = log->l_logBBsize; /* Is the end of the log device zeroed? */ if ((error = xlog_find_zeroed(log, &first_blk)) == -1) { *return_head_blk = first_blk; /* Is the whole lot zeroed? */ if (!first_blk) { /* Linux XFS shouldn't generate totally zeroed logs - * mkfs etc write a dummy unmount record to a fresh * log so we can store the uuid in there */ xlog_warn("XFS: totally zeroed log"); } return 0; } else if (error) { xlog_warn("XFS: empty log check failed"); return error; } first_blk = 0; /* get cycle # of 1st block */ bp = xlog_get_bp(log, 1); if (!bp) return ENOMEM; error = xlog_bread(log, 0, 1, bp, &offset); if (error) goto bp_err; first_half_cycle = xlog_get_cycle(offset); last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */ error = xlog_bread(log, last_blk, 1, bp, &offset); if (error) goto bp_err; last_half_cycle = xlog_get_cycle(offset); ASSERT(last_half_cycle != 0); /* * If the 1st half cycle number is equal to the last half cycle number, * then the entire log is stamped with the same cycle number. In this * case, head_blk can't be set to zero (which makes sense). The below * math doesn't work out properly with head_blk equal to zero. Instead, * we set it to log_bbnum which is an invalid block number, but this * value makes the math correct. If head_blk doesn't changed through * all the tests below, *head_blk is set to zero at the very end rather * than log_bbnum. In a sense, log_bbnum and zero are the same block * in a circular file. */ if (first_half_cycle == last_half_cycle) { /* * In this case we believe that the entire log should have * cycle number last_half_cycle. We need to scan backwards * from the end verifying that there are no holes still * containing last_half_cycle - 1. If we find such a hole, * then the start of that hole will be the new head. The * simple case looks like * x | x ... | x - 1 | x * Another case that fits this picture would be * x | x + 1 | x ... | x * In this case the head really is somewhere at the end of the * log, as one of the latest writes at the beginning was * incomplete. * One more case is * x | x + 1 | x ... | x - 1 | x * This is really the combination of the above two cases, and * the head has to end up at the start of the x-1 hole at the * end of the log. * * In the 256k log case, we will read from the beginning to the * end of the log and search for cycle numbers equal to x-1. * We don't worry about the x+1 blocks that we encounter, * because we know that they cannot be the head since the log * started with x. */ head_blk = log_bbnum; stop_on_cycle = last_half_cycle - 1; } else { /* * In this case we want to find the first block with cycle * number matching last_half_cycle. We expect the log to be * some variation on * x + 1 ... | x ... | x * The first block with cycle number x (last_half_cycle) will * be where the new head belongs. First we do a binary search * for the first occurrence of last_half_cycle. The binary * search may not be totally accurate, so then we scan back * from there looking for occurrences of last_half_cycle before * us. If that backwards scan wraps around the beginning of * the log, then we look for occurrences of last_half_cycle - 1 * at the end of the log. The cases we're looking for look * like * v binary search stopped here * x + 1 ... | x | x + 1 | x ... | x * ^ but we want to locate this spot * or * <---------> less than scan distance * x + 1 ... | x ... | x - 1 | x * ^ we want to locate this spot */ stop_on_cycle = last_half_cycle; if ((error = xlog_find_cycle_start(log, bp, first_blk, &head_blk, last_half_cycle))) goto bp_err; } /* * Now validate the answer. Scan back some number of maximum possible * blocks and make sure each one has the expected cycle number. The * maximum is determined by the total possible amount of buffering * in the in-core log. The following number can be made tighter if * we actually look at the block size of the filesystem. */ num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log); if (head_blk >= num_scan_bblks) { /* * We are guaranteed that the entire check can be performed * in one buffer. */ start_blk = head_blk - num_scan_bblks; if ((error = xlog_find_verify_cycle(log, start_blk, num_scan_bblks, stop_on_cycle, &new_blk))) goto bp_err; if (new_blk != -1) head_blk = new_blk; } else { /* need to read 2 parts of log */ /* * We are going to scan backwards in the log in two parts. * First we scan the physical end of the log. In this part * of the log, we are looking for blocks with cycle number * last_half_cycle - 1. * If we find one, then we know that the log starts there, as * we've found a hole that didn't get written in going around * the end of the physical log. The simple case for this is * x + 1 ... | x ... | x - 1 | x * <---------> less than scan distance * If all of the blocks at the end of the log have cycle number * last_half_cycle, then we check the blocks at the start of * the log looking for occurrences of last_half_cycle. If we * find one, then our current estimate for the location of the * first occurrence of last_half_cycle is wrong and we move * back to the hole we've found. This case looks like * x + 1 ... | x | x + 1 | x ... * ^ binary search stopped here * Another case we need to handle that only occurs in 256k * logs is * x + 1 ... | x ... | x+1 | x ... * ^ binary search stops here * In a 256k log, the scan at the end of the log will see the * x + 1 blocks. We need to skip past those since that is * certainly not the head of the log. By searching for * last_half_cycle-1 we accomplish that. */ ASSERT(head_blk <= INT_MAX && (xfs_daddr_t) num_scan_bblks >= head_blk); start_blk = log_bbnum - (num_scan_bblks - head_blk); if ((error = xlog_find_verify_cycle(log, start_blk, num_scan_bblks - (int)head_blk, (stop_on_cycle - 1), &new_blk))) goto bp_err; if (new_blk != -1) { head_blk = new_blk; goto validate_head; } /* * Scan beginning of log now. The last part of the physical * log is good. This scan needs to verify that it doesn't find * the last_half_cycle. */ start_blk = 0; ASSERT(head_blk <= INT_MAX); if ((error = xlog_find_verify_cycle(log, start_blk, (int)head_blk, stop_on_cycle, &new_blk))) goto bp_err; if (new_blk != -1) head_blk = new_blk; } validate_head: /* * Now we need to make sure head_blk is not pointing to a block in * the middle of a log record. */ num_scan_bblks = XLOG_REC_SHIFT(log); if (head_blk >= num_scan_bblks) { start_blk = head_blk - num_scan_bblks; /* don't read head_blk */ /* start ptr at last block ptr before head_blk */ if ((error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0)) == -1) { error = XFS_ERROR(EIO); goto bp_err; } else if (error) goto bp_err; } else { start_blk = 0; ASSERT(head_blk <= INT_MAX); if ((error = xlog_find_verify_log_record(log, start_blk, &head_blk, 0)) == -1) { /* We hit the beginning of the log during our search */ start_blk = log_bbnum - (num_scan_bblks - head_blk); new_blk = log_bbnum; ASSERT(start_blk <= INT_MAX && (xfs_daddr_t) log_bbnum-start_blk >= 0); ASSERT(head_blk <= INT_MAX); if ((error = xlog_find_verify_log_record(log, start_blk, &new_blk, (int)head_blk)) == -1) { error = XFS_ERROR(EIO); goto bp_err; } else if (error) goto bp_err; if (new_blk != log_bbnum) head_blk = new_blk; } else if (error) goto bp_err; } xlog_put_bp(bp); if (head_blk == log_bbnum) *return_head_blk = 0; else *return_head_blk = head_blk; /* * When returning here, we have a good block number. Bad block * means that during a previous crash, we didn't have a clean break * from cycle number N to cycle number N-1. In this case, we need * to find the first block with cycle number N-1. */ return 0; bp_err: xlog_put_bp(bp); if (error) xlog_warn("XFS: failed to find log head"); return error; } /* * Find the sync block number or the tail of the log. * * This will be the block number of the last record to have its * associated buffers synced to disk. Every log record header has * a sync lsn embedded in it. LSNs hold block numbers, so it is easy * to get a sync block number. The only concern is to figure out which * log record header to believe. * * The following algorithm uses the log record header with the largest * lsn. The entire log record does not need to be valid. We only care * that the header is valid. * * We could speed up search by using current head_blk buffer, but it is not * available. */ int xlog_find_tail( xlog_t *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk) { xlog_rec_header_t *rhead; xlog_op_header_t *op_head; xfs_caddr_t offset = NULL; xfs_buf_t *bp; int error, i, found; xfs_daddr_t umount_data_blk; xfs_daddr_t after_umount_blk; xfs_lsn_t tail_lsn; int hblks; found = 0; /* * Find previous log record */ if ((error = xlog_find_head(log, head_blk))) return error; bp = xlog_get_bp(log, 1); if (!bp) return ENOMEM; if (*head_blk == 0) { /* special case */ error = xlog_bread(log, 0, 1, bp, &offset); if (error) goto done; if (xlog_get_cycle(offset) == 0) { *tail_blk = 0; /* leave all other log inited values alone */ goto done; } } /* * Search backwards looking for log record header block */ ASSERT(*head_blk < INT_MAX); for (i = (int)(*head_blk) - 1; i >= 0; i--) { error = xlog_bread(log, i, 1, bp, &offset); if (error) goto done; if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { found = 1; break; } } /* * If we haven't found the log record header block, start looking * again from the end of the physical log. XXXmiken: There should be * a check here to make sure we didn't search more than N blocks in * the previous code. */ if (!found) { for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) { error = xlog_bread(log, i, 1, bp, &offset); if (error) goto done; if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { found = 2; break; } } } if (!found) { xlog_warn("XFS: xlog_find_tail: couldn't find sync record"); ASSERT(0); return XFS_ERROR(EIO); } /* find blk_no of tail of log */ rhead = (xlog_rec_header_t *)offset; *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* * Reset log values according to the state of the log when we * crashed. In the case where head_blk == 0, we bump curr_cycle * one because the next write starts a new cycle rather than * continuing the cycle of the last good log record. At this * point we have guaranteed that all partial log records have been * accounted for. Therefore, we know that the last good log record * written was complete and ended exactly on the end boundary * of the physical log. */ log->l_prev_block = i; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (found == 2) log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, BBTOB(log->l_curr_block)); xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, BBTOB(log->l_curr_block)); /* * Look for unmount record. If we find it, then we know there * was a clean unmount. Since 'i' could be the last block in * the physical log, we convert to a log block before comparing * to the head_blk. * * Save the current tail lsn to use to pass to * xlog_clear_stale_blocks() below. We won't want to clear the * unmount record if there is one, so we pass the lsn of the * unmount record rather than the block after it. */ if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { int h_size = be32_to_cpu(rhead->h_size); int h_version = be32_to_cpu(rhead->h_version); if ((h_version & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; if (h_size % XLOG_HEADER_CYCLE_SIZE) hblks++; } else { hblks = 1; } } else { hblks = 1; } after_umount_blk = (i + hblks + (int) BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; tail_lsn = atomic64_read(&log->l_tail_lsn); if (*head_blk == after_umount_blk && be32_to_cpu(rhead->h_num_logops) == 1) { umount_data_blk = (i + hblks) % log->l_logBBsize; error = xlog_bread(log, umount_data_blk, 1, bp, &offset); if (error) goto done; op_head = (xlog_op_header_t *)offset; if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) { /* * Set tail and last sync so that newly written * log records will point recovery to after the * current unmount record. */ xlog_assign_atomic_lsn(&log->l_tail_lsn, log->l_curr_cycle, after_umount_blk); xlog_assign_atomic_lsn(&log->l_last_sync_lsn, log->l_curr_cycle, after_umount_blk); *tail_blk = after_umount_blk; /* * Note that the unmount was clean. If the unmount * was not clean, we need to know this to rebuild the * superblock counters from the perag headers if we * have a filesystem using non-persistent counters. */ log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN; } } /* * Make sure that there are no blocks in front of the head * with the same cycle number as the head. This can happen * because we allow multiple outstanding log writes concurrently, * and the later writes might make it out before earlier ones. * * We use the lsn from before modifying it so that we'll never * overwrite the unmount record after a clean unmount. * * Do this only if we are going to recover the filesystem * * NOTE: This used to say "if (!readonly)" * However on Linux, we can & do recover a read-only filesystem. * We only skip recovery if NORECOVERY is specified on mount, * in which case we would not be here. * * But... if the -device- itself is readonly, just skip this. * We can't recover this device anyway, so it won't matter. */ if (!xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) error = xlog_clear_stale_blocks(log, tail_lsn); done: xlog_put_bp(bp); if (error) xlog_warn("XFS: failed to locate log tail"); return error; } /* * Is the log zeroed at all? * * The last binary search should be changed to perform an X block read * once X becomes small enough. You can then search linearly through * the X blocks. This will cut down on the number of reads we need to do. * * If the log is partially zeroed, this routine will pass back the blkno * of the first block with cycle number 0. It won't have a complete LR * preceding it. * * Return: * 0 => the log is completely written to * -1 => use *blk_no as the first block of the log * >0 => error has occurred */ int xlog_find_zeroed( xlog_t *log, xfs_daddr_t *blk_no) { xfs_buf_t *bp; xfs_caddr_t offset; uint first_cycle, last_cycle; xfs_daddr_t new_blk, last_blk, start_blk; xfs_daddr_t num_scan_bblks; int error, log_bbnum = log->l_logBBsize; *blk_no = 0; /* check totally zeroed log */ bp = xlog_get_bp(log, 1); if (!bp) return ENOMEM; error = xlog_bread(log, 0, 1, bp, &offset); if (error) goto bp_err; first_cycle = xlog_get_cycle(offset); if (first_cycle == 0) { /* completely zeroed log */ *blk_no = 0; xlog_put_bp(bp); return -1; } /* check partially zeroed log */ error = xlog_bread(log, log_bbnum-1, 1, bp, &offset); if (error) goto bp_err; last_cycle = xlog_get_cycle(offset); if (last_cycle != 0) { /* log completely written to */ xlog_put_bp(bp); return 0; } else if (first_cycle != 1) { /* * If the cycle of the last block is zero, the cycle of * the first block must be 1. If it's not, maybe we're * not looking at a log... Bail out. */ xlog_warn("XFS: Log inconsistent or not a log (last==0, first!=1)"); return XFS_ERROR(EINVAL); } /* we have a partially zeroed log */ last_blk = log_bbnum-1; if ((error = xlog_find_cycle_start(log, bp, 0, &last_blk, 0))) goto bp_err; /* * Validate the answer. Because there is no way to guarantee that * the entire log is made up of log records which are the same size, * we scan over the defined maximum blocks. At this point, the maximum * is not chosen to mean anything special. XXXmiken */ num_scan_bblks = XLOG_TOTAL_REC_SHIFT(log); ASSERT(num_scan_bblks <= INT_MAX); if (last_blk < num_scan_bblks) num_scan_bblks = last_blk; start_blk = last_blk - num_scan_bblks; /* * We search for any instances of cycle number 0 that occur before * our current estimate of the head. What we're trying to detect is * 1 ... | 0 | 1 | 0... * ^ binary search ends here */ if ((error = xlog_find_verify_cycle(log, start_blk, (int)num_scan_bblks, 0, &new_blk))) goto bp_err; if (new_blk != -1) last_blk = new_blk; /* * Potentially backup over partial log record write. We don't need * to search the end of the log because we know it is zero. */ if ((error = xlog_find_verify_log_record(log, start_blk, &last_blk, 0)) == -1) { error = XFS_ERROR(EIO); goto bp_err; } else if (error) goto bp_err; *blk_no = last_blk; bp_err: xlog_put_bp(bp); if (error) return error; return -1; } STATIC xlog_recover_t * xlog_recover_find_tid( struct hlist_head *head, xlog_tid_t tid) { xlog_recover_t *trans; struct hlist_node *n; hlist_for_each_entry(trans, n, head, r_list) { if (trans->r_log_tid == tid) return trans; } return NULL; } STATIC void xlog_recover_new_tid( struct hlist_head *head, xlog_tid_t tid, xfs_lsn_t lsn) { xlog_recover_t *trans; trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); trans->r_log_tid = tid; trans->r_lsn = lsn; INIT_LIST_HEAD(&trans->r_itemq); INIT_HLIST_NODE(&trans->r_list); hlist_add_head(&trans->r_list, head); } STATIC void xlog_recover_add_item( struct list_head *head) { xlog_recover_item_t *item; item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP); INIT_LIST_HEAD(&item->ri_list); list_add_tail(&item->ri_list, head); } STATIC int xlog_recover_add_to_cont_trans( struct log *log, xlog_recover_t *trans, xfs_caddr_t dp, int len) { xlog_recover_item_t *item; xfs_caddr_t ptr, old_ptr; int old_len; if (list_empty(&trans->r_itemq)) { /* finish copying rest of trans header */ xlog_recover_add_item(&trans->r_itemq); ptr = (xfs_caddr_t) &trans->r_theader + sizeof(xfs_trans_header_t) - len; memcpy(ptr, dp, len); /* d, s, l */ return 0; } /* take the tail entry */ item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; old_len = item->ri_buf[item->ri_cnt-1].i_len; ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u); memcpy(&ptr[old_len], dp, len); /* d, s, l */ item->ri_buf[item->ri_cnt-1].i_len += len; item->ri_buf[item->ri_cnt-1].i_addr = ptr; trace_xfs_log_recover_item_add_cont(log, trans, item, 0); return 0; } /* * The next region to add is the start of a new region. It could be * a whole region or it could be the first part of a new region. Because * of this, the assumption here is that the type and size fields of all * format structures fit into the first 32 bits of the structure. * * This works because all regions must be 32 bit aligned. Therefore, we * either have both fields or we have neither field. In the case we have * neither field, the data part of the region is zero length. We only have * a log_op_header and can throw away the header since a new one will appear * later. If we have at least 4 bytes, then we can determine how many regions * will appear in the current log item. */ STATIC int xlog_recover_add_to_trans( struct log *log, xlog_recover_t *trans, xfs_caddr_t dp, int len) { xfs_inode_log_format_t *in_f; /* any will do */ xlog_recover_item_t *item; xfs_caddr_t ptr; if (!len) return 0; if (list_empty(&trans->r_itemq)) { /* we need to catch log corruptions here */ if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { xlog_warn("XFS: xlog_recover_add_to_trans: " "bad header magic number"); ASSERT(0); return XFS_ERROR(EIO); } if (len == sizeof(xfs_trans_header_t)) xlog_recover_add_item(&trans->r_itemq); memcpy(&trans->r_theader, dp, len); /* d, s, l */ return 0; } ptr = kmem_alloc(len, KM_SLEEP); memcpy(ptr, dp, len); in_f = (xfs_inode_log_format_t *)ptr; /* take the tail entry */ item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); if (item->ri_total != 0 && item->ri_total == item->ri_cnt) { /* tail item is in use, get a new one */ xlog_recover_add_item(&trans->r_itemq); item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); } if (item->ri_total == 0) { /* first region to be added */ if (in_f->ilf_size == 0 || in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { xlog_warn( "XFS: bad number of regions (%d) in inode log format", in_f->ilf_size); ASSERT(0); return XFS_ERROR(EIO); } item->ri_total = in_f->ilf_size; item->ri_buf = kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), KM_SLEEP); } ASSERT(item->ri_total > item->ri_cnt); /* Description region is ri_buf[0] */ item->ri_buf[item->ri_cnt].i_addr = ptr; item->ri_buf[item->ri_cnt].i_len = len; item->ri_cnt++; trace_xfs_log_recover_item_add(log, trans, item, 0); return 0; } /* * Free up any resources allocated by the transaction * * Remember that EFIs, EFDs, and IUNLINKs are handled later. */ STATIC void xlog_recover_free_trans( struct xlog_recover *trans) { xlog_recover_item_t *item, *n; int i; list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) { /* Free the regions in the item. */ list_del(&item->ri_list); for (i = 0; i < item->ri_cnt; i++) kmem_free(item->ri_buf[i].i_addr); /* Free the item itself */ kmem_free(item->ri_buf); kmem_free(item); } /* Free the transaction recover structure */ kmem_free(trans); } /* * Perform the transaction. * * If the transaction modifies a buffer or inode, do it now. Otherwise, * EFIs and EFDs get queued up by adding entries into the AIL for them. */ STATIC int xlog_recover_commit_trans( struct log *log, struct xlog_recover *trans, int pass) { int error = 0; hlist_del(&trans->r_list); if ((error = xlog_recover_do_trans(log, trans, pass))) return error; xlog_recover_free_trans(trans); return 0; } STATIC int xlog_recover_unmount_trans( xlog_recover_t *trans) { /* Do nothing now */ xlog_warn("XFS: xlog_recover_unmount_trans: Unmount LR"); return 0; } /* * There are two valid states of the r_state field. 0 indicates that the * transaction structure is in a normal state. We have either seen the * start of the transaction or the last operation we added was not a partial * operation. If the last operation we added to the transaction was a * partial operation, we need to mark r_state with XLOG_WAS_CONT_TRANS. * * NOTE: skip LRs with 0 data length. */ STATIC int xlog_recover_process_data( xlog_t *log, struct hlist_head rhash[], xlog_rec_header_t *rhead, xfs_caddr_t dp, int pass) { xfs_caddr_t lp; int num_logops; xlog_op_header_t *ohead; xlog_recover_t *trans; xlog_tid_t tid; int error; unsigned long hash; uint flags; lp = dp + be32_to_cpu(rhead->h_len); num_logops = be32_to_cpu(rhead->h_num_logops); /* check the log format matches our own - else we can't recover */ if (xlog_header_check_recover(log->l_mp, rhead)) return (XFS_ERROR(EIO)); while ((dp < lp) && num_logops) { ASSERT(dp + sizeof(xlog_op_header_t) <= lp); ohead = (xlog_op_header_t *)dp; dp += sizeof(xlog_op_header_t); if (ohead->oh_clientid != XFS_TRANSACTION && ohead->oh_clientid != XFS_LOG) { xlog_warn( "XFS: xlog_recover_process_data: bad clientid"); ASSERT(0); return (XFS_ERROR(EIO)); } tid = be32_to_cpu(ohead->oh_tid); hash = XLOG_RHASH(tid); trans = xlog_recover_find_tid(&rhash[hash], tid); if (trans == NULL) { /* not found; add new tid */ if (ohead->oh_flags & XLOG_START_TRANS) xlog_recover_new_tid(&rhash[hash], tid, be64_to_cpu(rhead->h_lsn)); } else { if (dp + be32_to_cpu(ohead->oh_len) > lp) { xlog_warn( "XFS: xlog_recover_process_data: bad length"); return (XFS_ERROR(EIO)); } flags = ohead->oh_flags & ~XLOG_END_TRANS; if (flags & XLOG_WAS_CONT_TRANS) flags &= ~XLOG_CONTINUE_TRANS; switch (flags) { case XLOG_COMMIT_TRANS: error = xlog_recover_commit_trans(log, trans, pass); break; case XLOG_UNMOUNT_TRANS: error = xlog_recover_unmount_trans(trans); break; case XLOG_WAS_CONT_TRANS: error = xlog_recover_add_to_cont_trans(log, trans, dp, be32_to_cpu(ohead->oh_len)); break; case XLOG_START_TRANS: xlog_warn( "XFS: xlog_recover_process_data: bad transaction"); ASSERT(0); error = XFS_ERROR(EIO); break; case 0: case XLOG_CONTINUE_TRANS: error = xlog_recover_add_to_trans(log, trans, dp, be32_to_cpu(ohead->oh_len)); break; default: xlog_warn( "XFS: xlog_recover_process_data: bad flag"); ASSERT(0); error = XFS_ERROR(EIO); break; } if (error) return error; } dp += be32_to_cpu(ohead->oh_len); num_logops--; } return 0; } STATIC void xlog_unpack_data( xlog_rec_header_t *rhead, xfs_caddr_t dp, xlog_t *log) { int i, j, k; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i]; dp += BBSIZE; } if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead; for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k]; dp += BBSIZE; } } } STATIC int xlog_valid_rec_header( xlog_t *log, xlog_rec_header_t *rhead, xfs_daddr_t blkno) { int hlen; if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { XFS_ERROR_REPORT("xlog_valid_rec_header(1)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); } if (unlikely( (!rhead->h_version || (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { xlog_warn("XFS: %s: unrecognised log version (%d).", __func__, be32_to_cpu(rhead->h_version)); return XFS_ERROR(EIO); } /* LR body must have data or it wouldn't have been written */ hlen = be32_to_cpu(rhead->h_len); if (unlikely( hlen <= 0 || hlen > INT_MAX )) { XFS_ERROR_REPORT("xlog_valid_rec_header(2)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); } if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) { XFS_ERROR_REPORT("xlog_valid_rec_header(3)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); } return 0; } /* * Read the log from tail to head and process the log records found. * Handle the two cases where the tail and head are in the same cycle * and where the active portion of the log wraps around the end of * the physical log separately. The pass parameter is passed through * to the routines called to process the data and is not looked at * here. */ int xlog_do_recovery_pass( xlog_t *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass) { xlog_rec_header_t *rhead; xfs_daddr_t blk_no; xfs_caddr_t offset; xfs_buf_t *hbp, *dbp; int error = 0, h_size; int bblks, split_bblks; int hblks, split_hblks, wrapped_hblks; struct hlist_head rhash[XLOG_RHASH_SIZE]; ASSERT(head_blk != tail_blk); /* * Read the header of the tail block and get the iclog buffer size from * h_size. Use this to tell how many sectors make up the log header. */ if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { /* * When using variable length iclogs, read first sector of * iclog header and extract the header size from it. Get a * new hbp that is the correct size. */ hbp = xlog_get_bp(log, 1); if (!hbp) return ENOMEM; error = xlog_bread(log, tail_blk, 1, hbp, &offset); if (error) goto bread_err1; rhead = (xlog_rec_header_t *)offset; error = xlog_valid_rec_header(log, rhead, tail_blk); if (error) goto bread_err1; h_size = be32_to_cpu(rhead->h_size); if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; if (h_size % XLOG_HEADER_CYCLE_SIZE) hblks++; xlog_put_bp(hbp); hbp = xlog_get_bp(log, hblks); } else { hblks = 1; } } else { ASSERT(log->l_sectBBsize == 1); hblks = 1; hbp = xlog_get_bp(log, 1); h_size = XLOG_BIG_RECORD_BSIZE; } if (!hbp) return ENOMEM; dbp = xlog_get_bp(log, BTOBB(h_size)); if (!dbp) { xlog_put_bp(hbp); return ENOMEM; } memset(rhash, 0, sizeof(rhash)); if (tail_blk <= head_blk) { for (blk_no = tail_blk; blk_no < head_blk; ) { error = xlog_bread(log, blk_no, hblks, hbp, &offset); if (error) goto bread_err2; rhead = (xlog_rec_header_t *)offset; error = xlog_valid_rec_header(log, rhead, blk_no); if (error) goto bread_err2; /* blocks in data section */ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); error = xlog_bread(log, blk_no + hblks, bblks, dbp, &offset); if (error) goto bread_err2; xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, rhead, offset, pass))) goto bread_err2; blk_no += bblks + hblks; } } else { /* * Perform recovery around the end of the physical log. * When the head is not on the same cycle number as the tail, * we can't do a sequential recovery as above. */ blk_no = tail_blk; while (blk_no < log->l_logBBsize) { /* * Check for header wrapping around physical end-of-log */ offset = XFS_BUF_PTR(hbp); split_hblks = 0; wrapped_hblks = 0; if (blk_no + hblks <= log->l_logBBsize) { /* Read header in one read */ error = xlog_bread(log, blk_no, hblks, hbp, &offset); if (error) goto bread_err2; } else { /* This LR is split across physical log end */ if (blk_no != log->l_logBBsize) { /* some data before physical log end */ ASSERT(blk_no <= INT_MAX); split_hblks = log->l_logBBsize - (int)blk_no; ASSERT(split_hblks > 0); error = xlog_bread(log, blk_no, split_hblks, hbp, &offset); if (error) goto bread_err2; } /* * Note: this black magic still works with * large sector sizes (non-512) only because: * - we increased the buffer size originally * by 1 sector giving us enough extra space * for the second read; * - the log start is guaranteed to be sector * aligned; * - we read the log end (LR header start) * _first_, then the log start (LR header end) * - order is important. */ wrapped_hblks = hblks - split_hblks; error = XFS_BUF_SET_PTR(hbp, offset + BBTOB(split_hblks), BBTOB(hblks - split_hblks)); if (error) goto bread_err2; error = xlog_bread_noalign(log, 0, wrapped_hblks, hbp); if (error) goto bread_err2; error = XFS_BUF_SET_PTR(hbp, offset, BBTOB(hblks)); if (error) goto bread_err2; } rhead = (xlog_rec_header_t *)offset; error = xlog_valid_rec_header(log, rhead, split_hblks ? blk_no : 0); if (error) goto bread_err2; bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); blk_no += hblks; /* Read in data for log record */ if (blk_no + bblks <= log->l_logBBsize) { error = xlog_bread(log, blk_no, bblks, dbp, &offset); if (error) goto bread_err2; } else { /* This log record is split across the * physical end of log */ offset = XFS_BUF_PTR(dbp); split_bblks = 0; if (blk_no != log->l_logBBsize) { /* some data is before the physical * end of log */ ASSERT(!wrapped_hblks); ASSERT(blk_no <= INT_MAX); split_bblks = log->l_logBBsize - (int)blk_no; ASSERT(split_bblks > 0); error = xlog_bread(log, blk_no, split_bblks, dbp, &offset); if (error) goto bread_err2; } /* * Note: this black magic still works with * large sector sizes (non-512) only because: * - we increased the buffer size originally * by 1 sector giving us enough extra space * for the second read; * - the log start is guaranteed to be sector * aligned; * - we read the log end (LR header start) * _first_, then the log start (LR header end) * - order is important. */ error = XFS_BUF_SET_PTR(dbp, offset + BBTOB(split_bblks), BBTOB(bblks - split_bblks)); if (error) goto bread_err2; error = xlog_bread_noalign(log, wrapped_hblks, bblks - split_bblks, dbp); if (error) goto bread_err2; error = XFS_BUF_SET_PTR(dbp, offset, h_size); if (error) goto bread_err2; } xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, rhead, offset, pass))) goto bread_err2; blk_no += bblks; } ASSERT(blk_no >= log->l_logBBsize); blk_no -= log->l_logBBsize; /* read first part of physical log */ while (blk_no < head_blk) { error = xlog_bread(log, blk_no, hblks, hbp, &offset); if (error) goto bread_err2; rhead = (xlog_rec_header_t *)offset; error = xlog_valid_rec_header(log, rhead, blk_no); if (error) goto bread_err2; bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); error = xlog_bread(log, blk_no+hblks, bblks, dbp, &offset); if (error) goto bread_err2; xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, rhead, offset, pass))) goto bread_err2; blk_no += bblks + hblks; } } bread_err2: xlog_put_bp(dbp); bread_err1: xlog_put_bp(hbp); return error; } xfsprogs-3.1.9ubuntu2/configure.ac0000664000000000000000000000615412062210562014104 0ustar AC_INIT([xfsprogs], [3.1.9]) AC_PREREQ(2.50) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([include/libxfs.h]) AC_CONFIG_HEADER(include/platform_defs.h) AC_PREFIX_DEFAULT(/usr) AC_PROG_LIBTOOL AC_ARG_ENABLE(shared, [ --enable-shared=[yes/no] Enable use of shared libraries [default=yes]],, enable_shared=yes) AC_SUBST(enable_shared) AC_ARG_ENABLE(gettext, [ --enable-gettext=[yes/no] Enable alternate language support [default=yes]],, enable_gettext=yes) AC_SUBST(enable_gettext) AC_ARG_ENABLE(readline, [ --enable-readline=[yes/no] Enable readline command editing [default=no]], test $enable_readline = yes && libreadline="-lreadline", enable_readline=no) AC_SUBST(libreadline) AC_SUBST(enable_readline) AC_ARG_ENABLE(editline, [ --enable-editline=[yes/no] Enable editline command editing [default=no]], test $enable_editline = yes && libeditline="-ledit", enable_editline=no) AC_SUBST(libeditline) AC_SUBST(enable_editline) AC_ARG_ENABLE(termcap, [ --enable-termcap=[yes/no] Enable terminal capabilities library [default=no]], test $enable_termcap = yes && libtermcap="-ltermcap",) AC_SUBST(libtermcap) # AC_HAVE_BLKID_TOPO below wil find the library & check for topo support AC_ARG_ENABLE(blkid, [ --enable-blkid=[yes/no] Enable block device id library [default=yes]],, enable_blkid=yes) AC_ARG_ENABLE(lib64, [ --enable-lib64=[yes/no] Enable lib64 support [default=yes]],, enable_lib64=yes) AC_SUBST(enable_lib64) # # If the user specified a libdir ending in lib64 do not append another # 64 to the library names. # base_libdir=`basename "$libdir"` case $base_libdir in lib64) enable_lib64=no esac # # Some important tools should be installed into the root partitions. # # Check whether exec_prefix=/usr: and install them to /sbin in that # case. If the user choses a different prefix assume he just wants # a local install for testing and not a system install. # case $exec_prefix:$prefix in NONE:NONE | NONE:/usr | /usr:*) root_sbindir='/sbin' root_libdir="/${base_libdir}" ;; *) root_sbindir="${sbindir}" root_libdir="${libdir}" ;; esac AC_SUBST([root_sbindir]) AC_SUBST([root_libdir]) # Find localized files. Don't descend into any "dot directories" # (like .git or .pc from quilt). Strangely, the "-print" argument # to "find" is required, to avoid including such directories in the # list. LOCALIZED_FILES="" for lfile in `find ${srcdir} -path './.??*' -prune -o -name '*.c' -type f -print || exit 1`; do LOCALIZED_FILES="$LOCALIZED_FILES \$(TOPDIR)/$lfile" done AC_SUBST(LOCALIZED_FILES) AC_PACKAGE_GLOBALS(xfsprogs) AC_PACKAGE_UTILITIES(xfsprogs) AC_MULTILIB($enable_lib64) AC_PACKAGE_NEED_AIO_H AC_PACKAGE_NEED_LIO_LISTIO AC_PACKAGE_NEED_UUID_H AC_PACKAGE_NEED_UUIDCOMPARE AC_PACKAGE_NEED_PTHREAD_H AC_PACKAGE_NEED_PTHREADMUTEXINIT AC_HAVE_FADVISE AC_HAVE_MADVISE AC_HAVE_MINCORE AC_HAVE_SENDFILE AC_HAVE_GETMNTENT AC_HAVE_GETMNTINFO AC_HAVE_FALLOCATE AC_HAVE_FIEMAP AC_HAVE_PREADV AC_HAVE_SYNC_FILE_RANGE AC_HAVE_BLKID_TOPO($enable_blkid) AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([char *]) AC_TYPE_PSINT AC_TYPE_PSUNSIGNED AC_TYPE_U32 AC_MANUAL_FORMAT AC_CONFIG_FILES([include/builddefs]) AC_OUTPUT xfsprogs-3.1.9ubuntu2/po/0000775000000000000000000000000012062211564012231 5ustar xfsprogs-3.1.9ubuntu2/po/Makefile0000664000000000000000000000057211307015331013670 0ustar # # Copyright (c) 2001-2003 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs POTHEAD = $(PKG_NAME).pot LINGUAS = de pl LSRCFILES = $(LINGUAS:%=%.po) LDIRT = $(POTHEAD) XGETTEXTFILES = $(LOCALIZED_FILES) default: $(POTHEAD) $(LINGUAS:%=%.mo) include $(BUILDRULES) install: default $(INSTALL_LINGUAS) install-dev install-lib: xfsprogs-3.1.9ubuntu2/po/xfsprogs.pot0000664000000000000000000103731312062211463014636 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-12-13 10:28+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: .././copy/xfs_copy.c:102 #, c-format msgid "Check logfile \"%s\" for more details\n" msgstr "" #: .././copy/xfs_copy.c:108 #, c-format msgid "%s: could not write to logfile \"%s\".\n" msgstr "" #: .././copy/xfs_copy.c:111 #, c-format msgid "Aborting XFS copy -- logfile error -- reason: %s\n" msgstr "" #: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:286 .././copy/xfs_copy.c:563 #: .././copy/xfs_copy.c:570 msgid "Aborting XFS copy - reason" msgstr "" #: .././copy/xfs_copy.c:140 msgid "THE FOLLOWING COPIES FAILED TO COMPLETE\n" msgstr "" #: .././copy/xfs_copy.c:144 msgid "write error" msgstr "" #: .././copy/xfs_copy.c:146 msgid "lseek64 error" msgstr "" #: .././copy/xfs_copy.c:147 #, c-format msgid " at offset %lld\n" msgstr "" #: .././copy/xfs_copy.c:151 #, c-format msgid "All copies completed.\n" msgstr "" #: .././copy/xfs_copy.c:154 #, c-format msgid "See \"%s\" for more details.\n" msgstr "" #: .././copy/xfs_copy.c:255 #, c-format msgid "%s: write error on target %d \"%s\" at offset %lld\n" msgstr "" #: .././copy/xfs_copy.c:260 #, c-format msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" msgstr "" #: .././copy/xfs_copy.c:266 #, c-format msgid "Aborting target %d - reason" msgstr "" #: .././copy/xfs_copy.c:270 msgid "Aborting XFS copy - no more targets.\n" msgstr "" #: .././copy/xfs_copy.c:281 #, c-format msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" msgstr "" #: .././copy/xfs_copy.c:283 #, c-format msgid "%s: offset was probably %lld\n" msgstr "" #: .././copy/xfs_copy.c:294 #, c-format msgid "%s: Unknown child died (should never happen!)\n" msgstr "" #: .././copy/xfs_copy.c:304 #, c-format msgid "Usage: %s [-bd] [-L logfile] source target [target ...]\n" msgstr "" #: .././copy/xfs_copy.c:386 #, c-format msgid "%s: lseek64 failure at offset %lld\n" msgstr "" #: .././copy/xfs_copy.c:401 #, c-format msgid "assert error: buf->length = %d, buf->size = %d\n" msgstr "" #: .././copy/xfs_copy.c:408 #, c-format msgid "%s: read failure at offset %lld\n" msgstr "" #: .././copy/xfs_copy.c:543 .././db/init.c:93 .././estimate/xfs_estimate.c:141 #: .././fsr/xfs_fsr.c:302 .././growfs/xfs_growfs.c:182 .././io/init.c:184 #: .././logprint/logprint.c:196 .././mkfs/xfs_mkfs.c:1623 #: .././quota/init.c:131 .././repair/xfs_repair.c:317 .././rtcp/xfs_rtcp.c:55 #, c-format msgid "%s version %s\n" msgstr "" #: .././copy/xfs_copy.c:561 #, c-format msgid "%s: couldn't open log file \"%s\"\n" msgstr "" #: .././copy/xfs_copy.c:568 #, c-format msgid "%s: couldn't set up logfile stream\n" msgstr "" #: .././copy/xfs_copy.c:580 msgid "Couldn't allocate target array\n" msgstr "" #: .././copy/xfs_copy.c:595 #, c-format msgid "%s: couldn't register atexit function.\n" msgstr "" #: .././copy/xfs_copy.c:604 #, c-format msgid "%s: couldn't open source \"%s\"\n" msgstr "" #: .././copy/xfs_copy.c:610 #, c-format msgid "%s: couldn't stat source \"%s\"\n" msgstr "" #: .././copy/xfs_copy.c:620 #, c-format msgid "%s: Cannot set direct I/O flag on \"%s\".\n" msgstr "" #: .././copy/xfs_copy.c:625 #, c-format msgid "%s: xfsctl on file \"%s\" failed.\n" msgstr "" #: .././copy/xfs_copy.c:648 #, c-format msgid "%s: Warning -- a filesystem is mounted on the source device.\n" msgstr "" #: .././copy/xfs_copy.c:651 msgid "\t\tGenerated copies may be corrupt unless the source is\n" msgstr "" #: .././copy/xfs_copy.c:653 msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" msgstr "" #: .././copy/xfs_copy.c:670 #, c-format msgid "" "%s: couldn't initialize XFS library\n" "%s: Aborting.\n" msgstr "" #: .././copy/xfs_copy.c:684 #, c-format msgid "" "%s: %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" #: .././copy/xfs_copy.c:688 #, c-format msgid "" "%s %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" #: .././copy/xfs_copy.c:692 #, c-format msgid "" "%s: %s has an external log.\n" "%s: Aborting.\n" msgstr "" #: .././copy/xfs_copy.c:696 #, c-format msgid "" "%s: %s has a real-time section.\n" "%s: Aborting.\n" msgstr "" #: .././copy/xfs_copy.c:721 msgid "" "Error: filesystem block size is smaller than the disk sectorsize.\n" "Aborting XFS copy now.\n" msgstr "" #: .././copy/xfs_copy.c:742 #, c-format msgid "Creating file %s\n" msgstr "" #: .././copy/xfs_copy.c:760 #, c-format msgid "" "%s: a filesystem is mounted on target device \"%s\".\n" "%s cannot copy to mounted filesystems. Aborting\n" msgstr "" #: .././copy/xfs_copy.c:771 #, c-format msgid "%s: couldn't open target \"%s\"\n" msgstr "" #: .././copy/xfs_copy.c:781 #, c-format msgid "%s: cannot grow data section.\n" msgstr "" #: .././copy/xfs_copy.c:789 #, c-format msgid "%s: xfsctl on \"%s\" failed.\n" msgstr "" #: .././copy/xfs_copy.c:808 #, c-format msgid "%s: failed to write last block\n" msgstr "" #: .././copy/xfs_copy.c:810 #, c-format msgid "\tIs target \"%s\" too small?\n" msgstr "" #: .././copy/xfs_copy.c:820 msgid "Couldn't initialize global thread mask\n" msgstr "" #: .././copy/xfs_copy.c:827 msgid "Error initializing wbuf 0\n" msgstr "" #: .././copy/xfs_copy.c:835 msgid "Error initializing btree buf 1\n" msgstr "" #: .././copy/xfs_copy.c:840 msgid "Error creating first semaphore.\n" msgstr "" #: .././copy/xfs_copy.c:855 msgid "Couldn't malloc space for thread args\n" msgstr "" #: .././copy/xfs_copy.c:867 #, c-format msgid "Error creating thread mutex %d\n" msgstr "" #: .././copy/xfs_copy.c:884 #, c-format msgid "Error creating thread for target %d\n" msgstr "" #: .././copy/xfs_copy.c:974 msgid "WARNING: source filesystem inconsistent.\n" msgstr "" #: .././copy/xfs_copy.c:976 msgid " A leaf btree rec isn't a leaf. Aborting now.\n" msgstr "" #: .././db/check.c:372 msgid "free block usage information" msgstr "" #: .././db/check.c:375 msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." msgstr "" #: .././db/check.c:376 msgid "get block usage and check consistency" msgstr "" #: .././db/check.c:379 msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." msgstr "" #: .././db/check.c:380 msgid "trash randomly selected block(s)" msgstr "" #: .././db/check.c:383 msgid "[-n] [-c blockcount]" msgstr "" #: .././db/check.c:384 msgid "print usage for current block(s)" msgstr "" #: .././db/check.c:387 msgid "[-s] [-i ino] ..." msgstr "" #: .././db/check.c:388 msgid "print inode-name pairs" msgstr "" #: .././db/check.c:408 #, c-format msgid "-i %lld bad inode number\n" msgstr "" #: .././db/check.c:420 #, c-format msgid "inode %lld add link, now %u\n" msgstr "" #: .././db/check.c:447 #, c-format msgid "inode %lld parent %lld\n" msgstr "" #: .././db/check.c:760 msgid "block usage information not allocated\n" msgstr "" #: .././db/check.c:798 msgid "already have block usage information\n" msgstr "" #: .././db/check.c:814 .././db/check.c:922 msgid "WARNING: this may be a newer XFS filesystem.\n" msgstr "" #: .././db/check.c:850 #, c-format msgid "sb_icount %lld, counted %lld\n" msgstr "" #: .././db/check.c:856 #, c-format msgid "sb_ifree %lld, counted %lld\n" msgstr "" #: .././db/check.c:862 #, c-format msgid "sb_fdblocks %lld, counted %lld\n" msgstr "" #: .././db/check.c:868 #, c-format msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" msgstr "" #: .././db/check.c:874 #, c-format msgid "sb_frextents %lld, counted %lld\n" msgstr "" #: .././db/check.c:881 #, c-format msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" msgstr "" #: .././db/check.c:890 #, c-format msgid "sb versionnum missing attr bit %x\n" msgstr "" #: .././db/check.c:897 #, c-format msgid "sb versionnum missing nlink bit %x\n" msgstr "" #: .././db/check.c:904 #, c-format msgid "sb versionnum missing quota bit %x\n" msgstr "" #: .././db/check.c:911 #, c-format msgid "sb versionnum extra align bit %x\n" msgstr "" #: .././db/check.c:951 msgid "zeroed" msgstr "" #: .././db/check.c:951 msgid "set" msgstr "" #: .././db/check.c:951 msgid "flipped" msgstr "" #: .././db/check.c:951 msgid "randomized" msgstr "" #: .././db/check.c:961 #, c-format msgid "can't read block %u/%u for trashing\n" msgstr "" #: .././db/check.c:991 #, c-format msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" msgstr "" #: .././db/check.c:1023 .././db/check.c:1180 msgid "must run blockget first\n" msgstr "" #: .././db/check.c:1067 #, c-format msgid "bad blocktrash count %s\n" msgstr "" #: .././db/check.c:1081 #, c-format msgid "bad blocktrash type %s\n" msgstr "" #: .././db/check.c:1090 #, c-format msgid "bad blocktrash min %s\n" msgstr "" #: .././db/check.c:1098 #, c-format msgid "bad blocktrash max %s\n" msgstr "" #: .././db/check.c:1103 msgid "bad option for blocktrash command\n" msgstr "" #: .././db/check.c:1108 msgid "bad min/max for blocktrash command\n" msgstr "" #: .././db/check.c:1134 msgid "blocktrash: no matching blocks\n" msgstr "" #: .././db/check.c:1138 #, c-format msgid "blocktrash: seed %u\n" msgstr "" #: .././db/check.c:1196 #, c-format msgid "bad blockuse count %s\n" msgstr "" #: .././db/check.c:1202 .././db/check.c:1887 msgid "must run blockget -n first\n" msgstr "" #: .././db/check.c:1208 msgid "bad option for blockuse command\n" msgstr "" #: .././db/check.c:1215 #, c-format msgid "block %llu (%u/%u) type %s" msgstr "" #: .././db/check.c:1219 #, c-format msgid " inode %lld" msgstr "" #: .././db/check.c:1257 #, c-format msgid "block %u/%u expected type %s got %s\n" msgstr "" #: .././db/check.c:1289 #, c-format msgid "blocks %u/%u..%u claimed by inode %lld\n" msgstr "" #: .././db/check.c:1297 #, c-format msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" msgstr "" #: .././db/check.c:1326 #, c-format msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" msgstr "" #: .././db/check.c:1334 #, c-format msgid "disconnected inode %lld, nlink %d\n" msgstr "" #: .././db/check.c:1338 #, c-format msgid "allocated inode %lld has 0 link count\n" msgstr "" #: .././db/check.c:1348 #, c-format msgid "inode %lld name %s\n" msgstr "" #: .././db/check.c:1382 .././db/check.c:1397 #, c-format msgid "block %u/%u out of range\n" msgstr "" #: .././db/check.c:1385 .././db/check.c:1400 #, c-format msgid "blocks %u/%u..%u out of range\n" msgstr "" #: .././db/check.c:1423 #, c-format msgid "rtblock %llu expected type %s got %s\n" msgstr "" #: .././db/check.c:1443 #, c-format msgid "rtblocks %llu..%llu claimed by inode %lld\n" msgstr "" #: .././db/check.c:1452 #, c-format msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" msgstr "" #: .././db/check.c:1470 #, c-format msgid "root inode %lld is missing\n" msgstr "" #: .././db/check.c:1475 #, c-format msgid "root inode %lld is not a directory\n" msgstr "" #: .././db/check.c:1491 #, c-format msgid "rtblock %llu out of range\n" msgstr "" #: .././db/check.c:1515 #, c-format msgid "blocks %u/%u..%u claimed by block %u/%u\n" msgstr "" #: .././db/check.c:1524 #, c-format msgid "setting block %u/%u to %s\n" msgstr "" #: .././db/check.c:1547 #, c-format msgid "setting rtblock %llu to %s\n" msgstr "" #: .././db/check.c:1568 .././repair/rt.c:151 #, c-format msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" msgstr "" #: .././db/check.c:1593 #, c-format msgid "block %u/%u type %s not expected\n" msgstr "" #: .././db/check.c:1614 #, c-format msgid "rtblock %llu type %s not expected\n" msgstr "" #: .././db/check.c:1651 #, c-format msgid "dir ino %lld missing leaf entry for %x/%x\n" msgstr "" #: .././db/check.c:1770 #, c-format msgid "bad superblock magic number %x, giving up\n" msgstr "" #: .././db/check.c:1824 msgid "bad option for blockget command\n" msgstr "" #: .././db/check.c:1904 #, c-format msgid "bad option -%c for ncheck command\n" msgstr "" #: .././db/check.c:1977 .././db/check.c:2946 #, c-format msgid "block 0 for directory inode %lld is missing\n" msgstr "" #: .././db/check.c:1997 .././db/check.c:2957 #, c-format msgid "can't read block 0 for directory inode %lld\n" msgstr "" #: .././db/check.c:2043 #, c-format msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" msgstr "" #: .././db/check.c:2046 #, c-format msgid "bmap rec out of order, inode %lld entry %d\n" msgstr "" #: .././db/check.c:2052 #, c-format msgid "inode %lld bad rt block number %lld, offset %lld\n" msgstr "" #: .././db/check.c:2062 .././db/check.c:2068 #, c-format msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" msgstr "" #: .././db/check.c:2086 .././db/check.c:2100 #, c-format msgid "inode %lld block %lld at offset %lld\n" msgstr "" #: .././db/check.c:2127 #, c-format msgid "level for ino %lld %s fork bmap root too large (%u)\n" msgstr "" #: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 #: .././db/bmap.c:216 .././repair/scan.c:184 .././repair/dinode.c:568 #: .././repair/dinode.c:1135 msgid "data" msgstr "" #: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 #: .././db/bmap.c:216 .././repair/scan.c:186 .././repair/dinode.c:570 #: .././repair/dinode.c:1137 msgid "attr" msgstr "" #: .././db/check.c:2139 #, c-format msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" msgstr "" #: .././db/check.c:2166 #, c-format msgid "extent count for ino %lld %s fork too low (%d) for file format\n" msgstr "" #: .././db/check.c:2216 .././db/check.c:3297 #, c-format msgid "bad directory data magic # %#x for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:2233 #, c-format msgid "bad block directory tail for dir ino %lld\n" msgstr "" #: .././db/check.c:2278 #, c-format msgid "dir %lld block %d bad free entry at %d\n" msgstr "" #: .././db/check.c:2302 #, c-format msgid "dir %lld block %d zero length entry at %d\n" msgstr "" #: .././db/check.c:2311 #, c-format msgid "dir %lld block %d bad entry at %d\n" msgstr "" #: .././db/check.c:2329 #, c-format msgid "dir %lld block %d entry %*.*s %lld\n" msgstr "" #: .././db/check.c:2336 #, c-format msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" msgstr "" #: .././db/check.c:2346 .././db/check.c:3020 #, c-format msgid "multiple .. entries in dir %lld (%lld, %lld)\n" msgstr "" #: .././db/check.c:2363 .././db/check.c:3037 #, c-format msgid "dir %lld entry . inode number mismatch (%lld)\n" msgstr "" #: .././db/check.c:2376 #, c-format msgid "dir %lld block %d bad count %u\n" msgstr "" #: .././db/check.c:2387 .././db/check.c:3311 #, c-format msgid "dir %lld block %d extra leaf entry %x %x\n" msgstr "" #: .././db/check.c:2399 #, c-format msgid "dir %lld block %d bad bestfree data\n" msgstr "" #: .././db/check.c:2407 #, c-format msgid "dir %lld block %d bad block tail count %d (stale %d)\n" msgstr "" #: .././db/check.c:2416 #, c-format msgid "dir %lld block %d bad stale tail count %d\n" msgstr "" #: .././db/check.c:2422 #, c-format msgid "dir %lld block %d consecutive free entries\n" msgstr "" #: .././db/check.c:2428 #, c-format msgid "dir %lld block %d entry/unused tag mismatch\n" msgstr "" #: .././db/check.c:2481 #, c-format msgid "no . entry for directory %lld\n" msgstr "" #: .././db/check.c:2486 #, c-format msgid "no .. entry for directory %lld\n" msgstr "" #: .././db/check.c:2490 #, c-format msgid ". and .. same for non-root directory %lld\n" msgstr "" #: .././db/check.c:2495 #, c-format msgid "root directory %lld has .. %lld\n" msgstr "" #: .././db/check.c:2525 .././db/check.c:2560 #, c-format msgid "bad size (%lld) or format (%d) for directory inode %lld\n" msgstr "" #: .././db/check.c:2588 #, c-format msgid "bad number of extents %d for inode %lld\n" msgstr "" #: .././db/check.c:2660 #, c-format msgid "bad magic number %#x for inode %lld\n" msgstr "" #: .././db/check.c:2667 #, c-format msgid "bad version number %#x for inode %lld\n" msgstr "" #: .././db/check.c:2675 #, c-format msgid "bad nblocks %lld for free inode %lld\n" msgstr "" #: .././db/check.c:2686 #, c-format msgid "bad nlink %d for free inode %lld\n" msgstr "" #: .././db/check.c:2692 #, c-format msgid "bad mode %#o for free inode %lld\n" msgstr "" #: .././db/check.c:2701 #, c-format msgid "bad next unlinked %#x for inode %lld\n" msgstr "" #: .././db/check.c:2711 #, c-format msgid "bad format %d for inode %lld type %#o\n" msgstr "" #: .././db/check.c:2718 #, c-format msgid "bad fork offset %d for inode %lld\n" msgstr "" #: .././db/check.c:2725 #, c-format msgid "bad attribute format %d for inode %lld\n" msgstr "" #: .././db/check.c:2731 #, c-format msgid "" "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s" "%s%s\n" msgstr "" #: .././db/check.c:2851 #, c-format msgid "bad nblocks %lld for inode %lld, counted %lld\n" msgstr "" #: .././db/check.c:2858 #, c-format msgid "bad nextents %d for inode %lld, counted %d\n" msgstr "" #: .././db/check.c:2864 #, c-format msgid "bad anextents %d for inode %lld, counted %d\n" msgstr "" #: .././db/check.c:2916 #, c-format msgid "local inode %lld data is too large (size %lld)\n" msgstr "" #: .././db/check.c:2925 #, c-format msgid "local inode %lld attr is too large (size %d)\n" msgstr "" #: .././db/check.c:2990 #, c-format msgid "bad directory leaf magic # %#x for dir ino %lld\n" msgstr "" #: .././db/check.c:3003 .././db/check.c:3768 #, c-format msgid "dir %lld entry %*.*s %lld\n" msgstr "" #: .././db/check.c:3010 .././db/check.c:3664 .././db/check.c:3756 #, c-format msgid "dir %lld entry %*.*s bad inode number %lld\n" msgstr "" #: .././db/check.c:3089 .././db/check.c:3358 #, c-format msgid "dir inode %lld block %u=%llu\n" msgstr "" #: .././db/check.c:3101 .././db/check.c:3368 #, c-format msgid "can't read block %u for directory inode %lld\n" msgstr "" #: .././db/check.c:3115 .././db/check.c:3381 #, c-format msgid "multiple .. entries in dir %lld\n" msgstr "" #: .././db/check.c:3137 #, c-format msgid "missing free index for data block %d in dir ino %lld\n" msgstr "" #: .././db/check.c:3163 #, c-format msgid "bad free block magic # %#x for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3173 #, c-format msgid "bad free block firstdb %d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3186 #, c-format msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3200 #, c-format msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3214 #, c-format msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3243 #, c-format msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3252 #, c-format msgid "single leaf block for dir ino %lld block %d should be at block %d\n" msgstr "" #: .././db/check.c:3264 #, c-format msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" msgstr "" #: .././db/check.c:3288 #, c-format msgid "bad node block level %d for dir ino %lld block %d\n" msgstr "" #: .././db/check.c:3320 #, c-format msgid "dir %lld block %d stale mismatch %d/%d\n" msgstr "" #: .././db/check.c:3352 #, c-format msgid "can't read root block for directory inode %lld\n" msgstr "" #: .././db/check.c:3441 #, c-format msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" msgstr "" #: .././db/check.c:3451 #, c-format msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" msgstr "" #: .././db/check.c:3459 #, c-format msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" msgstr "" #: .././db/check.c:3468 #, c-format msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" msgstr "" #: .././db/check.c:3478 #, c-format msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" msgstr "" #: .././db/check.c:3487 #, c-format msgid "bad id %u for %s dqblk %lld entry %d id %u\n" msgstr "" #: .././db/check.c:3533 #, c-format msgid "block %lld for rtbitmap inode is missing\n" msgstr "" #: .././db/check.c:3544 #, c-format msgid "can't read block %lld for rtbitmap inode\n" msgstr "" #: .././db/check.c:3600 #, c-format msgid "block %lld for rtsummary inode is missing\n" msgstr "" #: .././db/check.c:3611 #, c-format msgid "can't read block %lld for rtsummary inode\n" msgstr "" #: .././db/check.c:3644 .././db/check.c:3748 #, c-format msgid "dir %lld entry . %lld\n" msgstr "" #: .././db/check.c:3652 #, c-format msgid "dir %llu bad size in entry at %d\n" msgstr "" #: .././db/check.c:3676 #, c-format msgid "dir %lld entry %*.*s offset %d %lld\n" msgstr "" #: .././db/check.c:3681 #, c-format msgid "dir %lld entry %*.*s bad offset %d\n" msgstr "" #: .././db/check.c:3694 #, c-format msgid "dir %llu size is %lld, should be %u\n" msgstr "" #: .././db/check.c:3702 #, c-format msgid "dir %llu offsets too high\n" msgstr "" #: .././db/check.c:3713 .././db/check.c:3782 #, c-format msgid "dir %lld entry .. bad inode number %lld\n" msgstr "" #: .././db/check.c:3718 .././db/check.c:3787 #, c-format msgid "dir %lld entry .. %lld\n" msgstr "" #: .././db/check.c:3721 #, c-format msgid "dir %lld i8count mismatch is %d should be %d\n" msgstr "" #: .././db/check.c:3773 #, c-format msgid "dir %llu size is %lld, should be %d\n" msgstr "" #: .././db/check.c:3864 #, c-format msgid "%s quota id %u, have/exp" msgstr "" #: .././db/check.c:3867 #, c-format msgid " bc %lld/%lld" msgstr "" #: .././db/check.c:3871 #, c-format msgid " ic %lld/%lld" msgstr "" #: .././db/check.c:3875 #, c-format msgid " rc %lld/%lld" msgstr "" #: .././db/check.c:3931 #, c-format msgid "can't read superblock for ag %u\n" msgstr "" #: .././db/check.c:3940 #, c-format msgid "bad sb magic # %#x in ag %u\n" msgstr "" #: .././db/check.c:3946 #, c-format msgid "bad sb version # %#x in ag %u\n" msgstr "" #: .././db/check.c:3956 .././db/sb.c:201 msgid "mkfs not completed successfully\n" msgstr "" #: .././db/check.c:3968 .././db/frag.c:365 #, c-format msgid "can't read agf block for ag %u\n" msgstr "" #: .././db/check.c:3974 #, c-format msgid "bad agf magic # %#x in ag %u\n" msgstr "" #: .././db/check.c:3980 #, c-format msgid "bad agf version # %#x in ag %u\n" msgstr "" #: .././db/check.c:3996 .././db/frag.c:374 #, c-format msgid "can't read agi block for ag %u\n" msgstr "" #: .././db/check.c:4002 #, c-format msgid "bad agi magic # %#x in ag %u\n" msgstr "" #: .././db/check.c:4008 #, c-format msgid "bad agi version # %#x in ag %u\n" msgstr "" #: .././db/check.c:4033 .././repair/scan.c:1121 #, c-format msgid "agf_freeblks %u, counted %u in ag %u\n" msgstr "" #: .././db/check.c:4040 .././repair/scan.c:1126 #, c-format msgid "agf_longest %u, counted %u in ag %u\n" msgstr "" #: .././db/check.c:4048 #, c-format msgid "agf_btreeblks %u, counted %u in ag %u\n" msgstr "" #: .././db/check.c:4056 .././repair/scan.c:1156 #, c-format msgid "agi_count %u, counted %u in ag %u\n" msgstr "" #: .././db/check.c:4063 .././repair/scan.c:1161 #, c-format msgid "agi_freecount %u, counted %u in ag %u\n" msgstr "" #: .././db/check.c:4072 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" msgstr "" #: .././db/check.c:4109 #, c-format msgid "can't read agfl block for ag %u\n" msgstr "" #: .././db/check.c:4128 #, c-format msgid "freeblk count %u != flcount %u in ag %u\n" msgstr "" #: .././db/check.c:4157 .././db/check.c:4185 .././db/frag.c:397 #: .././db/frag.c:420 .././db/freesp.c:270 #, c-format msgid "can't read btree block %u/%u\n" msgstr "" #: .././db/check.c:4218 #, c-format msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" msgstr "" #: .././db/check.c:4225 #, c-format msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" msgstr "" #: .././db/check.c:4237 .././db/check.c:4254 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" msgstr "" #: .././db/check.c:4282 #, c-format msgid "bad magic # %#x in btbno block %u/%u\n" msgstr "" #: .././db/check.c:4291 #, c-format msgid "expected level %d got %d in btbno block %u/%u\n" msgstr "" #: .././db/check.c:4300 .././db/check.c:4328 .././db/check.c:4373 #: .././db/check.c:4404 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" msgstr "" #: .././db/check.c:4315 .././repair/scan.c:621 #, c-format msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" msgstr "" #: .././db/check.c:4355 #, c-format msgid "bad magic # %#x in btcnt block %u/%u\n" msgstr "" #: .././db/check.c:4364 #, c-format msgid "expected level %d got %d in btcnt block %u/%u\n" msgstr "" #: .././db/check.c:4392 .././repair/scan.c:633 #, c-format msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" msgstr "" #: .././db/check.c:4435 #, c-format msgid "bad magic # %#x in inobt block %u/%u\n" msgstr "" #: .././db/check.c:4442 #, c-format msgid "expected level %d got %d in inobt block %u/%u\n" msgstr "" #: .././db/check.c:4451 .././db/check.c:4517 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" msgstr "" #: .././db/check.c:4486 .././db/frag.c:489 #, c-format msgid "can't read inode block %u/%u\n" msgstr "" #: .././db/check.c:4504 #, c-format msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" msgstr "" #: .././db/check.c:4559 #, c-format msgid "setting inode to %lld for block %u/%u\n" msgstr "" #: .././db/check.c:4591 #, c-format msgid "setting inode to %lld for rtblock %llu\n" msgstr "" #: .././db/check.c:4607 #, c-format msgid "inode %lld nlink %u %s dir\n" msgstr "" #: .././db/convert.c:171 #, c-format msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" msgstr "" #: .././db/convert.c:176 .././db/convert.c:183 #, c-format msgid "unknown conversion type %s\n" msgstr "" #: .././db/convert.c:187 msgid "result type same as argument\n" msgstr "" #: .././db/convert.c:191 #, c-format msgid "conflicting conversion type %s\n" msgstr "" #: .././db/convert.c:270 #, c-format msgid "%s is not a number\n" msgstr "" #: .././db/metadump.c:55 msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" msgstr "" #: .././db/metadump.c:56 msgid "dump metadata to a file" msgstr "" #: .././db/metadump.c:86 #, c-format msgid "" "\n" " The 'metadump' command dumps the known metadata to a compact file suitable\n" " for compressing and sending to an XFS maintainer for corruption analysis \n" " or xfs_repair failures.\n" "\n" " Options:\n" " -e -- Ignore read errors and keep going\n" " -g -- Display dump progress\n" " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" " -o -- Don't obfuscate names and extended attributes\n" " -w -- Show warnings of bad metadata information\n" "\n" msgstr "" #: .././db/frag.c:173 #, c-format msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" msgstr "" #: .././db/frag.c:214 msgid "bad option for frag command\n" msgstr "" #: .././db/frag.c:349 #, c-format msgid "inode %lld actual %lld ideal %lld\n" msgstr "" #: .././db/frag.c:443 .././db/frag.c:453 #, c-format msgid "invalid numrecs (%u) in %s block\n" msgstr "" #: .././db/attrset.c:38 msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" msgstr "" #: .././db/attrset.c:39 msgid "set the named attribute on the current inode" msgstr "" #: .././db/attrset.c:42 msgid "[-r|-s|-p|-u] [-n] name" msgstr "" #: .././db/attrset.c:43 msgid "remove the named attribute from the current inode" msgstr "" #: .././db/attrset.c:49 msgid "" "\n" " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" " the extended attribute allocation and removal code.\n" " Both commands require an attribute name to be specified, and the attr_set\n" " command allows an optional value length (-v) to be provided as well.\n" " There are 4 namespace flags:\n" " -r -- 'root'\n" " -u -- 'user'\t\t(default)\n" " -s -- 'secure'\n" "\n" " For attr_set, these options further define the type of set operation:\n" " -C -- 'create' - create attribute, fail if it already exists\n" " -R -- 'replace' - replace attribute, fail if it does not exist\n" " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" "\n" msgstr "" #: .././db/attrset.c:86 .././db/attrset.c:189 .././db/addr.c:72 #: .././db/print.c:74 .././db/type.c:102 .././db/write.c:101 msgid "no current type\n" msgstr "" #: .././db/attrset.c:90 .././db/attrset.c:193 msgid "current type is not inode\n" msgstr "" #: .././db/attrset.c:125 #, c-format msgid "bad attr_set valuelen %s\n" msgstr "" #: .././db/attrset.c:131 msgid "bad option for attr_set command\n" msgstr "" #: .././db/attrset.c:137 msgid "too few options for attr_set (no name given)\n" msgstr "" #: .././db/attrset.c:146 #, c-format msgid "cannot allocate buffer (%d)\n" msgstr "" #: .././db/attrset.c:155 .././db/attrset.c:230 #, c-format msgid "failed to iget inode %llu\n" msgstr "" #: .././db/attrset.c:162 #, c-format msgid "failed to set attr %s on inode %llu\n" msgstr "" #: .././db/attrset.c:217 msgid "bad option for attr_remove command\n" msgstr "" #: .././db/attrset.c:223 msgid "too few options for attr_remove (no name given)\n" msgstr "" #: .././db/attrset.c:236 #, c-format msgid "failed to remove attr %s from inode %llu\n" msgstr "" #: .././db/addr.c:35 msgid "[field-expression]" msgstr "" #: .././db/addr.c:36 msgid "set current address" msgstr "" #: .././db/addr.c:42 msgid "" "\n" " 'addr' uses the given field to set the filesystem address and type\n" "\n" " Examples:\n" "\n" " sb\n" " a rootino - set the type to inode and set position to the root inode\n" " a u.bmx[0].startblock (for inode with blockmap)\n" "\n" msgstr "" #: .././db/addr.c:82 #, c-format msgid "no fields for type %s\n" msgstr "" #: .././db/addr.c:95 msgid "array not allowed for addr command\n" msgstr "" #: .././db/addr.c:105 #, c-format msgid "no next type for field %s\n" msgstr "" #: .././db/addr.c:112 #, c-format msgid "no addr function for field %s (type %s)\n" msgstr "" #: .././db/agf.c:35 .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 msgid "[agno]" msgstr "" #: .././db/agf.c:36 msgid "set address to agf header" msgstr "" #: .././db/agf.c:79 msgid "" "\n" " set allocation group free block list\n" "\n" " Example:\n" "\n" " agf 2 - move location to AGF in 2nd filesystem allocation group\n" "\n" " Located in the second sector of each allocation group, the AGF\n" " contains the root of two different freespace btrees:\n" " The 'cnt' btree keeps track freespace indexed on section size.\n" " The 'bno' btree tracks sections of freespace indexed on block number.\n" msgstr "" #: .././db/agf.c:104 .././db/agfl.c:90 .././db/agi.c:89 .././db/sb.c:151 #, c-format msgid "bad allocation group number %s\n" msgstr "" #: .././db/agfl.c:37 msgid "set address to agfl block" msgstr "" #: .././db/agfl.c:63 msgid "" "\n" " set allocation group freelist\n" "\n" " Example:\n" "\n" " agfl 5\n" " Located in the fourth sector of each allocation group,\n" " the agfl freelist for internal btree space allocation is maintained\n" " for each allocation group. This acts as a reserved pool of space\n" " separate from the general filesystem freespace (not used for user data).\n" "\n" msgstr "" #: .././db/agi.c:36 msgid "set address to agi header" msgstr "" #: .././db/agi.c:64 msgid "" "\n" " set allocation group inode btree\n" "\n" " Example:\n" "\n" " agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" "\n" " Located in the 3rd 512 byte block of each allocation group,\n" " the agi inode btree tracks all used/free inodes in the allocation group.\n" " Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" "\n" msgstr "" #: .././db/block.c:43 .././db/block.c:49 msgid "filoff" msgstr "" #: .././db/block.c:44 msgid "set address to file offset (attr fork)" msgstr "" #: .././db/block.c:46 msgid "[d]" msgstr "" #: .././db/block.c:47 msgid "set address to daddr value" msgstr "" #: .././db/block.c:50 msgid "set address to file offset (data fork)" msgstr "" #: .././db/block.c:52 msgid "[fsb]" msgstr "" #: .././db/block.c:53 msgid "set address to fsblock value" msgstr "" #: .././db/block.c:59 msgid "" "\n" " Example:\n" "\n" " 'ablock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's attribute fork. The filesystem block size is specified in\n" " the superblock.\n" "\n" msgstr "" #: .././db/block.c:82 .././db/block.c:177 #, c-format msgid "bad block number %s\n" msgstr "" #: .././db/block.c:90 msgid "no attribute data for file\n" msgstr "" #: .././db/block.c:96 msgid "file attr block is unmapped\n" msgstr "" #: .././db/block.c:119 msgid "" "\n" " Example:\n" "\n" " 'daddr 102' - sets position to the 102nd absolute disk block\n" " (512 byte block).\n" msgstr "" #: .././db/block.c:135 #, c-format msgid "current daddr is %lld\n" msgstr "" #: .././db/block.c:141 #, c-format msgid "bad daddr %s\n" msgstr "" #: .././db/block.c:153 msgid "" "\n" " Example:\n" "\n" " 'dblock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's data fork. The filesystem block size is specified in the\n" " superblock.\n" "\n" msgstr "" #: .././db/block.c:185 msgid "no type for file data\n" msgstr "" #: .././db/block.c:192 msgid "file data block is unmapped\n" msgstr "" #: .././db/block.c:210 msgid "" "\n" " Example:\n" "\n" " 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" " The filesystem block size is specified in the superblock and set during\n" " mkfs time. Offset is absolute (not AG relative).\n" "\n" msgstr "" #: .././db/block.c:229 #, c-format msgid "current fsblock is %lld\n" msgstr "" #: .././db/block.c:235 .././db/block.c:241 #, c-format msgid "bad fsblock %s\n" msgstr "" #: .././db/init.c:46 #, c-format msgid "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" msgstr "" #: .././db/init.c:112 msgid "" "\n" "fatal error -- couldn't initialize XFS library\n" msgstr "" #: .././db/init.c:118 #, c-format msgid "%s: %s is invalid (cannot read first 512 bytes)\n" msgstr "" #: .././db/init.c:129 #, c-format msgid "" "%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" msgstr "" #: .././db/init.c:141 #, c-format msgid "%s: device %s unusable (not an XFS filesystem?)\n" msgstr "" #: .././db/command.c:82 .././db/help.c:56 .././libxcmd/help.c:49 #, c-format msgid "command %s not found\n" msgstr "" #: .././db/command.c:86 #, c-format msgid "bad argument count %d to %s, expected " msgstr "" #: .././db/command.c:88 #, c-format msgid "at least %d" msgstr "" #: .././db/command.c:92 #, c-format msgid "between %d and %d" msgstr "" #: .././db/command.c:93 msgid " arguments\n" msgstr "" #: .././db/debug.c:27 msgid "[flagbits]" msgstr "" #: .././db/debug.c:28 msgid "set debug option bits" msgstr "" #: .././db/debug.c:42 #, c-format msgid "bad value for debug %s\n" msgstr "" #: .././db/dquot.c:37 msgid "[projid|gid|uid]" msgstr "" #: .././db/dquot.c:38 msgid "set current address to project, group or user quota block" msgstr "" #: .././db/dquot.c:124 msgid "bad option for dquot command\n" msgstr "" #: .././db/dquot.c:128 msgid "project" msgstr "" #: .././db/dquot.c:128 msgid "group" msgstr "" #: .././db/dquot.c:128 msgid "user" msgstr "" #: .././db/dquot.c:130 #, c-format msgid "dquot command requires one %s id argument\n" msgstr "" #: .././db/dquot.c:137 #, c-format msgid "no %s quota inode present\n" msgstr "" #: .././db/dquot.c:142 #, c-format msgid "bad %s id for dquot %s\n" msgstr "" #: .././db/dquot.c:154 #, c-format msgid "no %s quota data for id %d\n" msgstr "" #: .././db/echo.c:27 msgid "[args]..." msgstr "" #: .././db/echo.c:28 msgid "echo arguments" msgstr "" #: .././db/faddr.c:40 .././db/faddr.c:63 msgid "no current allocation group, cannot set new addr\n" msgstr "" #: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 #: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 #: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 msgid "null block number, cannot set new addr\n" msgstr "" #: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 #: .././db/faddr.c:389 msgid "null inode number, cannot set new addr\n" msgstr "" #: .././db/faddr.c:88 msgid "null attribute block number, cannot set new addr\n" msgstr "" #: .././db/faddr.c:94 msgid "attribute block is unmapped\n" msgstr "" #: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 #: .././db/faddr.c:239 msgid "file block is unmapped\n" msgstr "" #: .././db/faddr.c:285 msgid "null directory block number, cannot set new addr\n" msgstr "" #: .././db/faddr.c:292 msgid "directory block is unmapped\n" msgstr "" #: .././db/flist.c:149 #, c-format msgid "field %s not found\n" msgstr "" #: .././db/flist.c:159 #, c-format msgid "no elements in %s\n" msgstr "" #: .././db/flist.c:165 #, c-format msgid "indices %d-%d for field %s out of range %d-%d\n" msgstr "" #: .././db/flist.c:173 #, c-format msgid "index %d for field %s out of range %d-%d\n" msgstr "" #: .././db/flist.c:187 #, c-format msgid "field %s is not an array\n" msgstr "" #: .././db/flist.c:200 #, c-format msgid "field %s has no subfields\n" msgstr "" #: .././db/flist.c:220 #, c-format msgid "fl@%p:\n" msgstr "" #: .././db/flist.c:221 #, c-format msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" msgstr "" #: .././db/flist.c:223 #, c-format msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" msgstr "" #: .././db/flist.c:225 msgid "oklow " msgstr "" #: .././db/flist.c:226 msgid "okhigh" msgstr "" #: .././db/flist.c:227 #, c-format msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" msgstr "" #: .././db/flist.c:230 #, c-format msgid "\tfld->flags=%d (%s%s%s%s%s)\n" msgstr "" #: .././db/flist.c:322 #, c-format msgid "bad syntax in field name %s\n" msgstr "" #: .././db/flist.c:378 #, c-format msgid "missing closing quote %s\n" msgstr "" #: .././db/flist.c:395 #, c-format msgid "bad character in field %s\n" msgstr "" #: .././db/fprint.c:98 msgid "null" msgstr "" #: .././db/inode.c:385 #, c-format msgid "bad value for inode number %s\n" msgstr "" #: .././db/inode.c:390 .././db/bmap.c:153 msgid "no current inode\n" msgstr "" #: .././db/inode.c:392 #, c-format msgid "current inode number is %lld\n" msgstr "" #: .././db/inode.c:614 #, c-format msgid "bad inode number %lld\n" msgstr "" #: .././db/hash.c:30 msgid "string" msgstr "" #: .././db/hash.c:31 msgid "calculate hash value" msgstr "" #: .././db/hash.c:37 msgid "" "\n" " 'hash' prints out the calculated hash value for a string using the\n" "directory/attribute code hash function.\n" "\n" " Usage: \"hash \"\n" "\n" msgstr "" #: .././db/help.c:30 .././db/io.c:48 .././libxcmd/help.c:92 msgid "[command]" msgstr "" #: .././db/help.c:31 .././libxcmd/help.c:93 msgid "help for one or all commands" msgstr "" #: .././db/help.c:40 .././libxcmd/help.c:33 #, c-format msgid "" "\n" "Use 'help commandname' for extended help.\n" msgstr "" #: .././db/help.c:89 #, c-format msgid "(or %s) " msgstr "" #: .././db/input.c:43 msgid "source-file" msgstr "" #: .././db/input.c:44 msgid "get commands from source-file" msgstr "" #: .././db/input.c:320 #, c-format msgid "can't open %s\n" msgstr "" #: .././db/io.c:46 msgid "pop location from the stack" msgstr "" #: .././db/io.c:49 msgid "push location to the stack" msgstr "" #: .././db/io.c:52 msgid "view the location stack" msgstr "" #: .././db/io.c:55 msgid "move forward to next entry in the position ring" msgstr "" #: .././db/io.c:58 msgid "move to the previous location in the position ring" msgstr "" #: .././db/io.c:61 msgid "show position ring or move to a specific entry" msgstr "" #: .././db/io.c:91 #, c-format msgid "can't set block offset to %d\n" msgstr "" #: .././db/io.c:104 msgid "can't pop anything from I/O stack\n" msgstr "" #: .././db/io.c:132 msgid "" "\n" " Changes the address and data type to the first entry on the stack.\n" "\n" msgstr "" #: .././db/io.c:146 #, c-format msgid "\tbyte offset %lld, length %d\n" msgstr "" #: .././db/io.c:147 #, c-format msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" msgstr "" #: .././db/io.c:151 msgid "\tblock map" msgstr "" #: .././db/io.c:156 #, c-format msgid "\tinode %lld, dir inode %lld, type %s\n" msgstr "" #: .././db/io.c:157 .././growfs/xfs_growfs.c:86 .././logprint/log_misc.c:152 #: .././mkfs/xfs_mkfs.c:1979 #, c-format msgid "none" msgstr "" #: .././db/io.c:167 msgid "no entries in location ring.\n" msgstr "" #: .././db/io.c:171 msgid " type bblock bblen fsbno inode\n" msgstr "" #: .././db/io.c:225 #, c-format msgid "no such command %s\n" msgstr "" #: .././db/io.c:229 #, c-format msgid "no push form allowed for %s\n" msgstr "" #: .././db/io.c:253 msgid "" "\n" " Allows you to push the current address and data type on the stack for\n" " later return. 'push' also accepts an additional command to execute after\n" " storing the current address (ex: 'push a rootino' from the superblock).\n" "\n" msgstr "" #: .././db/io.c:269 .././db/io.c:310 msgid "ring is empty\n" msgstr "" #: .././db/io.c:273 msgid "no further entries\n" msgstr "" #: .././db/io.c:293 msgid "" "\n" " The 'forward' ('f') command moves to the next location in the position\n" " ring, updating the current position and data type. If the current " "location\n" " is the top entry in the ring, then the 'forward' command will have\n" " no effect.\n" "\n" msgstr "" #: .././db/io.c:314 msgid "no previous entries\n" msgstr "" #: .././db/io.c:334 msgid "" "\n" " The 'back' ('b') command moves to the previous location in the position\n" " ring, updating the current position and data type. If the current " "location\n" " is the last entry in the ring, then the 'back' command will have no " "effect.\n" "\n" msgstr "" #: .././db/io.c:357 #, c-format msgid "invalid entry: %d\n" msgstr "" #: .././db/io.c:374 #, c-format msgid "" "\n" " The position ring automatically keeps track of each disk location and\n" " structure type for each change of position you make during your xfs_db\n" " session. The last %d most recent entries are kept in the ring.\n" "\n" " To display the current list of ring entries type 'ring' by itself on\n" " the command line. The entry highlighted by an asterisk ('*') is the\n" " current entry.\n" "\n" " To move to another entry in the ring type 'ring ' where is\n" " your desired entry from the ring position list.\n" "\n" " You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" " to the previous or next entry in the ring, respectively.\n" "\n" " Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" " location implicitly. Use the 'push' and 'pop' commands if you wish to\n" " store a specific location explicitly for later return.\n" "\n" msgstr "" #: .././db/io.c:438 .././db/io.c:481 #, c-format msgid "can't seek in filesystem at bb %lld\n" msgstr "" #: .././db/io.c:515 msgid "nothing to write\n" msgstr "" #: .././db/io.c:521 #, c-format msgid "incomplete write, block: %lld\n" msgstr "" #: .././db/io.c:524 #, c-format msgid "write error: %s\n" msgstr "" #: .././db/io.c:529 #, c-format msgid "incomplete read, block: %lld\n" msgstr "" #: .././db/io.c:532 #, c-format msgid "read error: %s\n" msgstr "" #: .././db/io.c:548 msgid "set_cur no stack element to set\n" msgstr "" #: .././db/io.c:554 #, c-format msgid "xfs_db got a bbmap for %lld\n" msgstr "" #: .././db/io.c:585 msgid "" "\n" " The stack is used to explicitly store your location and data type\n" " for later return. The 'push' operation stores the current address\n" " and type on the stack, the 'pop' operation returns you to the\n" " position and datatype of the top entry on the stack.\n" "\n" " The 'stack' allows explicit location saves, see 'ring' for implicit\n" " position tracking.\n" "\n" msgstr "" #: .././db/malloc.c:27 #, c-format msgid "%s: out of memory\n" msgstr "" #: .././db/output.c:30 msgid "[stop|start ]" msgstr "" #: .././db/output.c:31 msgid "start or stop logging to a file" msgstr "" #: .././db/output.c:68 #, c-format msgid "logging to %s\n" msgstr "" #: .././db/output.c:70 .././db/output.c:77 msgid "no log file\n" msgstr "" #: .././db/output.c:80 #, c-format msgid "already logging to %s\n" msgstr "" #: .././db/output.c:84 #, c-format msgid "can't open %s for writing\n" msgstr "" #: .././db/output.c:90 msgid "bad log command, ignored\n" msgstr "" #: .././db/print.c:41 msgid "[value]..." msgstr "" #: .././db/print.c:42 msgid "print field values" msgstr "" #: .././db/print.c:79 #, c-format msgid "no print function for type %s\n" msgstr "" #: .././db/print.c:153 msgid "(empty)\n" msgstr "" #: .././db/print.c:215 msgid "(empty)" msgstr "" #: .././db/print.c:275 msgid "no arguments allowed\n" msgstr "" #: .././db/quit.c:27 msgid "exit xfs_db" msgstr "" #: .././db/type.c:50 msgid "[newtype]" msgstr "" #: .././db/type.c:51 msgid "set/show current data type" msgstr "" #: .././db/type.c:104 #, c-format msgid "current type is \"%s\"\n" msgstr "" #: .././db/type.c:106 msgid "" "\n" " supported types are:\n" " " msgstr "" #: .././db/type.c:121 #, c-format msgid "no such type %s\n" msgstr "" #: .././db/type.c:124 msgid "no current object\n" msgstr "" #: .././db/write.c:41 msgid "[field or value]..." msgstr "" #: .././db/write.c:42 msgid "write value to disk" msgstr "" #: .././db/write.c:58 msgid "" "\n" " The 'write' command takes on different personalities depending on the\n" " type of object being worked with.\n" "\n" " Write has 3 modes:\n" " 'struct mode' - is active anytime you're looking at a filesystem object\n" " which contains individual fields (ex: an inode).\n" " 'data mode' - is active anytime you set a disk address directly or set\n" " the type to 'data'.\n" " 'string mode' - only used for writing symlink blocks.\n" "\n" " Examples:\n" " Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" " 'write fname \"hello\\000\"' - write superblock fname.\n" " (note: in struct mode strings are not null terminated)\n" " 'write fname #6669736800' - write superblock fname with " "hex.\n" " 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" " - write superblock uuid.\n" " Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" " 'write lshift 3' - shift the block 3 bytes to the left\n" " 'write sequence 1 5' - write a cycle of number [1-5] through\n" " the entire block.\n" " String mode: 'write \"This_is_a_filename\" - write null terminated " "string.\n" "\n" " In data mode type 'write' by itself for a list of specific commands.\n" "\n" msgstr "" #: .././db/write.c:95 #, c-format msgid "%s started in read only mode, writing disabled\n" msgstr "" #: .././db/write.c:107 #, c-format msgid "no handler function for type %s, write unsupported.\n" msgstr "" #: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 #: .././db/write.c:258 .././db/write.c:293 .././db/write.c:342 #: .././db/write.c:371 #, c-format msgid "length (%d) too large for data block size (%d)" msgstr "" #: .././db/write.c:559 msgid "usage: write fieldname value\n" msgstr "" #: .././db/write.c:565 #, c-format msgid "unable to parse '%s'.\n" msgstr "" #: .././db/write.c:579 msgid "parsing error\n" msgstr "" #: .././db/write.c:598 #, c-format msgid "unable to convert value '%s'.\n" msgstr "" #: .././db/write.c:621 msgid "usage (in string mode): write \"string...\"\n" msgstr "" #: .././db/write.c:663 msgid "write: invalid subcommand\n" msgstr "" #: .././db/write.c:668 #, c-format msgid "write %s: invalid number of arguments\n" msgstr "" #: .././db/write.c:692 msgid "usage: write (in data mode)\n" msgstr "" #: .././db/freesp.c:106 #, c-format msgid "total free extents %lld\n" msgstr "" #: .././db/freesp.c:107 #, c-format msgid "total free blocks %lld\n" msgstr "" #: .././db/freesp.c:108 #, c-format msgid "average free extent size %g\n" msgstr "" #: .././db/freesp.c:199 msgid "" "freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" msgstr "" #: .././db/freesp.c:406 msgid "from" msgstr "" #: .././db/freesp.c:406 msgid "to" msgstr "" #: .././db/freesp.c:406 .././repair/progress.c:26 msgid "extents" msgstr "" #: .././db/freesp.c:406 .././repair/progress.c:18 msgid "blocks" msgstr "" #: .././db/freesp.c:406 msgid "pct" msgstr "" #: .././db/sb.c:43 msgid "set current address to sb header" msgstr "" #: .././db/sb.c:45 msgid "[uuid]" msgstr "" #: .././db/sb.c:46 msgid "write/print FS uuid" msgstr "" #: .././db/sb.c:48 msgid "[label]" msgstr "" #: .././db/sb.c:49 msgid "write/print FS label" msgstr "" #: .././db/sb.c:51 msgid "[feature | [vnum fnum]]" msgstr "" #: .././db/sb.c:52 msgid "set feature bit(s) in the sb version field" msgstr "" #: .././db/sb.c:124 msgid "" "\n" " set allocation group superblock\n" "\n" " Example:\n" "\n" " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" "\n" " Located in the first sector of each allocation group, the superblock\n" " contains the base information for the filesystem.\n" " The superblock in allocation group 0 is the primary. The copies in the\n" " remaining allocation groups only serve as backup for filesystem recovery.\n" " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" "\n" msgstr "" #: .././db/sb.c:183 #, c-format msgid "can't read superblock for AG %u\n" msgstr "" #: .././db/sb.c:191 #, c-format msgid "bad sb magic # %#x in AG %u\n" msgstr "" #: .././db/sb.c:196 #, c-format msgid "bad sb version # %#x in AG %u\n" msgstr "" #: .././db/sb.c:218 msgid "aborting - external log specified for FS with an internal log\n" msgstr "" #: .././db/sb.c:224 msgid "aborting - no external log specified for FS with an external log\n" msgstr "" #: .././db/sb.c:242 msgid "ERROR: cannot find log head/tail, run xfs_repair\n" msgstr "" #: .././db/sb.c:247 #, c-format msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running %s. If you are unable to mount the filesystem, then use\n" "the xfs_repair -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" #: .././db/sb.c:264 msgid "Clearing log and setting UUID\n" msgstr "" #: .././db/sb.c:273 msgid "ERROR: cannot clear the log\n" msgstr "" #: .././db/sb.c:284 msgid "" "\n" " write/print FS uuid\n" "\n" " Example:\n" "\n" " 'uuid' - print UUID\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" " 'uuid generate' - generate and write\n" " 'uuid rewrite' - copy UUID from SB 0\n" "\n" "The print function checks the UUID in each SB and will warn if the UUIDs\n" "differ between AGs (the log is not checked). The write commands will\n" "set the uuid in all AGs to either a specified value, a newly generated\n" "value or the value found in the first superblock (SB 0) respectively.\n" "As a side effect of writing the UUID, the log is cleared (which is fine\n" "on a CLEANLY unmounted FS).\n" "\n" msgstr "" #: .././db/sb.c:336 .././db/sb.c:488 msgid "invalid parameters\n" msgstr "" #: .././db/sb.c:343 .././db/sb.c:495 .././db/sb.c:640 #, c-format msgid "%s: not in expert mode, writing disabled\n" msgstr "" #: .././db/sb.c:355 msgid "failed to read UUID from AG 0\n" msgstr "" #: .././db/sb.c:360 #, c-format msgid "old UUID = %s\n" msgstr "" #: .././db/sb.c:363 msgid "invalid UUID\n" msgstr "" #: .././db/sb.c:372 .././db/sb.c:500 .././db/sb.c:712 msgid "writing all SBs\n" msgstr "" #: .././db/sb.c:375 #, c-format msgid "failed to set UUID in AG %d\n" msgstr "" #: .././db/sb.c:380 #, c-format msgid "new UUID = %s\n" msgstr "" #: .././db/sb.c:388 #, c-format msgid "failed to read UUID from AG %d\n" msgstr "" #: .././db/sb.c:394 #, c-format msgid "warning: UUID in AG %d differs to the primary SB\n" msgstr "" #: .././db/sb.c:405 msgid "warning - external log specified for FS with an internal log\n" msgstr "" #: .././db/sb.c:408 msgid "warning - no external log specified for FS with an external log\n" msgstr "" #: .././db/sb.c:413 #, c-format msgid "UUID = %s\n" msgstr "" #: .././db/sb.c:424 msgid "" "\n" " write/print FS label\n" "\n" " Example:\n" "\n" " 'label' - print label\n" " 'label 123456789012' - write label\n" " 'label --' - write an empty label\n" "\n" "The print function checks the label in each SB and will warn if the labels\n" "differ between AGs. The write commands will set the label in all AGs to the\n" "specified value. The maximum length of a label is 12 characters - use of a\n" "longer label will result in truncation and a warning will be issued.\n" "\n" msgstr "" #: .././db/sb.c:461 #, c-format msgid "%s: truncating label length from %d to %d\n" msgstr "" #: .././db/sb.c:503 #, c-format msgid "failed to set label in AG %d\n" msgstr "" #: .././db/sb.c:506 #, c-format msgid "new label = \"%s\"\n" msgstr "" #: .././db/sb.c:513 #, c-format msgid "failed to read label in AG %d\n" msgstr "" #: .././db/sb.c:519 #, c-format msgid "warning: AG %d label differs\n" msgstr "" #: .././db/sb.c:521 #, c-format msgid "label = \"%s\"\n" msgstr "" #: .././db/sb.c:531 msgid "" "\n" " set/print feature bits in sb version\n" "\n" " Example:\n" "\n" " 'version' - print current feature bits\n" " 'version extflg' - enable unwritten extents\n" " 'version attr1' - enable v1 inline extended attributes\n" " 'version attr2' - enable v2 inline extended attributes\n" " 'version log2' - enable v2 log format\n" "\n" "The version function prints currently enabled features for a filesystem\n" "according to the version field of its primary superblock.\n" "It can also be used to enable selected features, such as support for\n" "unwritten extents. The updated version is written into all AGs.\n" "\n" msgstr "" #: .././db/sb.c:560 msgid "Superblock has mismatched features2 fields, skipping modification\n" msgstr "" #: .././db/sb.c:659 msgid "unwritten extents flag is already enabled\n" msgstr "" #: .././db/sb.c:679 msgid "version 2 log format is already in use\n" msgstr "" #: .././db/sb.c:706 #, c-format msgid "%s: invalid version change command \"%s\"\n" msgstr "" #: .././db/sb.c:715 #, c-format msgid "failed to set versionnum in AG %d\n" msgstr "" #: .././db/sb.c:733 #, c-format msgid "versionnum [0x%x+0x%x] = %s\n" msgstr "" #: .././db/bmap.c:39 msgid "[-ad] [block [len]]" msgstr "" #: .././db/bmap.c:40 msgid "show block map for current file" msgstr "" #: .././db/bmap.c:166 msgid "bad option for bmap command\n" msgstr "" #: .././db/bmap.c:183 #, c-format msgid "bad block number for bmap %s\n" msgstr "" #: .././db/bmap.c:191 #, c-format msgid "bad len for bmap %s\n" msgstr "" #: .././db/bmap.c:214 #, c-format msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" msgstr "" #: .././estimate/xfs_estimate.c:76 #, c-format msgid "" "Usage: %s [opts] directory [directory ...]\n" "\t-b blocksize (fundamental filesystem blocksize)\n" "\t-i logsize (internal log size)\n" "\t-e logsize (external log size)\n" "\t-v prints more verbose messages\n" "\t-h prints this usage message\n" "\n" "Note:\tblocksize may have 'k' appended to indicate x1024\n" "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" msgstr "" #: .././estimate/xfs_estimate.c:106 #, c-format msgid "blocksize %llu too small\n" msgstr "" #: .././estimate/xfs_estimate.c:111 #, c-format msgid "blocksize %llu too large\n" msgstr "" #: .././estimate/xfs_estimate.c:118 #, c-format msgid "already have external log noted, can't have both\n" msgstr "" #: .././estimate/xfs_estimate.c:127 #, c-format msgid "already have internal log noted, can't have both\n" msgstr "" #: .././estimate/xfs_estimate.c:157 #, c-format msgid "" "directory bsize blocks megabytes " "logsize\n" msgstr "" #: .././estimate/xfs_estimate.c:171 #, c-format msgid "dirsize=%llu\n" msgstr "" #: .././estimate/xfs_estimate.c:172 #, c-format msgid "fullblocks=%llu\n" msgstr "" #: .././estimate/xfs_estimate.c:173 #, c-format msgid "isize=%llu\n" msgstr "" #: .././estimate/xfs_estimate.c:175 #, c-format msgid "%llu regular files\n" msgstr "" #: .././estimate/xfs_estimate.c:176 #, c-format msgid "%llu symbolic links\n" msgstr "" #: .././estimate/xfs_estimate.c:177 #, c-format msgid "%llu directories\n" msgstr "" #: .././estimate/xfs_estimate.c:178 #, c-format msgid "%llu special files\n" msgstr "" #: .././estimate/xfs_estimate.c:191 #, c-format msgid "%s will take about %.1f megabytes\n" msgstr "" #: .././estimate/xfs_estimate.c:198 #, c-format msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" msgstr "" #: .././estimate/xfs_estimate.c:204 #, c-format msgid "\twith the external log using %llu blocks " msgstr "" #: .././estimate/xfs_estimate.c:206 #, c-format msgid "or about %.1f megabytes\n" msgstr "" #: .././fsr/xfs_fsr.c:196 #, c-format msgid "%s: cannot read %s\n" msgstr "" #: .././fsr/xfs_fsr.c:275 #, c-format msgid "%s: Stats not yet supported for XFS\n" msgstr "" #: .././fsr/xfs_fsr.c:339 #, c-format msgid "%s: could not stat: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:358 #, c-format msgid "%s: char special not supported: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:364 #, c-format msgid "%s: cannot defragment: %s: Not XFS\n" msgstr "" #: .././fsr/xfs_fsr.c:374 #, c-format msgid "%s: not fsys dev, dir, or reg file, ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:389 #, c-format msgid "" "Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m " "mtab]\n" " %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n" "\n" "Options:\n" " -n Do nothing, only interesting with -v. Not\n" " effective with in mtab mode.\n" " -s\t\tPrint statistics only.\n" " -g Print to syslog (default if stdout not a tty).\n" " -t time How long to run in seconds.\n" " -p passes\tNumber of passes before terminating global re-org.\n" " -f leftoff Use this instead of %s.\n" " -m mtab Use something other than /etc/mtab.\n" " -d Debug, print even more.\n" " -v\t\tVerbose, more -v's more verbose.\n" msgstr "" #: .././fsr/xfs_fsr.c:420 #, c-format msgid "could not open mtab file: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:426 .././fsr/xfs_fsr.c:458 #, c-format msgid "out of memory: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:449 #, c-format msgid "Skipping %s: not mounted rw\n" msgstr "" #: .././fsr/xfs_fsr.c:463 #, c-format msgid "out of memory on realloc: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:474 #, c-format msgid "strdup(%s) failed\n" msgstr "" #: .././fsr/xfs_fsr.c:484 #, c-format msgid "no rw xfs file systems in mtab: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:488 #, c-format msgid "Found %d mounted, writable, XFS filesystems\n" msgstr "" #: .././fsr/xfs_fsr.c:518 #, c-format msgid "%s: open failed\n" msgstr "" #: .././fsr/xfs_fsr.c:533 #, c-format msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" msgstr "" #: .././fsr/xfs_fsr.c:553 #, c-format msgid "could not read %s, starting with %s\n" msgstr "" #: .././fsr/xfs_fsr.c:590 #, c-format msgid "START: pass=%d ino=%llu %s %s\n" msgstr "" #: .././fsr/xfs_fsr.c:607 #, c-format msgid "Completed all %d passes\n" msgstr "" #: .././fsr/xfs_fsr.c:617 msgid "couldn't fork sub process:" msgstr "" #: .././fsr/xfs_fsr.c:654 #, c-format msgid "open(%s) failed: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:661 #, c-format msgid "write(%s) failed: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:668 #, c-format msgid "%s startpass %d, endpass %d, time %d seconds\n" msgstr "" #: .././fsr/xfs_fsr.c:690 #, c-format msgid "%s start inode=%llu\n" msgstr "" #: .././fsr/xfs_fsr.c:695 #, c-format msgid "unable to get handle: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:701 #, c-format msgid "unable to open: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:707 #, c-format msgid "Skipping %s: could not get XFS geometry\n" msgstr "" #: .././fsr/xfs_fsr.c:739 #, c-format msgid "could not open: inode %llu\n" msgstr "" #: .././fsr/xfs_fsr.c:769 #, c-format msgid "%s: xfs_bulkstat: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:795 #, c-format msgid "%s: Directory defragmentation not supported\n" msgstr "" #: .././fsr/xfs_fsr.c:814 #, c-format msgid "unable to construct sys handle for %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:825 #, c-format msgid "unable to open sys handle for %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:831 #, c-format msgid "unable to get bstat on %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:839 #, c-format msgid "unable to open handle %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:847 #, c-format msgid "Unable to get geom on fs for: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:896 #, c-format msgid "sync failed: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:902 #, c-format msgid "%s: zero size, ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:921 #, c-format msgid "locking check failed: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:928 #, c-format msgid "mandatory lock: %s: ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:941 #, c-format msgid "unable to get fs stat on %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:948 #, c-format msgid "insufficient freespace for: %s: size=%lld: ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:955 #, c-format msgid "failed to get inode attrs: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:960 #, c-format msgid "%s: immutable/append, ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:965 #, c-format msgid "%s: marked as don't defrag, ignoring\n" msgstr "" #: .././fsr/xfs_fsr.c:971 #, c-format msgid "cannot get realtime geometry for: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:976 #, c-format msgid "low on realtime free space: %s: ignoring file\n" msgstr "" #: .././fsr/xfs_fsr.c:983 #, c-format msgid "cannot open: %s: Permission denied\n" msgstr "" #: .././fsr/xfs_fsr.c:1040 .././fsr/xfs_fsr.c:1085 .././fsr/xfs_fsr.c:1131 msgid "could not set ATTR\n" msgstr "" #: .././fsr/xfs_fsr.c:1049 #, c-format msgid "unable to stat temp file: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1068 #, c-format msgid "unable to get bstat on temp file: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1073 #, c-format msgid "orig forkoff %d, temp forkoff %d\n" msgstr "" #: .././fsr/xfs_fsr.c:1105 #, c-format msgid "forkoff diff %d too large!\n" msgstr "" #: .././fsr/xfs_fsr.c:1139 msgid "set temp attr\n" msgstr "" #: .././fsr/xfs_fsr.c:1178 #, c-format msgid "%s already fully defragmented.\n" msgstr "" #: .././fsr/xfs_fsr.c:1183 #, c-format msgid "%s extents=%d can_save=%d tmp=%s\n" msgstr "" #: .././fsr/xfs_fsr.c:1189 #, c-format msgid "could not open tmp file: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1197 #, c-format msgid "failed to set ATTR fork on tmp: %s:\n" msgstr "" #: .././fsr/xfs_fsr.c:1205 #, c-format msgid "could not set inode attrs on tmp: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1213 #, c-format msgid "could not get DirectIO info on tmp: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1229 #, c-format msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" msgstr "" #: .././fsr/xfs_fsr.c:1236 #, c-format msgid "could not allocate buf: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1247 #, c-format msgid "could not open fragfile: %s : %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1264 #, c-format msgid "could not trunc tmp %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1279 #, c-format msgid "could not pre-allocate tmp space: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1290 msgid "Couldn't rewind on temporary file\n" msgstr "" #: .././fsr/xfs_fsr.c:1299 #, c-format msgid "Temporary file has %d extents (%d in original)\n" msgstr "" #: .././fsr/xfs_fsr.c:1302 #, c-format msgid "No improvement will be made (skipping): %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1346 #, c-format msgid "bad read of %d bytes from %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1350 .././fsr/xfs_fsr.c:1384 #, c-format msgid "bad write of %d bytes to %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1367 #, c-format msgid "bad write2 of %d bytes to %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1372 #, c-format msgid "bad copy to %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1407 #, c-format msgid "failed to fchown tmpfile %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1418 #, c-format msgid "%s: file type not supported\n" msgstr "" #: .././fsr/xfs_fsr.c:1422 #, c-format msgid "%s: file modified defrag aborted\n" msgstr "" #: .././fsr/xfs_fsr.c:1427 #, c-format msgid "%s: file busy\n" msgstr "" #: .././fsr/xfs_fsr.c:1429 #, c-format msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1438 #, c-format msgid "extents before:%d after:%d %s %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1464 #, c-format msgid "tmp file name too long: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1513 #, c-format msgid "realloc failed: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1526 #, c-format msgid "malloc failed: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1556 #, c-format msgid "failed reading extents: inode %llu" msgstr "" #: .././fsr/xfs_fsr.c:1606 msgid "failed reading extents" msgstr "" #: .././fsr/xfs_fsr.c:1694 .././fsr/xfs_fsr.c:1708 #, c-format msgid "tmpdir already exists: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1697 #, c-format msgid "could not create tmpdir: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1710 #, c-format msgid "cannot create tmpdir: %s: %s\n" msgstr "" #: .././fsr/xfs_fsr.c:1748 .././fsr/xfs_fsr.c:1756 #, c-format msgid "could not remove tmpdir: %s: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:34 #, c-format msgid "" "Usage: %s [options] mountpoint\n" "\n" "Options:\n" "\t-d grow data/metadata section\n" "\t-l grow log section\n" "\t-r grow realtime section\n" "\t-n don't change anything, just show geometry\n" "\t-I allow inode numbers to exceed %d significant bits\n" "\t-i convert log from external to internal format\n" "\t-t alternate location for mount table (/etc/mtab)\n" "\t-x convert log from internal to external format\n" "\t-D size grow data/metadata section to size blks\n" "\t-L size grow/shrink log section to size blks\n" "\t-R size grow realtime section to size blks\n" "\t-e size set realtime extent size to size blks\n" "\t-m imaxpct set inode max percent to imaxpct\n" "\t-V print version information\n" msgstr "" #: .././growfs/xfs_growfs.c:68 #, c-format msgid "" "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" msgstr "" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:444 #: .././growfs/xfs_growfs.c:445 msgid "internal" msgstr "" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:86 #: .././growfs/xfs_growfs.c:444 .././growfs/xfs_growfs.c:445 msgid "external" msgstr "" #: .././growfs/xfs_growfs.c:199 #, c-format msgid "%s: %s is not a mounted XFS filesystem\n" msgstr "" #: .././growfs/xfs_growfs.c:216 #, c-format msgid "%s: specified file [\"%s\"] is not on an XFS filesystem\n" msgstr "" #: .././growfs/xfs_growfs.c:233 #, c-format msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:268 #, c-format msgid "%s: failed to access data device for %s\n" msgstr "" #: .././growfs/xfs_growfs.c:273 #, c-format msgid "%s: failed to access external log for %s\n" msgstr "" #: .././growfs/xfs_growfs.c:279 #, c-format msgid "%s: failed to access realtime device for %s\n" msgstr "" #: .././growfs/xfs_growfs.c:314 #, c-format msgid "data size %lld too large, maximum is %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:321 #, c-format msgid "data size %lld too small, old size is %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:329 #, c-format msgid "data size unchanged, skipping\n" msgstr "" #: .././growfs/xfs_growfs.c:332 #, c-format msgid "inode max pct unchanged, skipping\n" msgstr "" #: .././growfs/xfs_growfs.c:339 .././growfs/xfs_growfs.c:378 #: .././growfs/xfs_growfs.c:413 #, c-format msgid "%s: growfs operation in progress already\n" msgstr "" #: .././growfs/xfs_growfs.c:343 #, c-format msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:359 #, c-format msgid "realtime size %lld too large, maximum is %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:365 #, c-format msgid "realtime size %lld too small, old size is %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:371 #, c-format msgid "realtime size unchanged, skipping\n" msgstr "" #: .././growfs/xfs_growfs.c:382 #, c-format msgid "%s: realtime growth not implemented\n" msgstr "" #: .././growfs/xfs_growfs.c:386 #, c-format msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:407 #, c-format msgid "log size unchanged, skipping\n" msgstr "" #: .././growfs/xfs_growfs.c:417 #, c-format msgid "%s: log growth not supported yet\n" msgstr "" #: .././growfs/xfs_growfs.c:421 #, c-format msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:429 #, c-format msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" msgstr "" #: .././growfs/xfs_growfs.c:434 #, c-format msgid "data blocks changed from %lld to %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:437 #, c-format msgid "inode max percent changed from %d to %d\n" msgstr "" #: .././growfs/xfs_growfs.c:440 #, c-format msgid "log blocks changed from %d to %d\n" msgstr "" #: .././growfs/xfs_growfs.c:443 #, c-format msgid "log changed from %s to %s\n" msgstr "" #: .././growfs/xfs_growfs.c:447 #, c-format msgid "realtime blocks changed from %lld to %lld\n" msgstr "" #: .././growfs/xfs_growfs.c:450 #, c-format msgid "realtime extent size changed from %d to %d\n" msgstr "" #: .././io/open.c:53 msgid "socket" msgstr "" #: .././io/open.c:55 msgid "directory" msgstr "" #: .././io/open.c:57 msgid "char device" msgstr "" #: .././io/open.c:59 msgid "block device" msgstr "" #: .././io/open.c:61 msgid "regular file" msgstr "" #: .././io/open.c:63 msgid "symbolic link" msgstr "" #: .././io/open.c:65 msgid "fifo" msgstr "" #: .././io/open.c:80 .././io/open.c:718 #, c-format msgid "fd.path = \"%s\"\n" msgstr "" #: .././io/open.c:81 #, c-format msgid "fd.flags = %s,%s,%s%s%s%s\n" msgstr "" #: .././io/open.c:82 .././io/file.c:42 msgid "sync" msgstr "" #: .././io/open.c:82 .././io/file.c:42 msgid "non-sync" msgstr "" #: .././io/open.c:83 .././io/file.c:43 msgid "direct" msgstr "" #: .././io/open.c:83 .././io/file.c:43 msgid "non-direct" msgstr "" #: .././io/open.c:84 .././io/file.c:44 msgid "read-only" msgstr "" #: .././io/open.c:84 .././io/file.c:44 msgid "read-write" msgstr "" #: .././io/open.c:85 .././io/file.c:45 msgid ",real-time" msgstr "" #: .././io/open.c:86 .././io/file.c:46 msgid ",append-only" msgstr "" #: .././io/open.c:87 .././io/file.c:47 msgid ",non-block" msgstr "" #: .././io/open.c:91 #, c-format msgid "stat.ino = %lld\n" msgstr "" #: .././io/open.c:92 #, c-format msgid "stat.type = %s\n" msgstr "" #: .././io/open.c:93 #, c-format msgid "stat.size = %lld\n" msgstr "" #: .././io/open.c:94 #, c-format msgid "stat.blocks = %lld\n" msgstr "" #: .././io/open.c:96 #, c-format msgid "stat.atime = %s" msgstr "" #: .././io/open.c:97 #, c-format msgid "stat.mtime = %s" msgstr "" #: .././io/open.c:98 #, c-format msgid "stat.ctime = %s" msgstr "" #: .././io/open.c:107 #, c-format msgid "fsxattr.xflags = 0x%x " msgstr "" #: .././io/open.c:109 #, c-format msgid "fsxattr.projid = %u\n" msgstr "" #: .././io/open.c:110 #, c-format msgid "fsxattr.extsize = %u\n" msgstr "" #: .././io/open.c:111 #, c-format msgid "fsxattr.nextents = %u\n" msgstr "" #: .././io/open.c:112 #, c-format msgid "fsxattr.naextents = %u\n" msgstr "" #: .././io/open.c:117 #, c-format msgid "dioattr.mem = 0x%x\n" msgstr "" #: .././io/open.c:118 #, c-format msgid "dioattr.miniosz = %u\n" msgstr "" #: .././io/open.c:119 #, c-format msgid "dioattr.maxiosz = %u\n" msgstr "" #: .././io/open.c:235 #, c-format msgid "" "\n" " opens a new file in the requested mode\n" "\n" " Example:\n" " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" "\n" " Opens a file for subsequent use by all of the other xfs_io commands.\n" " With no arguments, open uses the stat command to show the current file.\n" " -a -- open with the O_APPEND flag (append-only mode)\n" " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" " -f -- open with O_CREAT (create the file if it doesn't exist)\n" " -m -- permissions to use in case a new file is created (default 0600)\n" " -n -- open with O_NONBLOCK\n" " -r -- open with O_RDONLY, the default is O_RDWR\n" " -s -- open with O_SYNC\n" " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" " -R -- mark the file as a realtime XFS file immediately after opening it\n" " Note1: usually read/write direct IO requests must be blocksize aligned;\n" " some kernels, however, allow sectorsize alignment for direct IO.\n" " Note2: the bmap for non-regular files can be obtained provided the file\n" " was opened correctly (in particular, must be opened read-only).\n" "\n" msgstr "" #: .././io/open.c:272 .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 #: .././io/init.c:102 #, c-format msgid "no files are open, try 'help open'\n" msgstr "" #: .././io/open.c:294 .././io/init.c:157 #, c-format msgid "non-numeric mode -- %s\n" msgstr "" #: .././io/open.c:373 #, c-format msgid "" "\n" " displays the project identifier associated with the current path\n" "\n" " Options:\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, but only list projects on directories\n" "\n" msgstr "" #: .././io/open.c:396 .././io/open.c:468 .././io/open.c:592 .././io/open.c:614 #: .././io/attr.c:171 .././io/attr.c:247 .././libxfs/init.c:110 #: .././mkfs/proto.c:284 .././quota/project.c:118 .././quota/project.c:163 #: .././quota/project.c:210 #, c-format msgid "%s: cannot open %s: %s\n" msgstr "" #: .././io/open.c:439 #, c-format msgid "projid = %u\n" msgstr "" #: .././io/open.c:447 #, c-format msgid "" "\n" " modifies the project identifier associated with the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying projects on directories\n" "\n" msgstr "" #: .././io/open.c:506 #, c-format msgid "invalid project ID -- %s\n" msgstr "" #: .././io/open.c:522 #, c-format msgid "" "\n" " report or modify preferred extent size (in bytes) for the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying extsize on directories\n" "\n" msgstr "" #: .././io/open.c:565 #, c-format msgid "invalid target file type - file %s\n" msgstr "" #: .././io/open.c:651 #, c-format msgid "non-numeric extsize argument -- %s\n" msgstr "" #: .././io/open.c:698 #, c-format msgid "invalid setfl argument -- '%c'\n" msgstr "" #: .././io/open.c:722 #, c-format msgid "statfs.f_bsize = %lld\n" msgstr "" #: .././io/open.c:723 #, c-format msgid "statfs.f_blocks = %lld\n" msgstr "" #: .././io/open.c:725 #, c-format msgid "statfs.f_frsize = %lld\n" msgstr "" #: .././io/open.c:727 #, c-format msgid "statfs.f_bavail = %lld\n" msgstr "" #: .././io/open.c:729 #, c-format msgid "statfs.f_files = %lld\n" msgstr "" #: .././io/open.c:730 #, c-format msgid "statfs.f_ffree = %lld\n" msgstr "" #: .././io/open.c:737 #, c-format msgid "geom.bsize = %u\n" msgstr "" #: .././io/open.c:738 #, c-format msgid "geom.agcount = %u\n" msgstr "" #: .././io/open.c:739 #, c-format msgid "geom.agblocks = %u\n" msgstr "" #: .././io/open.c:740 #, c-format msgid "geom.datablocks = %llu\n" msgstr "" #: .././io/open.c:742 #, c-format msgid "geom.rtblocks = %llu\n" msgstr "" #: .././io/open.c:744 #, c-format msgid "geom.rtextents = %llu\n" msgstr "" #: .././io/open.c:746 #, c-format msgid "geom.rtextsize = %u\n" msgstr "" #: .././io/open.c:747 #, c-format msgid "geom.sunit = %u\n" msgstr "" #: .././io/open.c:748 #, c-format msgid "geom.swidth = %u\n" msgstr "" #: .././io/open.c:753 #, c-format msgid "counts.freedata = %llu\n" msgstr "" #: .././io/open.c:755 #, c-format msgid "counts.freertx = %llu\n" msgstr "" #: .././io/open.c:757 #, c-format msgid "counts.freeino = %llu\n" msgstr "" #: .././io/open.c:759 #, c-format msgid "counts.allocino = %llu\n" msgstr "" #: .././io/open.c:774 msgid "[-acdrstx] [path]" msgstr "" #: .././io/open.c:775 msgid "open the file specified by path" msgstr "" #: .././io/open.c:783 msgid "[-v]" msgstr "" #: .././io/open.c:784 msgid "statistics on the currently open file" msgstr "" #: .././io/open.c:792 msgid "close the current open file" msgstr "" #: .././io/open.c:796 msgid "[-adx]" msgstr "" #: .././io/open.c:799 msgid "set/clear append/direct flags on the open file" msgstr "" #: .././io/open.c:805 msgid "statistics on the filesystem of the currently open file" msgstr "" #: .././io/open.c:809 msgid "[-D | -R] projid" msgstr "" #: .././io/open.c:814 msgid "change project identifier on the currently open file" msgstr "" #: .././io/open.c:819 msgid "[-D | -R]" msgstr "" #: .././io/open.c:824 msgid "list project identifier set on the currently open file" msgstr "" #: .././io/open.c:829 msgid "[-D | -R] [extsize]" msgstr "" #: .././io/open.c:834 msgid "get/set preferred extent size (in bytes) for the open file" msgstr "" #: .././io/pread.c:33 #, c-format msgid "" "\n" " reads a range of bytes in a specified block size from the given offset\n" "\n" " Example:\n" " 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" "\n" " Reads a segment of the currently open file, optionally dumping it to the\n" " standard output stream (with -v option) for subsequent inspection.\n" " The reads are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different pattern is requested.\n" " -B -- read backwards through the range from offset (backwards N bytes)\n" " -F -- read forwards through the range of bytes from offset (default)\n" " -v -- be verbose, dump out buffers (used when reading forwards)\n" " -R -- read at random offsets in the range of bytes\n" " -Z N -- zeed the random number generator (used when reading randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" " -V N -- use vectored IO with N iovecs of blocksize each (preadv)\n" "\n" " When in \"random\" mode, the number of read operations will equal the\n" " number required to do a complete forward/backward scan of the range.\n" " Note that the offset within the range is chosen at random each time\n" " (an offset may be read more than once when operating in this mode).\n" "\n" msgstr "" #: .././io/pread.c:398 .././io/pwrite.c:269 #, c-format msgid "non-numeric bsize -- %s\n" msgstr "" #: .././io/pread.c:428 .././io/pwrite.c:316 #, c-format msgid "non-numeric vector count == %s\n" msgstr "" #: .././io/pread.c:437 .././io/pwrite.c:303 .././io/pwrite.c:330 #: .././io/mmap.c:530 #, c-format msgid "non-numeric seed -- %s\n" msgstr "" #: .././io/pread.c:452 .././io/pread.c:460 .././io/pwrite.c:350 #: .././io/fadvise.c:99 .././io/madvise.c:94 .././io/mincore.c:54 #: .././io/mmap.c:212 .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 #: .././io/prealloc.c:60 .././io/sendfile.c:133 .././io/sync_file_range.c:82 #, c-format msgid "non-numeric length argument -- %s\n" msgstr "" #: .././io/pread.c:497 #, c-format msgid "read %lld/%lld bytes at offset %lld\n" msgstr "" #: .././io/pread.c:499 .././io/pwrite.c:396 .././io/sendfile.c:163 #, c-format msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" msgstr "" #: .././io/pread.c:518 msgid "[-b bs] [-v] [-i N] [-FBR [-Z N]] off len" msgstr "" #: .././io/pread.c:519 msgid "reads a number of bytes at a specified offset" msgstr "" #: .././io/pwrite.c:32 #, c-format msgid "" "\n" " writes a range of bytes (in block size increments) from the given offset\n" "\n" " Example:\n" " 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Writes into a segment of the currently open file, using either a buffer\n" " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" " The writes are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different write pattern is requested.\n" " -S -- use an alternate seed number for filling the write buffer\n" " -i -- input file, source of data to write (used when writing forward)\n" " -d -- open the input file for direct IO\n" " -s -- skip a number of bytes at the start of the input file\n" " -w -- call fdatasync(2) at the end (included in timing results)\n" " -W -- call fsync(2) at the end (included in timing results)\n" " -B -- write backwards through the range from offset (backwards N bytes)\n" " -F -- write forwards through the range of bytes from offset (default)\n" " -R -- write at random offsets in the specified range of bytes\n" " -Z N -- zeed the random number generator (used when writing randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" " -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n" "\n" msgstr "" #: .././io/pwrite.c:296 #, c-format msgid "non-numeric skip -- %s\n" msgstr "" #: .././io/pwrite.c:344 .././io/fadvise.c:92 .././io/madvise.c:87 #: .././io/mincore.c:48 .././io/mmap.c:206 .././io/mmap.c:301 #: .././io/mmap.c:387 .././io/mmap.c:546 .././io/prealloc.c:55 #: .././io/sendfile.c:126 .././io/sync_file_range.c:75 #, c-format msgid "non-numeric offset argument -- %s\n" msgstr "" #: .././io/pwrite.c:394 #, c-format msgid "wrote %lld/%lld bytes at offset %lld\n" msgstr "" #: .././io/pwrite.c:419 msgid "" "[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off " "len" msgstr "" #: .././io/pwrite.c:421 msgid "writes a number of bytes at a specified offset" msgstr "" #: .././io/attr.c:59 #, c-format msgid "" "\n" " displays the set of extended inode flags associated with the current file\n" "\n" " Each individual flag is displayed as a single character, in this order:\n" " r -- file data is stored in the realtime section\n" " p -- file has preallocated extents (cannot be changed using chattr)\n" " i -- immutable, file cannot be modified\n" " a -- append-only, file can only be appended to\n" " s -- all updates are synchronous\n" " A -- the access time is not updated for this inode\n" " d -- do not include this file in a dump of the filesystem\n" " t -- child created in this directory has realtime bit set by default\n" " P -- child created in this directory has parents project ID by default\n" " n -- symbolic links cannot be created in this directory\n" " e -- for non-realtime files, observe the inode extent size value\n" " E -- children created in this directory inherit the extent size value\n" " f -- do not include this file when defragmenting the filesystem\n" " S -- enable filestreams allocator for this directory\n" "\n" " Options:\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, but only list attributes on directories\n" " -a -- show all flags which can be set alongside those which are set\n" " -v -- verbose mode; show long names of flags, not single characters\n" "\n" msgstr "" #: .././io/attr.c:90 #, c-format msgid "" "\n" " modifies the set of extended inode flags associated with the current file\n" "\n" " Examples:\n" " 'chattr +a' - sets the append-only flag\n" " 'chattr -a' - clears the append-only flag\n" "\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, only modifying attributes on directories\n" " +/-r -- set/clear the realtime flag\n" " +/-i -- set/clear the immutable flag\n" " +/-a -- set/clear the append-only flag\n" " +/-s -- set/clear the sync flag\n" " +/-A -- set/clear the no-atime flag\n" " +/-d -- set/clear the no-dump flag\n" " +/-t -- set/clear the realtime inheritance flag\n" " +/-P -- set/clear the project ID inheritance flag\n" " +/-n -- set/clear the no-symbolic-links flag\n" " +/-e -- set/clear the extent-size flag\n" " +/-E -- set/clear the extent-size inheritance flag\n" " +/-f -- set/clear the no-defrag flag\n" " +/-S -- set/clear the filestreams allocator flag\n" " Note1: user must have certain capabilities to modify immutable/append-" "only.\n" " Note2: immutable/append-only files cannot be deleted; removing these files\n" " requires the immutable/append-only flag to be cleared first.\n" " Note3: the realtime flag can only be set if the filesystem has a realtime\n" " section, and the (regular) file must be empty when the flag is set.\n" "\n" msgstr "" #: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 #: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 #, c-format msgid "%s: cannot get flags on %s: %s\n" msgstr "" #: .././io/attr.c:256 .././io/attr.c:327 #, c-format msgid "%s: cannot set flags on %s: %s\n" msgstr "" #: .././io/attr.c:291 .././io/attr.c:305 #, c-format msgid "%s: unknown flag\n" msgstr "" #: .././io/attr.c:311 #, c-format msgid "%s: bad chattr command, not +/-X\n" msgstr "" #: .././io/attr.c:338 msgid "[-R|-D] [+/-" msgstr "" #: .././io/attr.c:343 msgid "change extended inode flags on the currently open file" msgstr "" #: .././io/attr.c:348 msgid "[-R|-D|-a|-v]" msgstr "" #: .././io/attr.c:353 msgid "list extended inode flags set on the currently open file" msgstr "" #: .././io/bmap.c:30 #, c-format msgid "" "\n" " prints the block mapping for an XFS file's data or attribute forks\n" " Example:\n" " 'bmap -vp' - tabular format verbose map, including unwritten extents\n" "\n" " bmap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -p -- obtain all unwritten extents as well (w/ -v show which are " "unwritten.)\n" " -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" " Note: the bmap for non-regular files can be obtained provided the file\n" " was opened appropriately (in particular, must be opened read-only).\n" "\n" msgstr "" #: .././io/bmap.c:123 #, c-format msgid "%s: can't get geometry [\"%s\"]: %s\n" msgstr "" #: .././io/bmap.c:131 #, c-format msgid "%s: cannot read attrs on \"%s\": %s\n" msgstr "" #: .././io/bmap.c:149 .././io/fiemap.c:210 #, c-format msgid "%s: malloc of %d bytes failed.\n" msgstr "" #: .././io/bmap.c:197 #, c-format msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" msgstr "" #: .././io/bmap.c:228 #, c-format msgid "%s: cannot realloc %d bytes\n" msgstr "" #: .././io/bmap.c:237 #, c-format msgid "%s: no extents\n" msgstr "" #: .././io/bmap.c:251 .././io/bmap.c:379 .././io/fiemap.c:97 #: .././io/fiemap.c:317 .././io/fiemap.c:321 #, c-format msgid "hole" msgstr "" #: .././io/bmap.c:260 #, c-format msgid " %lld blocks\n" msgstr "" #: .././io/bmap.c:339 .././io/fiemap.c:243 msgid "EXT" msgstr "" #: .././io/bmap.c:340 .././io/fiemap.c:244 msgid "FILE-OFFSET" msgstr "" #: .././io/bmap.c:341 msgid "RT-BLOCK-RANGE" msgstr "" #: .././io/bmap.c:341 .././io/fiemap.c:245 msgid "BLOCK-RANGE" msgstr "" #: .././io/bmap.c:342 msgid "AG" msgstr "" #: .././io/bmap.c:343 msgid "AG-OFFSET" msgstr "" #: .././io/bmap.c:344 .././io/fiemap.c:246 msgid "TOTAL" msgstr "" #: .././io/bmap.c:345 msgid " FLAGS" msgstr "" #: .././io/bmap.c:413 #, c-format msgid " FLAG Values:\n" msgstr "" #: .././io/bmap.c:414 #, c-format msgid " %*.*o Unwritten preallocated extent\n" msgstr "" #: .././io/bmap.c:416 #, c-format msgid " %*.*o Doesn't begin on stripe unit\n" msgstr "" #: .././io/bmap.c:418 #, c-format msgid " %*.*o Doesn't end on stripe unit\n" msgstr "" #: .././io/bmap.c:420 #, c-format msgid " %*.*o Doesn't begin on stripe width\n" msgstr "" #: .././io/bmap.c:422 #, c-format msgid " %*.*o Doesn't end on stripe width\n" msgstr "" #: .././io/bmap.c:438 msgid "[-adlpv] [-n nx]" msgstr "" #: .././io/bmap.c:439 msgid "print block mapping for an XFS file" msgstr "" #: .././io/fadvise.c:31 #, c-format msgid "" "\n" " advise the page cache about expected I/O patterns on the current file\n" "\n" " Modifies kernel page cache behaviour when operating on the current file.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" " -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" " -r -- expect random page references (POSIX_FADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" " Notes: these interfaces are not supported in Linux kernels before 2.6.\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" "\n" msgstr "" #: .././io/fadvise.c:122 msgid "[-dnrsw] [off len]" msgstr "" #: .././io/fadvise.c:123 msgid "advisory commands for sections of a file" msgstr "" #: .././io/file.c:39 #, c-format msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" msgstr "" #: .././io/file.c:41 msgid "foreign" msgstr "" #: .././io/file.c:41 msgid "xfs" msgstr "" #: .././io/file.c:81 .././io/sendfile.c:103 .././quota/path.c:112 #, c-format msgid "value %d is out of range (0-%d)\n" msgstr "" #: .././io/file.c:94 .././quota/path.c:126 msgid "[N]" msgstr "" #: .././io/file.c:99 msgid "set the current file" msgstr "" #: .././io/file.c:108 msgid "list current open files and memory mappings" msgstr "" #: .././io/freeze.c:37 #, c-format msgid "%s: cannot freeze filesystem at %s: %s\n" msgstr "" #: .././io/freeze.c:54 #, c-format msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" msgstr "" #: .././io/freeze.c:70 msgid "freeze filesystem of current file" msgstr "" #: .././io/freeze.c:77 msgid "unfreeze filesystem of current file" msgstr "" #: .././io/fsync.c:59 msgid "calls fsync(2) to flush all in-core file state to disk" msgstr "" #: .././io/fsync.c:66 msgid "calls fdatasync(2) to flush the files in-core data to disk" msgstr "" #: .././io/getrusage.c:118 msgid "report process resource usage" msgstr "" #: .././io/imap.c:53 #, c-format msgid "ino %10llu count %2d mask %016llx\n" msgstr "" #: .././io/imap.c:71 msgid "[nentries]" msgstr "" #: .././io/imap.c:73 msgid "inode map for filesystem of current file" msgstr "" #: .././io/inject.c:109 #, c-format msgid "" "\n" " inject errors into the filesystem of the currently open file\n" "\n" " Example:\n" " 'inject readagf' - cause errors on allocation group freespace reads\n" "\n" " Causes the kernel to generate and react to errors within XFS, provided\n" " the XFS kernel code has been built with debugging features enabled.\n" " With no arguments, displays the list of error injection tags.\n" "\n" msgstr "" #: .././io/inject.c:135 #, c-format msgid "no such tag -- %s\n" msgstr "" #: .././io/inject.c:156 msgid "[tag ...]" msgstr "" #: .././io/inject.c:157 msgid "inject errors into a filesystem" msgstr "" #: .././io/madvise.c:32 #, c-format msgid "" "\n" " advise the page cache about access patterns expected for a mapping\n" "\n" " Modifies page cache behavior when operating on the current mapping.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" " -r -- expect random page references (POSIX_MADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" " Notes:\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED forces the maximum readahead.\n" "\n" msgstr "" #: .././io/madvise.c:98 .././io/mincore.c:58 #, c-format msgid "length argument too large -- %lld\n" msgstr "" #: .././io/madvise.c:127 msgid "[-drsw] [off len]" msgstr "" #: .././io/madvise.c:128 msgid "give advice about use of memory" msgstr "" #: .././io/mincore.c:92 .././io/mincore.c:102 #, c-format msgid "0x%lx %lu pages (%llu : %lu)\n" msgstr "" #: .././io/mincore.c:122 msgid "[off len]" msgstr "" #: .././io/mincore.c:123 msgid "find mapping pages that are memory resident" msgstr "" #: .././io/mmap.c:76 #, c-format msgid "offset (%lld) is before start of mapping (%lld)\n" msgstr "" #: .././io/mmap.c:82 #, c-format msgid "offset (%lld) is beyond end of mapping (%lld)\n" msgstr "" #: .././io/mmap.c:87 #, c-format msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" msgstr "" #: .././io/mmap.c:93 #, c-format msgid "offset address (%p) is not page aligned\n" msgstr "" #: .././io/mmap.c:133 #, c-format msgid "" "\n" " maps a range within the current file into memory\n" "\n" " Example:\n" " 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" "\n" " Memory maps a range of a file for subsequent use by other xfs_io commands.\n" " With no arguments, mmap shows the current mappings. The current mapping\n" " can be set by using the single argument form (mapping number or address).\n" " If two arguments are specified (a range), a new mapping is created and the\n" " following options are available:\n" " -r -- map with PROT_READ protection\n" " -w -- map with PROT_WRITE protection\n" " -x -- map with PROT_EXEC protection\n" " If no protection mode is specified, all are used by default.\n" "\n" msgstr "" #: .././io/mmap.c:167 .././io/mmap.c:174 .././io/init.c:106 #, c-format msgid "no mapped regions, try 'help mmap'\n" msgstr "" #: .././io/mmap.c:254 #, c-format msgid "" "\n" " flushes a range of bytes in the current memory mapping\n" "\n" " Writes all modified copies of pages over the specified range (or entire\n" " mapping if no range specified) to their backing storage locations. Also,\n" " optionally invalidates so that subsequent references to the pages will be\n" " obtained from their backing storage locations (instead of cached copies).\n" " -a -- perform asynchronous writes (MS_ASYNC)\n" " -i -- invalidate mapped pages (MS_INVALIDATE)\n" " -s -- perform synchronous writes (MS_SYNC)\n" "\n" msgstr "" #: .././io/mmap.c:330 #, c-format msgid "" "\n" " reads a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" "\n" " Accesses a range of the current memory mapping, optionally dumping it to\n" " the standard output stream (with -v option) for subsequent inspection.\n" " -f -- verbose mode, dump bytes with offsets relative to start of file.\n" " -r -- reverse order; start accessing from the end of range, moving " "backward\n" " -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" " The accesses are performed sequentially from the start offset by default.\n" " Notes:\n" " References to whole pages following the end of the backing file results\n" " in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" " on various filesystem conditions, including quota exceeded errors, and\n" " for physical device errors (such as unreadable disk blocks). No attempt\n" " has been made to catch signals at this stage...\n" "\n" msgstr "" #: .././io/mmap.c:494 #, c-format msgid "" "\n" " dirties a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" "\n" " Stores a byte into memory for a range within a mapping.\n" " The default stored value is 'X', repeated to fill the range specified.\n" " -S -- use an alternate seed character\n" " -r -- reverse order; start storing from the end of range, moving backward\n" " The stores are performed sequentially from the start offset by default.\n" "\n" msgstr "" #: .././io/mmap.c:586 msgid "[N] | [-rwx] [off len]" msgstr "" #: .././io/mmap.c:588 msgid "mmap a range in the current file, show mappings" msgstr "" #: .././io/mmap.c:597 msgid "[-r] [off len]" msgstr "" #: .././io/mmap.c:599 msgid "reads data from a region in the current memory mapping" msgstr "" #: .././io/mmap.c:608 msgid "[-ais] [off len]" msgstr "" #: .././io/mmap.c:609 msgid "flush a region in the current memory mapping" msgstr "" #: .././io/mmap.c:618 msgid "unmaps the current memory mapping" msgstr "" #: .././io/mmap.c:626 msgid "[-r] [-S seed] [off len]" msgstr "" #: .././io/mmap.c:628 msgid "writes data into a region in the current memory mapping" msgstr "" #: .././io/prealloc.c:216 .././io/prealloc.c:224 .././io/prealloc.c:232 #: .././io/prealloc.c:240 .././io/prealloc.c:250 .././io/prealloc.c:276 msgid "off len" msgstr "" #: .././io/prealloc.c:217 msgid "allocates zeroed space for part of a file" msgstr "" #: .././io/prealloc.c:225 msgid "frees space associated with part of a file" msgstr "" #: .././io/prealloc.c:234 msgid "reserves space associated with part of a file" msgstr "" #: .././io/prealloc.c:243 msgid "frees reserved space associated with part of a file" msgstr "" #: .././io/prealloc.c:252 msgid "Converts the given range of a file to allocated zeros" msgstr "" #: .././io/prealloc.c:266 msgid "[-k] [-p] off len" msgstr "" #: .././io/prealloc.c:268 msgid "allocates space associated with part of a file via fallocate" msgstr "" #: .././io/prealloc.c:278 msgid "de-allocates space assocated with part of a file via fallocate" msgstr "" #: .././io/resblks.c:39 #, c-format msgid "non-numeric argument -- %s\n" msgstr "" #: .././io/resblks.c:51 #, c-format msgid "reserved blocks = %llu\n" msgstr "" #: .././io/resblks.c:53 #, c-format msgid "available reserved blocks = %llu\n" msgstr "" #: .././io/resblks.c:66 msgid "[blocks]" msgstr "" #: .././io/resblks.c:68 msgid "get and/or set count of reserved filesystem blocks" msgstr "" #: .././io/sendfile.c:32 #, c-format msgid "" "\n" " transfer a range of bytes from the given offset between files\n" "\n" " Example:\n" " 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Copies data between one file descriptor and another. Because this copying\n" " is done within the kernel, sendfile does not need to transfer data to and\n" " from user space.\n" " -f -- specifies an input file from which to source data to write\n" " -i -- specifies an input file name from which to source data to write.\n" " An offset and length in the source file can be optionally specified.\n" "\n" msgstr "" #: .././io/sendfile.c:161 #, c-format msgid "sent %lld/%lld bytes from offset %lld\n" msgstr "" #: .././io/sendfile.c:186 msgid "-i infile | -f N [off len]" msgstr "" #: .././io/sendfile.c:188 msgid "Transfer data directly between file descriptors" msgstr "" #: .././io/shutdown.c:59 msgid "[-f]" msgstr "" #: .././io/shutdown.c:61 msgid "shuts down the filesystem where the current file resides" msgstr "" #: .././io/truncate.c:38 #, c-format msgid "non-numeric truncate argument -- %s\n" msgstr "" #: .././io/truncate.c:58 msgid "off" msgstr "" #: .././io/truncate.c:60 msgid "truncates the current file at the given offset" msgstr "" #: .././io/parent.c:49 #, c-format msgid "%s%s" msgstr "" #: .././io/parent.c:54 #, c-format msgid "inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n" msgstr "" #: .././io/parent.c:58 #, c-format msgid "path \"%s\" does not stat for inode: %llu; err = %s\n" msgstr "" #: .././io/parent.c:67 #, c-format msgid "path \"%s\" found\n" msgstr "" #: .././io/parent.c:73 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong inode#\n" msgstr "" #: .././io/parent.c:77 .././io/parent.c:107 #, c-format msgid "ino mismatch for path \"%s\" %llu vs %llu\n" msgstr "" #: .././io/parent.c:85 #, c-format msgid "inode number match: %llu\n" msgstr "" #: .././io/parent.c:95 #, c-format msgid "parent path \"%s\" does not stat: %s\n" msgstr "" #: .././io/parent.c:103 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong parent inode#\n" msgstr "" #: .././io/parent.c:116 #, c-format msgid "parent ino match for %llu\n" msgstr "" #: .././io/parent.c:138 #, c-format msgid "parentpaths failed for ino %llu: %s\n" msgstr "" #: .././io/parent.c:149 #, c-format msgid "inode-path for inode: %llu is missing\n" msgstr "" #: .././io/parent.c:173 #, c-format msgid "can't stat mount point \"%s\": %s\n" msgstr "" #: .././io/parent.c:194 #, c-format msgid "failed to get bulkstat information for inode %llu\n" msgstr "" #: .././io/parent.c:200 #, c-format msgid "failed to get valid bulkstat information for inode %llu\n" msgstr "" #: .././io/parent.c:212 #, c-format msgid "checking inode %llu\n" msgstr "" #: .././io/parent.c:227 #, c-format msgid "syssgi bulkstat failed: %s\n" msgstr "" #: .././io/parent.c:249 #, c-format msgid "unable to open \"%s\" for jdm: %s\n" msgstr "" #: .././io/parent.c:259 #, c-format msgid "unable to allocate buffers: %s\n" msgstr "" #: .././io/parent.c:268 #, c-format msgid "num errors: %d\n" msgstr "" #: .././io/parent.c:270 #, c-format msgid "succeeded checking %llu inodes\n" msgstr "" #: .././io/parent.c:281 #, c-format msgid "p_ino = %llu\n" msgstr "" #: .././io/parent.c:282 #, c-format msgid "p_gen = %u\n" msgstr "" #: .././io/parent.c:283 #, c-format msgid "p_reclen = %u\n" msgstr "" #: .././io/parent.c:285 #, c-format msgid "p_name = \"%s%s\"\n" msgstr "" #: .././io/parent.c:287 #, c-format msgid "p_name = \"%s\"\n" msgstr "" #: .././io/parent.c:309 #, c-format msgid "%s: failed path_to_fshandle \"%s\": %s\n" msgstr "" #: .././io/parent.c:316 #, c-format msgid "%s: path_to_handle failed for \"%s\"\n" msgstr "" #: .././io/parent.c:323 #, c-format msgid "%s: unable to allocate parent buffer: %s\n" msgstr "" #: .././io/parent.c:344 #, c-format msgid "%s: %s call failed for \"%s\": %s\n" msgstr "" #: .././io/parent.c:353 #, c-format msgid "%s: inode-path is missing\n" msgstr "" #: .././io/parent.c:384 #, c-format msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" msgstr "" #: .././io/parent.c:424 #, c-format msgid "" "\n" " list the current file's parents and their filenames\n" "\n" " -c -- check the current file's file system for parent consistency\n" " -p -- list the current file's parents and their full paths\n" " -v -- verbose mode\n" "\n" msgstr "" #: .././io/parent.c:440 msgid "[-cpv]" msgstr "" #: .././io/parent.c:442 msgid "print or check parent inodes" msgstr "" #: .././io/fiemap.c:32 #, c-format msgid "" "\n" " prints the block mapping for a file's data or attribute forks\n" " Example:\n" " 'fiemap -v' - tabular format verbose map\n" "\n" " fiemap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -v -- Verbose information\n" "\n" msgstr "" #: .././io/fiemap.c:139 .././io/fiemap.c:153 .././io/fiemap.c:323 #, c-format msgid " %llu blocks\n" msgstr "" #: .././io/fiemap.c:247 msgid "FLAGS" msgstr "" #: .././io/fiemap.c:343 msgid "[-alv] [-n nx]" msgstr "" #: .././io/fiemap.c:344 msgid "print block mapping for a file" msgstr "" #: .././io/init.c:35 #, c-format msgid "Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n" msgstr "" #: .././io/init.c:112 #, c-format msgid "foreign file active, %s command is for XFS filesystems only\n" msgstr "" #: .././io/sync_file_range.c:31 #, c-format msgid "" "\n" " Trigger specific writeback commands on a range of the current file\n" "\n" " With no options, the SYNC_FILE_RANGE_WRITE is implied.\n" " -a -- wait for IO to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER).\n" " -b -- wait for IO to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE).\n" " -w -- write dirty data in range (SYNC_FILE_RANGE_WRITE).\n" "\n" msgstr "" #: .././io/sync_file_range.c:102 msgid "[-abw] off len" msgstr "" #: .././io/sync_file_range.c:103 msgid "Control writeback on a range of a file" msgstr "" #: .././libdisk/drivers.c:35 #, c-format msgid "Cannot stat %s: %s\n" msgstr "" #: .././libdisk/lvm.c:60 #, c-format msgid "Warning - LVM device, but no lvdisplay(8) found\n" msgstr "" #: .././libdisk/lvm.c:70 .././libdisk/dm.c:73 #, c-format msgid "Could not open pipe\n" msgstr "" #: .././libdisk/lvm.c:85 .././libdisk/dm.c:88 #, c-format msgid "Failed to execute %s\n" msgstr "" #: .././libdisk/lvm.c:89 #, c-format msgid "Failed forking lvdisplay process\n" msgstr "" #: .././libdisk/md.c:61 #, c-format msgid "Error getting MD array device from %s\n" msgstr "" #: .././libdisk/md.c:68 #, c-format msgid "Couldn't malloc device string\n" msgstr "" #: .././libdisk/md.c:84 #, c-format msgid "Error getting MD array info from %s\n" msgstr "" #: .././libdisk/dm.c:57 #, c-format msgid "Warning - device mapper device, but no dmsetup(8) found\n" msgstr "" #: .././libdisk/dm.c:92 #, c-format msgid "Failed forking dmsetup process\n" msgstr "" #: .././libxcmd/command.c:85 #, c-format msgid "bad argument count %d to %s, expected at least %d arguments\n" msgstr "" #: .././libxcmd/command.c:89 #, c-format msgid "bad argument count %d to %s, expected %d arguments\n" msgstr "" #: .././libxcmd/command.c:93 #, c-format msgid "bad argument count %d to %s, expected between %d and %d arguments\n" msgstr "" #: .././libxcmd/command.c:155 #, c-format msgid "cannot strdup command '%s': %s\n" msgstr "" #: .././libxcmd/command.c:171 .././libxcmd/command.c:189 #, c-format msgid "command \"%s\" not found\n" msgstr "" #: .././libxcmd/quit.c:42 msgid "exit the program" msgstr "" #: .././libxcmd/paths.c:263 #, c-format msgid "%s: unable to extract mount options for \"%s\"\n" msgstr "" #: .././libxcmd/paths.c:324 #, c-format msgid "%s: getmntinfo() failed: %s\n" msgstr "" #: .././libxcmd/paths.c:385 #, c-format msgid "%s: cannot setup path for mount %s: %s\n" msgstr "" #: .././libxcmd/paths.c:407 #, c-format msgid "%s: cannot find mount point for path `%s': %s\n" msgstr "" #: .././libxcmd/paths.c:435 #, c-format msgid "%s: cannot setup path for project %s: %s\n" msgstr "" #: .././libxcmd/paths.c:476 #, c-format msgid "%s: cannot initialise path table: %s\n" msgstr "" #: .././libxcmd/paths.c:496 #, c-format msgid "%s: cannot setup path for project dir %s: %s\n" msgstr "" #: .././libxfs/darwin.c:41 #, c-format msgid "%s: error opening the device special file \"%s\": %s\n" msgstr "" #: .././libxfs/darwin.c:48 #, c-format msgid "%s: can't tell if \"%s\" is writable: %s\n" msgstr "" #: .././libxfs/darwin.c:76 .././libxfs/irix.c:58 .././libxfs/linux.c:138 #: .././libxfs/freebsd.c:116 #, c-format msgid "%s: cannot stat the device file \"%s\": %s\n" msgstr "" #: .././libxfs/darwin.c:86 #, c-format msgid "%s: can't determine device size: %s\n" msgstr "" #: .././libxfs/darwin.c:139 .././libxfs/irix.c:106 .././libxfs/linux.c:216 #: .././libxfs/freebsd.c:196 #, c-format msgid "%s: can't determine memory size\n" msgstr "" #: .././libxfs/kmem.c:15 #, c-format msgid "%s: zone init failed (%s, %d bytes): %s\n" msgstr "" #: .././libxfs/kmem.c:32 #, c-format msgid "%s: zone alloc failed (%s, %d bytes): %s\n" msgstr "" #: .././libxfs/kmem.c:56 #, c-format msgid "%s: malloc failed (%d bytes): %s\n" msgstr "" #: .././libxfs/kmem.c:77 #, c-format msgid "%s: realloc failed (%d bytes): %s\n" msgstr "" #: .././libxfs/linux.c:67 .././libxfs/freebsd.c:60 #, c-format msgid "%s: %s contains a mounted filesystem\n" msgstr "" #: .././libxfs/linux.c:85 .././libxfs/freebsd.c:75 #, c-format msgid "%s: %s contains a possibly writable, mounted filesystem\n" msgstr "" #: .././libxfs/linux.c:99 .././libxfs/freebsd.c:89 #, c-format msgid "%s: %s contains a mounted and writable filesystem\n" msgstr "" #: .././libxfs/linux.c:114 #, c-format msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" msgstr "" #: .././libxfs/linux.c:161 #, c-format msgid "%s: can't determine device size\n" msgstr "" #: .././libxfs/linux.c:169 #, c-format msgid "%s: warning - cannot get sector size from block device %s: %s\n" msgstr "" #: .././libxfs/init.c:80 .././libxfs/init.c:179 #, c-format msgid "%s: %s: device %lld is not open\n" msgstr "" #: .././libxfs/init.c:116 #, c-format msgid "%s: cannot stat %s: %s\n" msgstr "" #: .././libxfs/init.c:141 #, c-format msgid "%s: device %lld is already open\n" msgstr "" #: .././libxfs/init.c:154 #, c-format msgid "%s: %s: too many open devices\n" msgstr "" #: .././libxfs/init.c:197 #, c-format msgid "%s: can't find a character device matching %s\n" msgstr "" #: .././libxfs/init.c:203 #, c-format msgid "%s: can't find a block device matching %s\n" msgstr "" #: .././libxfs/init.c:320 #, c-format msgid "%s: can't get size for data subvolume\n" msgstr "" #: .././libxfs/init.c:325 #, c-format msgid "%s: can't get size for log subvolume\n" msgstr "" #: .././libxfs/init.c:330 #, c-format msgid "%s: can't get size for realtime subvolume\n" msgstr "" #: .././libxfs/init.c:430 #, c-format msgid "%s: cannot read realtime bitmap inode (%d)\n" msgstr "" #: .././libxfs/init.c:440 #, c-format msgid "%s: cannot read realtime summary inode (%d)\n" msgstr "" #: .././libxfs/init.c:464 #, c-format msgid "%s: filesystem has a realtime subvolume\n" msgstr "" #: .././libxfs/init.c:486 #, c-format msgid "%s: realtime init - %llu != %llu\n" msgstr "" #: .././libxfs/init.c:494 #, c-format msgid "%s: realtime size check failed\n" msgstr "" #: .././libxfs/init.c:699 #, c-format msgid "%s: size check failed\n" msgstr "" #: .././libxfs/init.c:708 #, c-format msgid "%s: WARNING - filesystem uses v1 dirs,limited functionality provided.\n" msgstr "" #: .././libxfs/init.c:728 #, c-format msgid "%s: data size check failed\n" msgstr "" #: .././libxfs/init.c:741 #, c-format msgid "%s: log size checks failed\n" msgstr "" #: .././libxfs/init.c:752 #, c-format msgid "%s: realtime device init failed\n" msgstr "" #: .././libxfs/init.c:759 #, c-format msgid "%s: perag init failed\n" msgstr "" #: .././libxfs/init.c:771 #, c-format msgid "%s: cannot read root inode (%d)\n" msgstr "" #: .././libxfs/init.c:791 #, c-format msgid "%s: cannot init perag data (%d)\n" msgstr "" #: .././libxfs/trans.c:33 #, c-format msgid "%s: xact calloc failed (%d bytes): %s\n" msgstr "" #: .././libxfs/trans.c:602 #, c-format msgid "%s: warning - itobp failed (%d)\n" msgstr "" #: .././libxfs/trans.c:610 #, c-format msgid "%s: warning - iflush_int failed (%d)\n" msgstr "" #: .././libxfs/trans.c:682 .././libxfs/trans.c:741 #, c-format msgid "%s: unrecognised log item type\n" msgstr "" #: .././libxfs/util.c:707 #, c-format msgid "%s: cannot reserve space: %s\n" msgstr "" #: .././libxfs/freebsd.c:49 #, c-format msgid "%s: %s possibly contains a mounted filesystem\n" msgstr "" #: .././libxfs/freebsd.c:129 #, c-format msgid "%s: Not a device or file: \"%s\"\n" msgstr "" #: .././libxfs/freebsd.c:135 #, c-format msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" msgstr "" #: .././libxfs/freebsd.c:141 #, c-format msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" msgstr "" #: .././libxfs/rdwr.c:40 #, c-format msgid "%s: %s can't memalign %d bytes: %s\n" msgstr "" #: .././libxfs/rdwr.c:50 #, c-format msgid "%s: %s seek to offset %llu failed: %s\n" msgstr "" #: .././libxfs/rdwr.c:60 #, c-format msgid "%s: %s write failed: %s\n" msgstr "" #: .././libxfs/rdwr.c:64 #, c-format msgid "%s: %s not progressing?\n" msgstr "" #: .././libxfs/rdwr.c:336 #, c-format msgid "%s: %s can't memalign %u bytes: %s\n" msgstr "" #: .././libxfs/rdwr.c:425 #, c-format msgid "Warning: recursive buffer locking at block % detected\n" msgstr "" #: .././libxfs/rdwr.c:519 #, c-format msgid "%s: read failed: %s\n" msgstr "" #: .././libxfs/rdwr.c:525 #, c-format msgid "%s: error - read only %d of %d bytes\n" msgstr "" #: .././libxfs/rdwr.c:568 #, c-format msgid "%s: pwrite64 failed: %s\n" msgstr "" #: .././libxfs/rdwr.c:574 #, c-format msgid "%s: error - wrote only %d of %d bytes\n" msgstr "" #: .././libxlog/util.c:37 #, c-format msgid "" "* ERROR: mismatched uuid in log\n" "* SB : %s\n" "* log: %s\n" msgstr "" #: .././libxlog/util.c:50 #, c-format msgid "" "\n" "LOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n" msgstr "" #: .././libxlog/util.c:58 #, c-format msgid "* ERROR: bad magic number in log header: 0x%x\n" msgstr "" #: .././libxlog/util.c:67 #, c-format msgid "* ERROR: log format incompatible (log=%d, ours=%d)\n" msgstr "" #: .././libxlog/util.c:77 .././libxlog/util.c:89 msgid "Bad log" msgstr "" #: .././logprint/log_copy.c:44 .././logprint/log_dump.c:43 #, c-format msgid "%s: read error (%lld): %s\n" msgstr "" #: .././logprint/log_copy.c:49 .././logprint/log_dump.c:48 #, c-format msgid "%s: physical end of log at %lld\n" msgstr "" #: .././logprint/log_copy.c:53 #, c-format msgid "%s: short read? (%lld)\n" msgstr "" #: .././logprint/log_copy.c:60 #, c-format msgid "%s: write error (%lld): %s\n" msgstr "" #: .././logprint/log_copy.c:65 #, c-format msgid "%s: short write? (%lld)\n" msgstr "" #: .././logprint/log_dump.c:56 #, c-format msgid "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n" msgstr "" #: .././logprint/log_dump.c:67 #, c-format msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" msgstr "" #: .././logprint/logprint.c:42 #, c-format msgid "" "Usage: %s [options...] \n" "\n" "Options:\n" " -c\t try to continue if error found in log\n" " -C copy the log from the filesystem to filename\n" " -d\t dump the log in log-record format\n" " -f\t specified device is actually a file\n" " -l filename of external log\n" " -n\t don't try and interpret log data\n" " -o\t print buffer data in hex\n" " -s block # to start printing\n" " -v print \"overwrite\" data\n" " -t\t print out transactional view\n" "\t-b in transactional view, extract buffer info\n" "\t-i in transactional view, extract inode info\n" "\t-q in transactional view, extract quota info\n" " -D print only data; no decoding\n" " -V print version information\n" msgstr "" #: .././logprint/logprint.c:75 #, c-format msgid " Can't open device %s: %s\n" msgstr "" #: .././logprint/logprint.c:81 #, c-format msgid " read of XFS superblock failed\n" msgstr "" #: .././logprint/logprint.c:97 #, c-format msgid "" " external log device not specified\n" "\n" msgstr "" #: .././logprint/logprint.c:112 #, c-format msgid "Can't open file %s: %s\n" msgstr "" #: .././logprint/logprint.c:212 #, c-format msgid "xfs_logprint:\n" msgstr "" #: .././logprint/logprint.c:220 #, c-format msgid " data device: 0x%llx\n" msgstr "" #: .././logprint/logprint.c:223 #, c-format msgid " log file: \"%s\" " msgstr "" #: .././logprint/logprint.c:225 #, c-format msgid " log device: 0x%llx " msgstr "" #: .././logprint/logprint.c:228 #, c-format msgid "" "daddr: %lld length: %lld\n" "\n" msgstr "" #: .././logprint/log_misc.c:132 #, c-format msgid "Oper (%d): tid: %x len: %d clientid: %s " msgstr "" #: .././logprint/log_misc.c:137 #, c-format msgid "flags: " msgstr "" #: .././logprint/log_misc.c:231 #, c-format msgid " Not enough data to decode further\n" msgstr "" #: .././logprint/log_misc.c:235 #, c-format msgid " type: %s tid: %x num_items: %d\n" msgstr "" #: .././logprint/log_misc.c:277 #, c-format msgid "" "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" msgstr "" #: .././logprint/log_misc.c:283 #, c-format msgid "#regs: %d Not printing rest of data\n" msgstr "" #: .././logprint/log_misc.c:300 #, c-format msgid "SUPER BLOCK Buffer: " msgstr "" #: .././logprint/log_misc.c:302 .././logprint/log_misc.c:366 #: .././logprint/log_misc.c:392 #, c-format msgid "Out of space\n" msgstr "" #: .././logprint/log_misc.c:310 #, c-format msgid "icount: %llu ifree: %llu " msgstr "" #: .././logprint/log_misc.c:315 #, c-format msgid "fdblks: %llu frext: %llu\n" msgstr "" #: .././logprint/log_misc.c:322 #, c-format msgid "AGI Buffer: XAGI " msgstr "" #: .././logprint/log_misc.c:325 #, c-format msgid "out of space\n" msgstr "" #: .././logprint/log_misc.c:328 #, c-format msgid "ver: %d " msgstr "" #: .././logprint/log_misc.c:330 #, c-format msgid "seq#: %d len: %d cnt: %d root: %d\n" msgstr "" #: .././logprint/log_misc.c:335 #, c-format msgid "level: %d free#: 0x%x newino: 0x%x\n" msgstr "" #: .././logprint/log_misc.c:345 #, c-format msgid "AGI unlinked data skipped " msgstr "" #: .././logprint/log_misc.c:346 #, c-format msgid "(CONTINUE set, no space)\n" msgstr "" #: .././logprint/log_misc.c:352 #, c-format msgid "bucket[%d - %d]: " msgstr "" #: .././logprint/log_misc.c:364 #, c-format msgid "AGF Buffer: XAGF " msgstr "" #: .././logprint/log_misc.c:369 #, c-format msgid "ver: %d seq#: %d len: %d \n" msgstr "" #: .././logprint/log_misc.c:373 #, c-format msgid "root BNO: %d CNT: %d\n" msgstr "" #: .././logprint/log_misc.c:376 #, c-format msgid "level BNO: %d CNT: %d\n" msgstr "" #: .././logprint/log_misc.c:379 #, c-format msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" msgstr "" #: .././logprint/log_misc.c:389 #, c-format msgid "DQUOT Buffer: DQ " msgstr "" #: .././logprint/log_misc.c:396 #, c-format msgid "ver: %d flags: 0x%x id: %d \n" msgstr "" #: .././logprint/log_misc.c:399 #, c-format msgid "blk limits hard: %llu soft: %llu\n" msgstr "" #: .././logprint/log_misc.c:404 #, c-format msgid "blk count: %llu warns: %d timer: %d\n" msgstr "" #: .././logprint/log_misc.c:408 #, c-format msgid "ino limits hard: %llu soft: %llu\n" msgstr "" #: .././logprint/log_misc.c:413 #, c-format msgid "ino count: %llu warns: %d timer: %d\n" msgstr "" #: .././logprint/log_misc.c:419 #, c-format msgid "BUF DATA\n" msgstr "" #: .././logprint/log_misc.c:461 #, c-format msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" #: .././logprint/log_misc.c:468 #, c-format msgid "EFD: Not enough data to decode further\n" msgstr "" #: .././logprint/log_misc.c:488 .././logprint/log_misc.c:497 #, c-format msgid "%s: xlog_print_trans_efi: malloc failed\n" msgstr "" #: .././logprint/log_misc.c:505 #, c-format msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" #: .././logprint/log_misc.c:532 #, c-format msgid "QOFF: #regs: %d flags: 0x%x\n" msgstr "" #: .././logprint/log_misc.c:535 #, c-format msgid "QOFF: Not enough data to decode further\n" msgstr "" #: .././logprint/log_misc.c:544 #, c-format msgid "INODE CORE\n" msgstr "" #: .././logprint/log_misc.c:545 #, c-format msgid "magic 0x%hx mode 0%ho version %d format %d\n" msgstr "" #: .././logprint/log_misc.c:548 #, c-format msgid "nlink %hd uid %d gid %d\n" msgstr "" #: .././logprint/log_misc.c:550 #, c-format msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" msgstr "" #: .././logprint/log_misc.c:552 #, c-format msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" msgstr "" #: .././logprint/log_misc.c:555 #, c-format msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" msgstr "" #: .././logprint/log_misc.c:558 #, c-format msgid "flags 0x%x gen 0x%x\n" msgstr "" #: .././logprint/log_misc.c:574 #, c-format msgid "SHORTFORM DIRECTORY size %d\n" msgstr "" #: .././logprint/log_misc.c:580 #, c-format msgid "SHORTFORM DIRECTORY size %d count %d\n" msgstr "" #: .././logprint/log_misc.c:583 #, c-format msgid ".. ino 0x%llx\n" msgstr "" #: .././logprint/log_misc.c:591 #, c-format msgid "%s ino 0x%llx namelen %d\n" msgstr "" #: .././logprint/log_misc.c:623 #, c-format msgid "INODE: " msgstr "" #: .././logprint/log_misc.c:624 #, c-format msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" msgstr "" #: .././logprint/log_misc.c:627 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr "" #: .././logprint/log_misc.c:632 #, c-format msgid "INODE: #regs: %d Not printing rest of data\n" msgstr "" #: .././logprint/log_misc.c:665 #, c-format msgid "EXTENTS inode data\n" msgstr "" #: .././logprint/log_misc.c:676 #, c-format msgid "BTREE inode data\n" msgstr "" #: .././logprint/log_misc.c:687 #, c-format msgid "LOCAL inode data\n" msgstr "" #: .././logprint/log_misc.c:701 #, c-format msgid "EXTENTS inode attr\n" msgstr "" #: .././logprint/log_misc.c:712 #, c-format msgid "BTREE inode attr\n" msgstr "" #: .././logprint/log_misc.c:723 #, c-format msgid "LOCAL inode attr\n" msgstr "" #: .././logprint/log_misc.c:735 #, c-format msgid "DEV inode: no extra region\n" msgstr "" #: .././logprint/log_misc.c:740 #, c-format msgid "UUID inode: no extra region\n" msgstr "" #: .././logprint/log_misc.c:748 msgid "xlog_print_trans_inode: illegal inode type" msgstr "" #: .././logprint/log_misc.c:776 #, c-format msgid "#regs: %d id: 0x%x" msgstr "" #: .././logprint/log_misc.c:777 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr "" #: .././logprint/log_misc.c:781 #, c-format msgid "DQUOT: #regs: %d Not printing rest of data\n" msgstr "" #: .././logprint/log_misc.c:800 #, c-format msgid "DQUOT: magic 0x%hx flags 0%ho\n" msgstr "" #: .././logprint/log_misc.c:828 #, c-format msgid "%s: lseek64 to %lld failed: %s\n" msgstr "" #: .././logprint/log_misc.c:871 #, c-format msgid "%s: xlog_print_record: malloc failed\n" msgstr "" #: .././logprint/log_misc.c:880 #, c-format msgid "%s: xlog_print_record: read error\n" msgstr "" #: .././logprint/log_misc.c:967 #, c-format msgid "Left over region from split log item\n" msgstr "" #: .././logprint/log_misc.c:1011 #, c-format msgid "Unmount filesystem\n" msgstr "" #: .././logprint/log_misc.c:1016 #, c-format msgid "%s: unknown log operation type (%x)\n" msgstr "" #: .././logprint/log_misc.c:1051 #, c-format msgid "Header 0x%x wanted 0x%x\n" msgstr "" #: .././logprint/log_misc.c:1065 #, c-format msgid "cycle: %d\tversion: %d\t" msgstr "" #: .././logprint/log_misc.c:1071 #, c-format msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" msgstr "" #: .././logprint/log_misc.c:1077 .././logprint/log_misc.c:1119 #, c-format msgid "cycle num overwrites: " msgstr "" #: .././logprint/log_misc.c:1086 #, c-format msgid "uuid: %s format: " msgstr "" #: .././logprint/log_misc.c:1089 #, c-format msgid "unknown\n" msgstr "" #: .././logprint/log_misc.c:1092 #, c-format msgid "little endian linux\n" msgstr "" #: .././logprint/log_misc.c:1095 #, c-format msgid "big endian linux\n" msgstr "" #: .././logprint/log_misc.c:1098 #, c-format msgid "big endian irix\n" msgstr "" #: .././logprint/log_misc.c:1104 #, c-format msgid "h_size: %d\n" msgstr "" #: .././logprint/log_misc.c:1116 #, c-format msgid "extended-header: cycle: %d\n" msgstr "" #: .././logprint/log_misc.c:1132 #, c-format msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" msgstr "" #: .././logprint/log_misc.c:1143 #, c-format msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" msgstr "" #: .././logprint/log_misc.c:1154 #, c-format msgid "* ERROR: data block=%-21lld *\n" msgstr "" #: .././logprint/log_misc.c:1165 #, c-format msgid "" "* ERROR: for header block=%lld\n" "* not enough hdrs for data length, required num = %d, hdr num = %d\n" msgstr "" #: .././logprint/log_misc.c:1171 msgid "Not enough headers for data length." msgstr "" #: .././logprint/log_misc.c:1181 #, c-format msgid "%s: xlog_print: malloc failed for ext hdrs\n" msgstr "" #: .././logprint/log_misc.c:1227 .././logprint/log_misc.c:1302 #: .././logprint/log_misc.c:1368 .././logprint/log_misc.c:1405 #, c-format msgid "%s: physical end of log\n" msgstr "" #: .././logprint/log_misc.c:1233 .././logprint/log_misc.c:1307 #: .././logprint/log_misc.c:1420 #, c-format msgid "BLKNO: %lld\n" msgstr "" #: .././logprint/log_misc.c:1290 #, c-format msgid "%s: problem finding oldest LR\n" msgstr "" #: .././logprint/log_misc.c:1316 #, c-format msgid "%s: after %d zeroed blocks\n" msgstr "" #: .././logprint/log_misc.c:1380 msgid "illegal value" msgstr "" #: .././logprint/log_misc.c:1386 #, c-format msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" msgstr "" #: .././logprint/log_misc.c:1391 #, c-format msgid "%s: totally cleared log\n" msgstr "" #: .././logprint/log_misc.c:1396 #, c-format msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" msgstr "" #: .././logprint/log_misc.c:1401 #, c-format msgid "%s: totally zeroed log\n" msgstr "" #: .././logprint/log_misc.c:1417 msgid "xlog_find_head: bad read" msgstr "" #: .././logprint/log_misc.c:1473 #, c-format msgid "%s: logical end of log\n" msgstr "" #: .././logprint/log_misc.c:1565 #, c-format msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" msgstr "" #: .././logprint/log_print_all.c:98 #, c-format msgid "" "BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" msgstr "" #: .././logprint/log_print_all.c:108 #, c-format msgid "\tSUPER Block Buffer:\n" msgstr "" #: .././logprint/log_print_all.c:111 #, c-format msgid " icount:%llu ifree:%llu " msgstr "" #: .././logprint/log_print_all.c:116 #, c-format msgid "fdblks:%llu frext:%llu\n" msgstr "" #: .././logprint/log_print_all.c:121 #, c-format msgid "\t\tsunit:%u swidth:%u\n" msgstr "" #: .././logprint/log_print_all.c:126 #, c-format msgid "\tAGI Buffer: (XAGI)\n" msgstr "" #: .././logprint/log_print_all.c:129 #, c-format msgid "\t\tver:%d " msgstr "" #: .././logprint/log_print_all.c:131 #, c-format msgid "seq#:%d len:%d cnt:%d root:%d\n" msgstr "" #: .././logprint/log_print_all.c:136 #, c-format msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" msgstr "" #: .././logprint/log_print_all.c:142 #, c-format msgid "\tAGF Buffer: (XAGF)\n" msgstr "" #: .././logprint/log_print_all.c:145 #, c-format msgid "\t\tver:%d seq#:%d len:%d \n" msgstr "" #: .././logprint/log_print_all.c:149 #, c-format msgid "\t\troot BNO:%d CNT:%d\n" msgstr "" #: .././logprint/log_print_all.c:152 #, c-format msgid "\t\tlevel BNO:%d CNT:%d\n" msgstr "" #: .././logprint/log_print_all.c:155 #, c-format msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" msgstr "" #: .././logprint/log_print_all.c:164 #, c-format msgid "\tDQUOT Buffer:\n" msgstr "" #: .././logprint/log_print_all.c:167 #, c-format msgid "\t\tUIDs 0x%lx-0x%lx\n" msgstr "" #: .././logprint/log_print_all.c:172 #, c-format msgid "\tBUF DATA\n" msgstr "" #: .././logprint/log_print_all.c:194 #, c-format msgid "\tQUOTAOFF: #regs:%d type:%s\n" msgstr "" #: .././logprint/log_print_all.c:209 #, c-format msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" msgstr "" #: .././logprint/log_print_all.c:213 #, c-format msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" msgstr "" #: .././logprint/log_print_all.c:218 #, c-format msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" msgstr "" #: .././logprint/log_print_all.c:224 #, c-format msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" msgstr "" #: .././logprint/log_print_all.c:229 #, c-format msgid "\t\tbtimer 0x%x itimer 0x%x \n" msgstr "" #: .././logprint/log_print_all.c:238 #, c-format msgid "\tCORE inode:\n" msgstr "" #: .././logprint/log_print_all.c:241 #, c-format msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" msgstr "" #: .././logprint/log_print_all.c:245 #, c-format msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" msgstr "" #: .././logprint/log_print_all.c:247 #, c-format msgid "\t\tatime:%d mtime:%d ctime:%d\n" msgstr "" #: .././logprint/log_print_all.c:249 #, c-format msgid "\t\tflushiter:%d\n" msgstr "" #: .././logprint/log_print_all.c:250 #, c-format msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" msgstr "" #: .././logprint/log_print_all.c:254 #, c-format msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" msgstr "" #: .././logprint/log_print_all.c:274 #, c-format msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" msgstr "" #: .././logprint/log_print_all.c:289 #, c-format msgid "\t\tDATA FORK EXTENTS inode data:\n" msgstr "" #: .././logprint/log_print_all.c:296 #, c-format msgid "\t\tDATA FORK BTREE inode data:\n" msgstr "" #: .././logprint/log_print_all.c:303 #, c-format msgid "\t\tDATA FORK LOCAL inode data:\n" msgstr "" #: .././logprint/log_print_all.c:310 #, c-format msgid "\t\tDEV inode: no extra region\n" msgstr "" #: .././logprint/log_print_all.c:314 #, c-format msgid "\t\tUUID inode: no extra region\n" msgstr "" #: .././logprint/log_print_all.c:329 #, c-format msgid "\t\tATTR FORK EXTENTS inode data:\n" msgstr "" #: .././logprint/log_print_all.c:337 #, c-format msgid "\t\tATTR FORK BTREE inode data:\n" msgstr "" #: .././logprint/log_print_all.c:345 #, c-format msgid "\t\tATTR FORK LOCAL inode data:\n" msgstr "" #: .././logprint/log_print_all.c:370 #, c-format msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "" #: .././logprint/log_print_all.c:394 #, c-format msgid "%s: xlog_recover_print_efi: malloc failed\n" msgstr "" #: .././logprint/log_print_all.c:402 #, c-format msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" msgstr "" #: .././logprint/log_print_all.c:442 #, c-format msgid "xlog_recover_print_logitem: illegal type\n" msgstr "" #: .././logprint/log_print_all.c:473 #, c-format msgid "%s: illegal type" msgstr "" #: .././logprint/log_print_all.c:481 #, c-format msgid ": cnt:%d total:%d " msgstr "" #: .././logprint/log_print_all.c:483 #, c-format msgid "a:0x%lx len:%d " msgstr "" #: .././logprint/log_print_trans.c:25 #, c-format msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" msgstr "" #: .././logprint/log_print_trans.c:51 #, c-format msgid "%s: failed to find head and tail, error: %d\n" msgstr "" #: .././logprint/log_print_trans.c:56 #, c-format msgid " log tail: %lld head: %lld state: %s\n" msgstr "" #: .././logprint/log_print_trans.c:62 #, c-format msgid " override tail: %d\n" msgstr "" #: .././logprint/log_print_trans.c:72 #, c-format msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" msgstr "" #: .././mkfs/proto.c:60 #, c-format msgid "%s: failed to open %s: %s\n" msgstr "" #: .././mkfs/proto.c:66 .././mkfs/proto.c:291 #, c-format msgid "%s: read failed on %s: %s\n" msgstr "" #: .././mkfs/proto.c:71 #, c-format msgid "%s: proto file %s premature EOF\n" msgstr "" #: .././mkfs/proto.c:108 msgid "cannot reserve space" msgstr "" #: .././mkfs/proto.c:161 #, c-format msgid "%s: premature EOF in prototype file\n" msgstr "" #: .././mkfs/proto.c:180 msgid "error reserving space for a file" msgstr "" #: .././mkfs/proto.c:249 msgid "error allocating space for a file" msgstr "" #: .././mkfs/proto.c:253 #, c-format msgid "%s: cannot allocate space for file\n" msgstr "" #: .././mkfs/proto.c:316 msgid "directory createname error" msgstr "" #: .././mkfs/proto.c:330 msgid "directory create error" msgstr "" #: .././mkfs/proto.c:396 .././mkfs/proto.c:408 .././mkfs/proto.c:419 #: .././mkfs/proto.c:426 #, c-format msgid "%s: bad format string %s\n" msgstr "" #: .././mkfs/proto.c:447 .././mkfs/proto.c:486 .././mkfs/proto.c:501 #: .././mkfs/proto.c:513 .././mkfs/proto.c:525 .././mkfs/proto.c:536 msgid "Inode allocation failed" msgstr "" #: .././mkfs/proto.c:464 msgid "Inode pre-allocation failed" msgstr "" #: .././mkfs/proto.c:474 msgid "Pre-allocated file creation failed" msgstr "" #: .././mkfs/proto.c:556 msgid "Directory creation failed" msgstr "" #: .././mkfs/proto.c:580 msgid "Error encountered creating file from prototype file" msgstr "" #: .././mkfs/proto.c:630 msgid "Realtime bitmap inode allocation failed" msgstr "" #: .././mkfs/proto.c:648 msgid "Realtime summary inode allocation failed" msgstr "" #: .././mkfs/proto.c:675 msgid "Allocation of the realtime bitmap failed" msgstr "" #: .././mkfs/proto.c:688 msgid "Completion of the realtime bitmap failed" msgstr "" #: .././mkfs/proto.c:712 msgid "Allocation of the realtime summary failed" msgstr "" #: .././mkfs/proto.c:724 msgid "Completion of the realtime summary failed" msgstr "" #: .././mkfs/proto.c:741 msgid "Error initializing the realtime space" msgstr "" #: .././mkfs/proto.c:746 msgid "Error completing the realtime space" msgstr "" #: .././mkfs/xfs_mkfs.c:220 #, c-format msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" msgstr "" #: .././mkfs/xfs_mkfs.c:227 #, c-format msgid "both data sunit and data swidth options must be specified\n" msgstr "" #: .././mkfs/xfs_mkfs.c:236 #, c-format msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" msgstr "" #: .././mkfs/xfs_mkfs.c:243 #, c-format msgid "both data su and data sw options must be specified\n" msgstr "" #: .././mkfs/xfs_mkfs.c:250 #, c-format msgid "data su must be a multiple of the sector size (%d)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:261 #, c-format msgid "" "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:271 #, c-format msgid "log su should not be used in conjunction with log sunit\n" msgstr "" #: .././mkfs/xfs_mkfs.c:280 #, c-format msgid "log sunit should not be used in conjunction with log su\n" msgstr "" #: .././mkfs/xfs_mkfs.c:350 .././mkfs/xfs_mkfs.c:474 #, c-format msgid "%s: %s appears to contain an existing filesystem (%s).\n" msgstr "" #: .././mkfs/xfs_mkfs.c:354 .././mkfs/xfs_mkfs.c:480 #, c-format msgid "%s: %s appears to contain a partition table (%s).\n" msgstr "" #: .././mkfs/xfs_mkfs.c:358 #, c-format msgid "%s: %s appears to contain something weird according to blkid\n" msgstr "" #: .././mkfs/xfs_mkfs.c:368 #, c-format msgid "%s: probe of %s failed, cannot detect existing filesystem.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:421 #, c-format msgid "warning: device is not properly aligned %s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:426 #, c-format msgid "Use -f to force usage of a misaligned device\n" msgstr "" #: .././mkfs/xfs_mkfs.c:440 #, c-format msgid "warning: unable to probe device toplology for device %s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:549 #, c-format msgid "log size %lld is not a multiple of the log stripe unit %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:577 #, c-format msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:579 #, c-format msgid "Must fit within an allocation group.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:590 #, c-format msgid "log size %lld blocks too small, minimum size is %d blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:596 #, c-format msgid "log size %lld blocks too large, maximum size is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:602 #, c-format msgid "log size %lld bytes too large, maximum size is %lld bytes\n" msgstr "" #: .././mkfs/xfs_mkfs.c:710 #, c-format msgid "agsize (%lld blocks) too small, need at least %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:718 #, c-format msgid "agsize (%lld blocks) too big, maximum is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:726 #, c-format msgid "agsize (%lld blocks) too big, data area is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:733 #, c-format msgid "too many allocation groups for size = %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:735 #, c-format msgid "need at most %lld allocation groups\n" msgstr "" #: .././mkfs/xfs_mkfs.c:743 #, c-format msgid "too few allocation groups for size = %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:745 #, c-format msgid "need at least %lld allocation groups\n" msgstr "" #: .././mkfs/xfs_mkfs.c:758 #, c-format msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:769 #, c-format msgid "%lld allocation groups is too many, maximum is %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:793 #, c-format msgid "error reading existing superblock -- failed to memalign buffer\n" msgstr "" #: .././mkfs/xfs_mkfs.c:799 #, c-format msgid "existing superblock read failed: %s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1098 #, c-format msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1114 #, c-format msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1141 #, c-format msgid "%s: Specify data sw as multiple of su, no unit suffix\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1370 #, c-format msgid "Specify log sunit in 512-byte blocks, no size suffix\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1630 #, c-format msgid "extra arguments\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1636 #, c-format msgid "cannot specify both %s and -d name=%s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1653 #, c-format msgid "illegal block size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1688 #, c-format msgid "specified blocksize %d is less than device physical sector size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1691 #, c-format msgid "switching to logical sector size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1709 #, c-format msgid "illegal sector size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1712 #, c-format msgid "block size %d cannot be smaller than logical sector size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1717 #, c-format msgid "illegal sector size %d; hw sector is %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1723 #, c-format msgid "illegal log sector size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1733 #, c-format msgid "illegal directory block size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1747 #, c-format msgid "both -d agcount= and agsize= specified, use one or the other\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1753 #, c-format msgid "if -d file then -d name and -d size are required\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1762 #, c-format msgid "illegal data length %lld, not a multiple of %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1768 #, c-format msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1782 #, c-format msgid "if -l file then -l name and -l size are required\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1791 #, c-format msgid "illegal log length %lld, not a multiple of %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1798 #, c-format msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1804 #, c-format msgid "if -r file then -r name and -r size are required\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1813 #, c-format msgid "illegal rt length %lld, not a multiple of %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1820 #, c-format msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1833 #, c-format msgid "illegal rt extent size %lld, not a multiple of %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1839 #, c-format msgid "rt extent size %s too large, maximum %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1845 #, c-format msgid "rt extent size %s too small, minimum %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1890 #, c-format msgid "illegal inode size %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1895 #, c-format msgid "allowable inode size with %d byte blocks is %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1899 #, c-format msgid "allowable inode size with %d byte blocks is between %d and %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1907 #, c-format msgid "log stripe unit specified, using v2 logs\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1922 #, c-format msgid "no device name given in argument list\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1947 #, c-format msgid "%s: Use the -f option to force overwrite.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1966 msgid "internal log" msgstr "" #: .././mkfs/xfs_mkfs.c:1968 msgid "volume log" msgstr "" #: .././mkfs/xfs_mkfs.c:1970 #, c-format msgid "no log subvolume or internal log\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1977 msgid "volume rt" msgstr "" #: .././mkfs/xfs_mkfs.c:1982 #, c-format msgid "" "size %s specified for data subvolume is too large, maximum is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1989 #, c-format msgid "can't get size of data subvolume\n" msgstr "" #: .././mkfs/xfs_mkfs.c:1994 #, c-format msgid "size %lld of data subvolume is too small, minimum %d blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2001 #, c-format msgid "can't have both external and internal logs\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2005 #, c-format msgid "data and log sector sizes must be equal for internal logs\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2011 #, c-format msgid "" "Warning: the data subvolume sector size %u is less than the sector size \n" "reported by the device (%u).\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2017 #, c-format msgid "" "Warning: the log subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2023 #, c-format msgid "" "Warning: the realtime subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2037 #, c-format msgid "" "size %s specified for log subvolume is too large, maximum is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2044 #, c-format msgid "size specified for non-existent log subvolume\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2047 #, c-format msgid "size %lld too large for internal log\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2074 #, c-format msgid "" "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2082 #, c-format msgid "size specified for non-existent rt subvolume\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2099 #, c-format msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2116 #, c-format msgid "" "%s: Specified data stripe unit %d is not the same as the volume stripe unit %" "d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2123 #, c-format msgid "" "%s: Specified data stripe width %d is not the same as the volume stripe " "width %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2171 #, c-format msgid "agsize rounded to %lld, swidth = %d\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2203 #, c-format msgid "" "Warning: AG size is a multiple of stripe width. This can cause performance\n" "problems by aligning all AGs on the same disk. To avoid this, run mkfs " "with\n" "an AG size that is one stripe unit smaller, for example %llu.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2228 #, c-format msgid "" "%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%" "d)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2260 #, c-format msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2273 #, c-format msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2276 #, c-format msgid "log stripe unit adjusted to 32KiB\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2301 #, c-format msgid "internal log size %lld too large, must fit in allocation group\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2308 #, c-format msgid "log ag number %d too large, must be less than %lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2338 #, c-format msgid "" "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2454 #, c-format msgid "%s: Growing the data section failed\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2484 #, c-format msgid "%s: filesystem failed to initialize\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2696 #, c-format msgid "%s: root inode created in AG %u, not AG 0\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2763 #, c-format msgid "Cannot specify both -%c %s and -%c %s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2774 #, c-format msgid "Illegal value %s for -%s option\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2791 #, c-format msgid "-%c %s option requires a value\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2804 .././repair/xfs_repair.c:162 #, c-format msgid "option respecified\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2813 .././repair/xfs_repair.c:169 #, c-format msgid "unknown option -%c %s\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2852 #, c-format msgid "blocksize not available yet.\n" msgstr "" #: .././mkfs/xfs_mkfs.c:2878 #, c-format msgid "" "Usage: %s\n" "/* blocksize */\t\t[-b log=n|size=num]\n" "/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" "\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" "\t\t\t sectlog=n|sectsize=num\n" "/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n" "\t\t\t projid32bit=0|1]\n" "/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" "\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" "\t\t\t lazy-count=0|1]\n" "/* label */\t\t[-L label (maximum 12 characters)]\n" "/* naming */\t\t[-n log=n|size=num,version=2|ci]\n" "/* prototype file */\t[-p fname]\n" "/* quiet */\t\t[-q]\n" "/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" "/* sectorsize */\t[-s log=n|size=num]\n" "/* version */\t\t[-V]\n" "\t\t\tdevicename\n" " is required unless -d name=xxx is given.\n" " is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n" " xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" " is xxx (512 byte blocks).\n" msgstr "" #: .././quota/path.c:39 #, c-format msgid "%sFilesystem Pathname\n" msgstr "" #: .././quota/path.c:40 msgid " " msgstr "" #: .././quota/path.c:43 #, c-format msgid "%c%03d%c " msgstr "" #: .././quota/path.c:45 #, c-format msgid "%-19s %s" msgstr "" #: .././quota/path.c:48 #, c-format msgid " (project %u" msgstr "" #: .././quota/path.c:50 #, c-format msgid ", %s" msgstr "" #: .././quota/path.c:103 #, c-format msgid "No paths are available\n" msgstr "" #: .././quota/path.c:131 msgid "set current path, or show the list of paths" msgstr "" #: .././quota/path.c:139 msgid "list known mount points and projects" msgstr "" #: .././quota/project.c:45 #, c-format msgid "" "\n" " list projects or setup a project tree for tree quota management\n" "\n" " Example:\n" " 'project -c logfiles'\n" " (match project 'logfiles' to a directory, and setup the directory tree)\n" "\n" " Without arguments, report all projects found in the /etc/projects file.\n" " The project quota mechanism in XFS can be used to implement a form of\n" " directory tree quota, where a specified directory and all of the files\n" " and subdirectories below it (i.e. a tree) can be restricted to using a\n" " subset of the available space in the filesystem.\n" "\n" " A managed tree must be setup initially using the -c option with a project.\n" " The specified project name or identifier is matched to one or more trees\n" " defined in /etc/projects, and these trees are then recursively descended\n" " to mark the affected inodes as being part of that tree - which sets inode\n" " flags and the project identifier on every file.\n" " Once this has been done, new files created in the tree will automatically\n" " be accounted to the tree based on their project identifier. An attempt to\n" " create a hard link to a file in the tree will only succeed if the project\n" " identifier matches the project identifier for the tree. The xfs_io " "utility\n" " can be used to set the project ID for an arbitrary file, but this can only\n" " be done by a privileged user.\n" "\n" " A previously setup tree can be cleared from project quota control through\n" " use of the -C option, which will recursively descend the tree, clearing\n" " the affected inodes from project quota control.\n" "\n" " The -c option can be used to check whether a tree is setup, it reports\n" " nothing if the tree is correct, otherwise it reports the paths of inodes\n" " which do not have the project ID of the rest of the tree, or if the inode\n" " flag is not set.\n" "\n" " The -p option can be used to manually specify project path without\n" " need to create /etc/projects file. This option can be used multiple times\n" " to specify multiple paths. When using this option only one projid/name can\n" " be specified at command line. Note that /etc/projects is also used if " "exists.\n" "\n" " The -d option allows to descend at most levels of " "directories\n" " below the command line arguments. -d 0 means only apply the actions\n" " to the top level of the projects. -d -1 means no recursion limit " "(default).\n" "\n" " The /etc/projid and /etc/projects file formats are simple, and described\n" " on the xfs_quota man page.\n" "\n" msgstr "" #: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 #, c-format msgid "%s: cannot stat file %s\n" msgstr "" #: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 #, c-format msgid "%s: skipping special file %s\n" msgstr "" #: .././quota/project.c:126 #, c-format msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" msgstr "" #: .././quota/project.c:130 #, c-format msgid "%s - project inheritance flag is not set\n" msgstr "" #: .././quota/project.c:178 #, c-format msgid "%s: cannot clear project on %s: %s\n" msgstr "" #: .././quota/project.c:225 #, c-format msgid "%s: cannot set project on %s: %s\n" msgstr "" #: .././quota/project.c:240 #, c-format msgid "Checking project %s (path %s)...\n" msgstr "" #: .././quota/project.c:244 #, c-format msgid "Setting up project %s (path %s)...\n" msgstr "" #: .././quota/project.c:248 #, c-format msgid "Clearing project %s (path %s)...\n" msgstr "" #: .././quota/project.c:271 #, c-format msgid "" "Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%" "d).\n" msgstr "" #: .././quota/project.c:274 msgid "infinite" msgstr "" #: .././quota/project.c:274 msgid "limited" msgstr "" #: .././quota/project.c:319 #, c-format msgid "projects file \"%s\" doesn't exist\n" msgstr "" #: .././quota/project.c:326 #, c-format msgid "" "%s: only one projid/name can be specified when using -p , %d found.\n" msgstr "" #: .././quota/project.c:336 #, c-format msgid "%s - no such project in %s or invalid project number\n" msgstr "" #: .././quota/project.c:353 msgid "[-c|-s|-C|-d |-p ] project ..." msgstr "" #: .././quota/project.c:356 msgid "check, setup or clear project quota trees" msgstr "" #: .././quota/quot.c:55 #, c-format msgid "" "\n" " display a summary of filesystem ownership\n" "\n" " -a -- summarise for all local XFS filesystem mount points\n" " -c -- display three columns giving file size in kilobytes, number of files\n" " of that size, and cumulative total of kilobytes in that size or\n" " smaller file. The last row is used as an overflow bucket and is the\n" " total of all files greater than 500 kilobytes.\n" " -v -- display three columns containing the number of kilobytes not\n" " accessed in the last 30, 60, and 90 days.\n" " -g -- display group summary\n" " -p -- display project summary\n" " -u -- display user summary\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" #: .././quota/quot.c:219 #, c-format msgid "%s (%s) %s:\n" msgstr "" #: .././quota/quot.c:295 #, c-format msgid "%s (%s):\n" msgstr "" #: .././quota/quot.c:300 .././quota/quot.c:304 #, c-format msgid "%d\t%llu\t%llu\n" msgstr "" #: .././quota/quot.c:418 msgid "[-bir] [-gpu] [-acv] [-f file]" msgstr "" #: .././quota/quot.c:419 msgid "summarize filesystem ownership" msgstr "" #: .././quota/quota.c:32 #, c-format msgid "" "\n" " display usage and quota information\n" "\n" " -g -- display group quota information\n" " -p -- display project quota information\n" " -u -- display user quota information\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -v -- increase verbosity in reporting (also dumps zero values)\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" #: .././quota/quota.c:85 #, c-format msgid "" "Disk quotas for %s %s (%u)\n" "Filesystem%s" msgstr "" #: .././quota/quota.c:90 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:91 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:94 #, c-format msgid " Files Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:95 #, c-format msgid " Files Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:98 #, c-format msgid "Realtime Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:99 #, c-format msgid " Realtime Quota Limit Warn/Time " msgstr "" #: .././quota/quota.c:235 #, c-format msgid "%s: cannot find user %s\n" msgstr "" #: .././quota/quota.c:285 #, c-format msgid "%s: cannot find group %s\n" msgstr "" #: .././quota/quota.c:342 #, c-format msgid "%s: must specify a project name/ID\n" msgstr "" #: .././quota/quota.c:355 #, c-format msgid "%s: cannot find project %s\n" msgstr "" #: .././quota/quota.c:460 msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." msgstr "" #: .././quota/quota.c:461 msgid "show usage and limits" msgstr "" #: .././quota/free.c:29 #, c-format msgid "" "\n" " reports the number of free disk blocks and inodes\n" "\n" " This command reports the number of total, used, and available disk blocks.\n" " It can optionally report the same set of numbers for inodes and realtime\n" " disk blocks, and will report on all known XFS filesystem mount points and\n" " project quota paths by default (see 'print' command for a list).\n" " -b -- report the block count values\n" " -i -- report the inode count values\n" " -r -- report the realtime block count values\n" " -h -- report in a human-readable format\n" " -N -- suppress the header from the output\n" "\n" msgstr "" #: .././quota/free.c:154 #, c-format msgid "%s: project quota flag not set on %s\n" msgstr "" #: .././quota/free.c:163 #, c-format msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" msgstr "" #: .././quota/free.c:230 #, c-format msgid "Filesystem " msgstr "" #: .././quota/free.c:230 #, c-format msgid "Filesystem " msgstr "" #: .././quota/free.c:233 #, c-format msgid " Size Used Avail Use%%" msgstr "" #: .././quota/free.c:234 #, c-format msgid " 1K-blocks Used Available Use%%" msgstr "" #: .././quota/free.c:237 #, c-format msgid " Inodes Used Free Use%%" msgstr "" #: .././quota/free.c:238 #, c-format msgid " Inodes IUsed IFree IUse%%" msgstr "" #: .././quota/free.c:239 #, c-format msgid " Pathname\n" msgstr "" #: .././quota/free.c:371 msgid "[-bir] [-hn] [-f file]" msgstr "" #: .././quota/free.c:372 msgid "show free and used counts for blocks and inodes" msgstr "" #: .././quota/state.c:33 #, c-format msgid "" "\n" " turn filesystem quota off, both accounting and enforcement\n" "\n" " Example:\n" " 'off -uv' (switch off user quota on the current filesystem)\n" " This command is the equivalent of the traditional quotaoff command,\n" " which disables quota completely on a mounted filesystem.\n" " Note that there is no 'on' command - for XFS filesystems (with the\n" " exception of the root filesystem on IRIX) quota can only be enabled\n" " at mount time, through the use of one of the quota mount options.\n" "\n" " The state command is useful for displaying the current state. Using\n" " the -v (verbose) option with the 'off' command will display the quota\n" " state for the affected filesystem once the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" #: .././quota/state.c:56 #, c-format msgid "" "\n" " query the state of quota on the current filesystem\n" "\n" " This is a verbose status command, reporting whether or not accounting\n" " and/or enforcement are enabled for a filesystem, which inodes are in\n" " use as the quota state inodes, and how many extents and blocks are\n" " presently being used to hold that information.\n" " The quota type is specified via -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" #: .././quota/state.c:72 #, c-format msgid "" "\n" " enable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and has quota accounting enabled, but not\n" " quota enforcement, enforcement can be enabled with this command.\n" " With the -v (verbose) option, the status of the filesystem will be\n" " reported after the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" #: .././quota/state.c:88 #, c-format msgid "" "\n" " disable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and is currently enforcing quota, this\n" " provides a mechanism to switch off the enforcement, but continue to\n" " perform used space (and used inodes) accounting.\n" " The affected quota type is -g (groups), -p (projects) or -u (users).\n" "\n" msgstr "" #: .././quota/state.c:102 #, c-format msgid "" "\n" " remove any space being used by the quota subsystem\n" "\n" " Once quota has been switched 'off' on a filesystem, the space that\n" " was allocated to holding quota metadata can be freed via this command.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" #: .././quota/state.c:121 #, c-format msgid "%s quota state on %s (%s)\n" msgstr "" #: .././quota/state.c:123 #, c-format msgid " Accounting: %s\n" msgstr "" #: .././quota/state.c:123 .././quota/state.c:124 msgid "ON" msgstr "" #: .././quota/state.c:123 .././quota/state.c:124 msgid "OFF" msgstr "" #: .././quota/state.c:124 #, c-format msgid " Enforcement: %s\n" msgstr "" #: .././quota/state.c:126 #, c-format msgid " Inode: #%llu (%llu blocks, %lu extents)\n" msgstr "" #: .././quota/state.c:131 #, c-format msgid " Inode: N/A\n" msgstr "" #: .././quota/state.c:140 #, c-format msgid "%s grace time: %s\n" msgstr "" #: .././quota/state.c:157 #, c-format msgid "%s quota are not enabled on %s\n" msgstr "" #: .././quota/state.c:527 .././quota/state.c:543 .././quota/state.c:551 #: .././quota/state.c:559 msgid "[-gpu] [-v]" msgstr "" #: .././quota/state.c:528 msgid "permanently switch quota off for a path" msgstr "" #: .././quota/state.c:535 msgid "[-gpu] [-a] [-v] [-f file]" msgstr "" #: .././quota/state.c:536 msgid "get overall quota state information" msgstr "" #: .././quota/state.c:544 msgid "enable quota enforcement" msgstr "" #: .././quota/state.c:552 msgid "disable quota enforcement" msgstr "" #: .././quota/state.c:560 msgid "remove quota extents from a filesystem" msgstr "" #: .././quota/util.c:59 #, c-format msgid "[-none-]" msgstr "" #: .././quota/util.c:59 #, c-format msgid "[--none--]" msgstr "" #: .././quota/util.c:62 #, c-format msgid "[------]" msgstr "" #: .././quota/util.c:62 #, c-format msgid "[--------]" msgstr "" #: .././quota/util.c:66 .././quota/util.c:69 msgid "day" msgstr "" #: .././quota/util.c:66 .././quota/util.c:69 msgid "days" msgstr "" #: .././quota/util.c:194 msgid "Blocks" msgstr "" #: .././quota/util.c:194 msgid "Inodes" msgstr "" #: .././quota/util.c:194 msgid "Realtime Blocks" msgstr "" #: .././quota/util.c:209 msgid "User" msgstr "" #: .././quota/util.c:209 msgid "Group" msgstr "" #: .././quota/util.c:209 msgid "Project" msgstr "" #: .././quota/util.c:417 #, c-format msgid "%s: open on %s failed: %s\n" msgstr "" #: .././quota/util.c:423 #, c-format msgid "%s: fdopen on %s failed: %s\n" msgstr "" #: .././quota/edit.c:36 #, c-format msgid "" "\n" " modify quota limits for the specified user\n" "\n" " Example:\n" " 'limit bsoft=100m bhard=110m tanya\n" "\n" " Changes the soft and/or hard block limits, inode limits and/or realtime\n" " block limits that are currently being used for the specified user, group,\n" " or project. The filesystem identified by the current path is modified.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota limits\n" " -p -- modify project quota limits\n" " -u -- modify user quota limits\n" " The block limit values can be specified with a units suffix - accepted\n" " units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" #: .././quota/edit.c:59 #, c-format msgid "" "\n" " modify quota enforcement timeout for the current filesystem\n" "\n" " Example:\n" " 'timer -i 3days'\n" " (soft inode limit timer is changed to 3 days)\n" "\n" " Changes the timeout value associated with the block limits, inode limits\n" " and/or realtime block limits for all users, groups, or projects on the\n" " current filesystem.\n" " As soon as a user consumes the amount of space or number of inodes set as\n" " the soft limit, a timer is started. If the timer expires and the user is\n" " still over the soft limit, the soft limit is enforced as the hard limit.\n" " The default timeout is 7 days.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota timer\n" " -p -- modify project quota timer\n" " -u -- modify user quota timer\n" " -b -- modify the blocks-used timer\n" " -i -- modify the inodes-used timer\n" " -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" " The timeout value is specified as a number of seconds, by default.\n" " However, a suffix may be used to alternatively specify minutes (m),\n" " hours (h), days (d), or weeks (w) - either the full word or the first\n" " letter of the word can be used.\n" "\n" msgstr "" #: .././quota/edit.c:91 #, c-format msgid "" "\n" " modify the number of quota warnings sent to the specified user\n" "\n" " Example:\n" " 'warn 2 jimmy'\n" " (tell the quota system that two warnings have been sent to user jimmy)\n" "\n" " Changes the warning count associated with the block limits, inode limits\n" " and/or realtime block limits for the specified user, group, or project.\n" " When a user has been warned the maximum number of times allowed, the soft\n" " limit is enforced as the hard limit. It is intended as an alternative to\n" " the timeout system, where the system administrator updates a count of the\n" " number of warnings issued to people, and they are penalised if the " "warnings\n" " are ignored.\n" " -d -- set maximum warning count, which triggers soft limit enforcement\n" " -g -- set group quota warning count\n" " -p -- set project quota warning count\n" " -u -- set user quota warning count\n" " -b -- set the blocks-used warning count\n" " -i -- set the inodes-used warning count\n" " -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" #: .././quota/edit.c:145 #, c-format msgid "%s: cannot set limits: %s\n" msgstr "" #: .././quota/edit.c:166 .././quota/edit.c:569 #, c-format msgid "%s: invalid user name: %s\n" msgstr "" #: .././quota/edit.c:189 .././quota/edit.c:586 #, c-format msgid "%s: invalid group name: %s\n" msgstr "" #: .././quota/edit.c:212 .././quota/edit.c:603 #, c-format msgid "%s: invalid project name: %s\n" msgstr "" #: .././quota/edit.c:237 #, c-format msgid "%s: Error: could not parse size %s.\n" msgstr "" #: .././quota/edit.c:243 #, c-format msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" msgstr "" #: .././quota/edit.c:332 #, c-format msgid "%s: unrecognised argument %s\n" msgstr "" #: .././quota/edit.c:339 #, c-format msgid "%s: cannot find any valid arguments\n" msgstr "" #: .././quota/edit.c:447 #, c-format msgid "%s: fopen on %s failed: %s\n" msgstr "" #: .././quota/edit.c:479 #, c-format msgid "%s: cannot set timer: %s\n" msgstr "" #: .././quota/edit.c:553 #, c-format msgid "%s: cannot set warnings: %s\n" msgstr "" #: .././quota/edit.c:689 msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" msgstr "" #: .././quota/edit.c:690 msgid "modify quota limits" msgstr "" #: .././quota/edit.c:697 .././quota/report.c:33 .././quota/report.c:647 msgid "[-gpu] [-f file]" msgstr "" #: .././quota/edit.c:698 msgid "restore quota limits from a backup file" msgstr "" #: .././quota/edit.c:704 .././quota/edit.c:712 msgid "[-bir] [-gpu] value -d|id|name" msgstr "" #: .././quota/edit.c:705 msgid "get/set quota enforcement timeouts" msgstr "" #: .././quota/edit.c:713 msgid "get/set enforcement warning counter" msgstr "" #: .././quota/init.c:48 #, c-format msgid "Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n" msgstr "" #: .././quota/report.c:34 .././quota/report.c:648 msgid "dump quota information for backup utilities" msgstr "" #: .././quota/report.c:36 #, c-format msgid "" "\n" " create a backup file which contains quota limits information\n" " -g -- dump out group quota limits\n" " -p -- dump out project quota limits\n" " -u -- dump out user quota limits (default)\n" " -f -- write the dump out to the specified file\n" "\n" msgstr "" #: .././quota/report.c:48 msgid "[-bir] [-gpu] [-ahntLNU] [-f file]" msgstr "" #: .././quota/report.c:49 .././quota/report.c:658 msgid "report filesystem quota information" msgstr "" #: .././quota/report.c:51 #, c-format msgid "" "\n" " report used space and inodes, and quota limits, for a filesystem\n" " Example:\n" " 'report -igh'\n" " (reports inode usage for all groups, in an easy-to-read format)\n" " This command is the equivalent of the traditional repquota command, which\n" " prints a summary of the disk usage and quotas for the current filesystem,\n" " or all filesystems.\n" " -a -- report for all mounted filesystems with quota enabled\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the header from the output\n" " -t -- terse output format, hides rows which are all zero\n" " -L -- lower ID bound to report on\n" " -U -- upper ID bound to report on\n" " -g -- report group usage and quota information\n" " -p -- report project usage and quota information\n" " -u -- report user usage and quota information\n" " -b -- report blocks-used information only\n" " -i -- report inodes-used information only\n" " -r -- report realtime-blocks-used information only\n" "\n" msgstr "" #: .././quota/report.c:228 #, c-format msgid "%s quota on %s (%s)\n" msgstr "" #: .././quota/report.c:253 .././quota/report.c:261 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr "" #: .././quota/report.c:254 .././quota/report.c:262 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr "" #: .././quota/report.c:257 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr "" #: .././quota/report.c:258 #, c-format msgid " Used Soft Hard Warn/ Grace " msgstr "" #: .././quota/report.c:657 msgid "[-bir] [-gpu] [-ahnt] [-f file]" msgstr "" #: .././repair/init.c:47 #, c-format msgid "getrlimit(RLIMIT_FSIZE) failed!\n" msgstr "" #: .././repair/init.c:55 #, c-format msgid "setrlimit failed - current: %lld, max: %lld\n" msgstr "" #: .././repair/init.c:102 msgid "couldn't initialize XFS library\n" msgstr "" #: .././repair/sb.c:100 msgid "" "\n" "attempting to find secondary superblock...\n" msgstr "" #: .././repair/sb.c:105 msgid "error finding secondary superblock -- failed to memalign buffer\n" msgstr "" #: .././repair/sb.c:142 msgid "found candidate secondary superblock...\n" msgstr "" #: .././repair/sb.c:154 msgid "verified secondary superblock...\n" msgstr "" #: .././repair/sb.c:159 msgid "unable to verify superblock, continuing...\n" msgstr "" #: .././repair/sb.c:457 msgid "failed to memalign superblock buffer\n" msgstr "" #: .././repair/sb.c:464 msgid "couldn't seek to offset 0 in filesystem\n" msgstr "" #: .././repair/sb.c:472 msgid "primary superblock write failed!\n" msgstr "" #: .././repair/sb.c:490 #, c-format msgid "error reading superblock %u -- failed to memalign buffer\n" msgstr "" #: .././repair/sb.c:500 #, c-format msgid "error reading superblock %u -- seek to offset % failed\n" msgstr "" #: .././repair/sb.c:508 #, c-format msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" msgstr "" #: .././repair/sb.c:554 msgid "couldn't malloc geometry structure\n" msgstr "" #: .././repair/sb.c:706 msgid "calloc failed in verify_set_primary_sb\n" msgstr "" #: .././repair/sb.c:777 msgid "" "Only two AGs detected and they do not match - cannot validate filesystem " "geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" #: .././repair/sb.c:793 msgid "" "Only one AG detected - cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" #: .././repair/sb.c:808 msgid "Not enough matching superblocks - cannot proceed.\n" msgstr "" #: .././repair/sb.c:823 msgid "could not read superblock\n" msgstr "" #: .././repair/rt.c:47 msgid "couldn't allocate memory for incore realtime bitmap.\n" msgstr "" #: .././repair/rt.c:51 msgid "couldn't allocate memory for incore realtime summary info.\n" msgstr "" #: .././repair/rt.c:203 #, c-format msgid "can't find block %d for rtbitmap inode\n" msgstr "" #: .././repair/rt.c:211 #, c-format msgid "can't read block %d for rtbitmap inode\n" msgstr "" #: .././repair/rt.c:265 #, c-format msgid "block %d for rtsummary inode is missing\n" msgstr "" #: .././repair/rt.c:273 #, c-format msgid "can't read block %d for rtsummary inode\n" msgstr "" #: .././repair/agheader.c:35 #, c-format msgid "bad magic # 0x%x for agf %d\n" msgstr "" #: .././repair/agheader.c:44 #, c-format msgid "bad version # %d for agf %d\n" msgstr "" #: .././repair/agheader.c:53 #, c-format msgid "bad sequence # %d for agf %d\n" msgstr "" #: .././repair/agheader.c:63 #, c-format msgid "bad length %d for agf %d, should be %d\n" msgstr "" #: .././repair/agheader.c:76 #, c-format msgid "bad length %d for agf %d, should be %\n" msgstr "" #: .././repair/agheader.c:90 #, c-format msgid "flfirst %d in agf %d too large (max = %zu)\n" msgstr "" #: .././repair/agheader.c:98 #, c-format msgid "fllast %d in agf %d too large (max = %zu)\n" msgstr "" #: .././repair/agheader.c:120 #, c-format msgid "bad magic # 0x%x for agi %d\n" msgstr "" #: .././repair/agheader.c:129 #, c-format msgid "bad version # %d for agi %d\n" msgstr "" #: .././repair/agheader.c:138 #, c-format msgid "bad sequence # %d for agi %d\n" msgstr "" #: .././repair/agheader.c:148 #, c-format msgid "bad length # %d for agi %d, should be %d\n" msgstr "" #: .././repair/agheader.c:161 #, c-format msgid "bad length # %d for agi %d, should be %\n" msgstr "" #: .././repair/agheader.c:271 #, c-format msgid "zeroing unused portion of %s superblock (AG #%u)\n" msgstr "" #: .././repair/agheader.c:272 .././repair/agheader.c:278 msgid "primary" msgstr "" #: .././repair/agheader.c:272 .././repair/agheader.c:278 msgid "secondary" msgstr "" #: .././repair/agheader.c:277 #, c-format msgid "would zero unused portion of %s superblock (AG #%u)\n" msgstr "" #: .././repair/agheader.c:296 #, c-format msgid "bad flags field in superblock %d\n" msgstr "" #: .././repair/agheader.c:313 #, c-format msgid "non-null user quota inode field in superblock %d\n" msgstr "" #: .././repair/agheader.c:326 #, c-format msgid "non-null group quota inode field in superblock %d\n" msgstr "" #: .././repair/agheader.c:338 #, c-format msgid "non-null quota flags in superblock %d\n" msgstr "" #: .././repair/agheader.c:356 #, c-format msgid "bad shared version number in superblock %d\n" msgstr "" #: .././repair/agheader.c:368 #, c-format msgid "bad inode alignment field in superblock %d\n" msgstr "" #: .././repair/agheader.c:381 #, c-format msgid "bad stripe unit/width fields in superblock %d\n" msgstr "" #: .././repair/agheader.c:399 #, c-format msgid "bad log/data device sector size fields in superblock %d\n" msgstr "" #: .././repair/agheader.c:430 #, c-format msgid "bad on-disk superblock %d - %s\n" msgstr "" #: .././repair/agheader.c:437 #, c-format msgid "primary/secondary superblock %d conflict - %s\n" msgstr "" #: .././repair/dir.c:152 #, c-format msgid "invalid inode number % in directory %\n" msgstr "" #: .././repair/dir.c:157 #, c-format msgid "entry in shortform dir % references rt bitmap inode %\n" msgstr "" #: .././repair/dir.c:162 #, c-format msgid "" "entry in shortform dir % references rt summary inode %\n" msgstr "" #: .././repair/dir.c:167 #, c-format msgid "" "entry in shortform dir % references user quota inode %\n" msgstr "" #: .././repair/dir.c:172 #, c-format msgid "" "entry in shortform dir % references group quota inode %\n" msgstr "" #: .././repair/dir.c:193 #, c-format msgid "" "entry references free inode % in shortform directory %\n" msgstr "" #: .././repair/dir.c:212 #, c-format msgid "" "entry references non-existent inode % in shortform dir %\n" msgstr "" #: .././repair/dir.c:236 .././repair/dir2.c:995 #, c-format msgid "zero length entry in shortform dir %, resetting to %d\n" msgstr "" #: .././repair/dir.c:241 .././repair/dir2.c:1000 #, c-format msgid "zero length entry in shortform dir %, would set to %d\n" msgstr "" #: .././repair/dir.c:246 #, c-format msgid "zero length entry in shortform dir %, " msgstr "" #: .././repair/dir.c:249 .././repair/dir.c:292 .././repair/dir2.c:1051 #, c-format msgid "junking %d entries\n" msgstr "" #: .././repair/dir.c:252 .././repair/dir.c:301 .././repair/dir2.c:1060 #, c-format msgid "would junk %d entries\n" msgstr "" #: .././repair/dir.c:270 .././repair/dir2.c:1029 #, c-format msgid "size of last entry overflows space left in in shortform dir %, " msgstr "" #: .././repair/dir.c:273 .././repair/dir2.c:1032 #, c-format msgid "resetting to %d\n" msgstr "" #: .././repair/dir.c:278 .././repair/dir2.c:1037 #, c-format msgid "would reset to %d\n" msgstr "" #: .././repair/dir.c:283 .././repair/dir2.c:1042 #, c-format msgid "size of entry #%d overflows space left in in shortform dir %\n" msgstr "" #: .././repair/dir.c:288 .././repair/dir2.c:1047 #, c-format msgid "junking entry #%d\n" msgstr "" #: .././repair/dir.c:297 .././repair/dir2.c:1056 #, c-format msgid "would junk entry #%d\n" msgstr "" #: .././repair/dir.c:320 .././repair/dir2.c:1079 #, c-format msgid "entry contains illegal character in shortform dir %\n" msgstr "" #: .././repair/dir.c:374 .././repair/dir2.c:1143 #, c-format msgid "junking entry \"%s\" in directory inode %\n" msgstr "" #: .././repair/dir.c:378 .././repair/dir2.c:1147 #, c-format msgid "would have junked entry \"%s\" in directory inode %\n" msgstr "" #: .././repair/dir.c:404 .././repair/dir2.c:1174 #, c-format msgid "would have corrected entry count in directory % from %d to %d\n" msgstr "" #: .././repair/dir.c:408 .././repair/dir2.c:1178 #, c-format msgid "corrected entry count in directory %, was %d, now %d\n" msgstr "" #: .././repair/dir.c:419 #, c-format msgid "" "would have corrected directory % size from %to %\n" msgstr "" #: .././repair/dir.c:424 .././repair/dir2.c:1212 #, c-format msgid "corrected directory % size, was %, now %\n" msgstr "" #: .././repair/dir.c:446 .././repair/dir2.c:1253 #, c-format msgid "bogus .. inode number (%) in directory inode %, " msgstr "" #: .././repair/dir.c:449 .././repair/dir.c:483 .././repair/dir2.c:1257 #: .././repair/dir2.c:1292 msgid "clearing inode number\n" msgstr "" #: .././repair/dir.c:455 .././repair/dir.c:489 .././repair/dir2.c:1263 #: .././repair/dir2.c:1298 msgid "would clear inode number\n" msgstr "" #: .././repair/dir.c:463 .././repair/dir2.c:1271 #, c-format msgid "" "corrected root directory % .. entry, was %, now %\n" msgstr "" #: .././repair/dir.c:471 .././repair/dir2.c:1279 #, c-format msgid "" "would have corrected root directory % .. entry from % to %" "\n" msgstr "" #: .././repair/dir.c:480 #, c-format msgid "bad .. entry in dir ino %, points to self, " msgstr "" #: .././repair/dir.c:524 #, c-format msgid "bad range claimed [%d, %d) in da block\n" msgstr "" #: .././repair/dir.c:531 #, c-format msgid "byte range end [%d %d) in da block larger than blocksize %d\n" msgstr "" #: .././repair/dir.c:538 #, c-format msgid "multiply claimed byte %d in da block\n" msgstr "" #: .././repair/dir.c:568 #, c-format msgid "hole (start %d, len %d) out of range, block %d, dir ino %\n" msgstr "" #: .././repair/dir.c:579 #, c-format msgid "hole claims used byte %d, block %d, dir ino %\n" msgstr "" #: .././repair/dir.c:693 #, c-format msgid "- derived hole value %d, saw %d, block %d, dir ino %\n" msgstr "" #: .././repair/dir.c:712 #, c-format msgid "" "- derived hole (base %d, size %d) in block %d, dir inode % not " "found\n" msgstr "" #: .././repair/dir.c:767 .././repair/phase6.c:1214 .././repair/phase6.c:1583 #, c-format msgid "can't read block %u (fsbno %) for directory inode %\n" msgstr "" #: .././repair/dir.c:771 #, c-format msgid "" "can't read block %u (fsbno %) for attrbute fork of inode %\n" msgstr "" #: .././repair/dir.c:779 .././repair/phase6.c:1224 #, c-format msgid "" "bad dir/attr magic number in inode %, file bno = %u, fsbno = %" "\n" msgstr "" #: .././repair/dir.c:787 .././repair/dir2.c:333 #, c-format msgid "bad record count in inode %, count = %d, max = %d\n" msgstr "" #: .././repair/dir.c:806 .././repair/dir2.c:356 #, c-format msgid "bad directory btree for directory inode %\n" msgstr "" #: .././repair/dir.c:810 #, c-format msgid "bad attribute fork btree for inode %\n" msgstr "" #: .././repair/dir.c:864 #, c-format msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "" #: .././repair/dir.c:931 #, c-format msgid "directory/attribute block used/count inconsistency - %d/%hu\n" msgstr "" #: .././repair/dir.c:941 .././repair/dir2.c:478 #, c-format msgid "" "directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" msgstr "" #: .././repair/dir.c:948 .././repair/dir2.c:485 #, c-format msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" msgstr "" #: .././repair/dir.c:954 #, c-format msgid "bad directory block in dir ino %\n" msgstr "" #: .././repair/dir.c:984 #, c-format msgid "" "correcting bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir.c:992 #, c-format msgid "" "would correct bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir.c:1130 .././repair/dir2.c:652 #, c-format msgid "can't get map info for block %u of directory inode %\n" msgstr "" #: .././repair/dir.c:1140 #, c-format msgid "can't read block %u (%) for directory inode %\n" msgstr "" #: .././repair/dir.c:1153 #, c-format msgid "" "bad magic number %x in block %u (%) for directory inode %\n" msgstr "" #: .././repair/dir.c:1161 #, c-format msgid "" "bad back pointer in block %u (%) for directory inode %\n" msgstr "" #: .././repair/dir.c:1167 #, c-format msgid "" "entry count %d too large in block %u (%) for directory inode %" "\n" msgstr "" #: .././repair/dir.c:1174 #, c-format msgid "bad level %d in block %u (%) for directory inode %\n" msgstr "" #: .././repair/dir.c:1231 #, c-format msgid "" "correcting bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir.c:1239 #, c-format msgid "" "would correct bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir.c:1347 #, c-format msgid "" "directory block header conflicts with used space in directory inode %" "\n" msgstr "" #: .././repair/dir.c:1377 #, c-format msgid "" "nameidx %d for entry #%d, bno %d, ino % > fs blocksize, deleting " "entry\n" msgstr "" #: .././repair/dir.c:1414 #, c-format msgid "" "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, marking entry " "bad\n" msgstr "" #: .././repair/dir.c:1429 #, c-format msgid "" "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, would delete " "entry\n" msgstr "" #: .././repair/dir.c:1466 #, c-format msgid "invalid ino number % in dir ino %, entry #%d, bno %d\n" msgstr "" #: .././repair/dir.c:1470 .././repair/dir.c:1486 .././repair/dir.c:1503 #: .././repair/dir.c:1519 .././repair/dir.c:1536 #, c-format msgid "\tclearing ino number in entry %d...\n" msgstr "" #: .././repair/dir.c:1477 .././repair/dir.c:1494 .././repair/dir.c:1510 #: .././repair/dir.c:1527 .././repair/dir.c:1544 #, c-format msgid "\twould clear ino number in entry %d...\n" msgstr "" #: .././repair/dir.c:1482 #, c-format msgid "" "entry #%d, bno %d in directory % references realtime bitmap inode %" "\n" msgstr "" #: .././repair/dir.c:1499 #, c-format msgid "" "entry #%d, bno %d in directory % references realtime summary inode %" "\n" msgstr "" #: .././repair/dir.c:1515 #, c-format msgid "" "entry #%d, bno %d in directory % references user quota inode %" "\n" msgstr "" #: .././repair/dir.c:1532 #, c-format msgid "" "entry #%d, bno %d in directory % references group quota inode %" "\n" msgstr "" #: .././repair/dir.c:1569 #, c-format msgid "" "entry references free inode % in directory %, will clear " "entry\n" msgstr "" #: .././repair/dir.c:1577 #, c-format msgid "" "entry references free inode % in directory %, would clear " "entry\n" msgstr "" #: .././repair/dir.c:1585 #, c-format msgid "bad ino number % in dir ino %, entry #%d, bno %d\n" msgstr "" #: .././repair/dir.c:1588 msgid "clearing inode number...\n" msgstr "" #: .././repair/dir.c:1593 msgid "would clear inode number...\n" msgstr "" #: .././repair/dir.c:1613 #, c-format msgid "entry #%d, dir inode %, has zero-len name, deleting entry\n" msgstr "" #: .././repair/dir.c:1651 #, c-format msgid "entry #%d, dir inode %, has zero-len name, marking entry bad\n" msgstr "" #: .././repair/dir.c:1664 #, c-format msgid "" "bad size, entry #%d in dir inode %, block %u -- entry overflows " "block\n" msgstr "" #: .././repair/dir.c:1675 #, c-format msgid "" "dir entry slot %d in block %u conflicts with used space in dir inode %" "\n" msgstr "" #: .././repair/dir.c:1715 #, c-format msgid "" "illegal name \"%s\" in directory inode %, entry will be cleared\n" msgstr "" #: .././repair/dir.c:1721 #, c-format msgid "" "illegal name \"%s\" in directory inode %, entry would be cleared\n" msgstr "" #: .././repair/dir.c:1731 #, c-format msgid "\tmismatched hash value for entry \"%s\"\n" msgstr "" #: .././repair/dir.c:1735 #, c-format msgid "\t\tin directory inode %. resetting hash value.\n" msgstr "" #: .././repair/dir.c:1741 #, c-format msgid "\t\tin directory inode %. would reset hash value.\n" msgstr "" #: .././repair/dir.c:1771 #, c-format msgid "\tbad hash ordering for entry \"%s\"\n" msgstr "" #: .././repair/dir.c:1775 #, c-format msgid "\t\tin directory inode %. will clear entry\n" msgstr "" #: .././repair/dir.c:1782 #, c-format msgid "\t\tin directory inode %. would clear entry\n" msgstr "" #: .././repair/dir.c:1798 #, c-format msgid "" "name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %" "\n" msgstr "" #: .././repair/dir.c:1805 #, c-format msgid "will clear entry \"%s\" (#%d) in directory inode %\n" msgstr "" #: .././repair/dir.c:1809 #, c-format msgid "would clear entry \"%s\" (#%d)in directory inode %\n" msgstr "" #: .././repair/dir.c:1845 #, c-format msgid "bad .. entry in dir ino %, points to self" msgstr "" #: .././repair/dir.c:1849 .././repair/dir.c:1946 msgid "will clear entry\n" msgstr "" #: .././repair/dir.c:1854 .././repair/dir.c:1950 .././repair/dir2.c:1642 msgid "would clear entry\n" msgstr "" #: .././repair/dir.c:1864 #, c-format msgid "correcting .. entry in root inode %, was %\n" msgstr "" #: .././repair/dir.c:1871 #, c-format msgid "bad .. entry (%) in root inode % should be %\n" msgstr "" #: .././repair/dir.c:1888 #, c-format msgid "" "multiple .. entries in directory inode %, will clear second entry\n" msgstr "" #: .././repair/dir.c:1894 #, c-format msgid "" "multiple .. entries in directory inode %, would clear second entry\n" msgstr "" #: .././repair/dir.c:1907 #, c-format msgid "" ". in directory inode % has wrong value (%), fixing entry...\n" msgstr "" #: .././repair/dir.c:1914 #, c-format msgid ". in directory inode % has wrong value (%)\n" msgstr "" #: .././repair/dir.c:1920 #, c-format msgid "multiple . entries in directory inode %\n" msgstr "" #: .././repair/dir.c:1927 #, c-format msgid "will clear one . entry in directory inode %\n" msgstr "" #: .././repair/dir.c:1933 #, c-format msgid "would clear one . entry in directory inode %\n" msgstr "" #: .././repair/dir.c:1943 #, c-format msgid "entry \"%s\" in directory inode % points to self, " msgstr "" #: .././repair/dir.c:1968 #, c-format msgid "" "- resetting first used heap value from %d to %d in block %u of dir ino %" "\n" msgstr "" #: .././repair/dir.c:1976 #, c-format msgid "" "- would reset first used value from %d to %d in block %u of dir ino %" "\n" msgstr "" #: .././repair/dir.c:1986 #, c-format msgid "" "- resetting namebytes cnt from %d to %d in block %u of dir inode %\n" msgstr "" #: .././repair/dir.c:1994 #, c-format msgid "" "- would reset namebytes cnt from %d to %d in block %u of dir inode %" "\n" msgstr "" #: .././repair/dir.c:2029 #, c-format msgid "- found unexpected lost holes in block %u, dir inode %\n" msgstr "" #: .././repair/dir.c:2037 #, c-format msgid "- hole info non-optimal in block %u, dir inode %\n" msgstr "" #: .././repair/dir.c:2044 #, c-format msgid "- hole info incorrect in block %u, dir inode %\n" msgstr "" #: .././repair/dir.c:2055 #, c-format msgid "" "- existing hole info for block %d, dir inode % (base, size) - \n" msgstr "" #: .././repair/dir.c:2063 #, c-format msgid "- holes flag = %d\n" msgstr "" #: .././repair/dir.c:2069 #, c-format msgid "- compacting block %u in dir inode %\n" msgstr "" #: .././repair/dir.c:2110 #, c-format msgid "not enough space in block %u of dir inode % for all entries\n" msgstr "" #: .././repair/dir.c:2180 #, c-format msgid "- would compact block %u in dir inode %\n" msgstr "" #: .././repair/dir.c:2245 .././repair/dir2.c:1828 #, c-format msgid "can't map block %u for directory inode %\n" msgstr "" #: .././repair/dir.c:2256 #, c-format msgid "" "can't read file block %u (fsbno %, daddr %) for directory " "inode %\n" msgstr "" #: .././repair/dir.c:2270 .././repair/dir.c:2529 #, c-format msgid "bad directory leaf magic # %#x for dir ino %\n" msgstr "" #: .././repair/dir.c:2310 #, c-format msgid "" "bad sibling back pointer for directory block %u in directory inode %" "\n" msgstr "" #: .././repair/dir.c:2341 .././repair/dir2.c:1904 #, c-format msgid "bad hash path in directory %\n" msgstr "" #: .././repair/dir.c:2450 #, c-format msgid "out of range internal directory block numbers (inode %)\n" msgstr "" #: .././repair/dir.c:2456 #, c-format msgid "" "setting directory inode (%) size to % bytes, was % " "bytes\n" msgstr "" #: .././repair/dir.c:2509 #, c-format msgid "block 0 for directory inode % is missing\n" msgstr "" #: .././repair/dir.c:2516 #, c-format msgid "can't read block 0 for directory inode %\n" msgstr "" #: .././repair/dir.c:2552 #, c-format msgid "clearing forw/back pointers for directory inode %\n" msgstr "" #: .././repair/dir.c:2558 #, c-format msgid "would clear forw/back pointers for directory inode %\n" msgstr "" #: .././repair/dir.c:2623 .././repair/dir2.c:2113 #, c-format msgid "no . entry for directory %\n" msgstr "" #: .././repair/dir.c:2632 .././repair/dir2.c:2123 #, c-format msgid "no .. entry for directory %\n" msgstr "" #: .././repair/dir.c:2634 .././repair/dir2.c:2125 #, c-format msgid "no .. entry for root directory %\n" msgstr "" #: .././repair/phase1.c:28 msgid "Sorry, could not find valid secondary superblock\n" msgstr "" #: .././repair/phase1.c:29 msgid "Exiting now.\n" msgstr "" #: .././repair/phase1.c:40 #, c-format msgid "could not allocate ag header buffer (%d bytes)\n" msgstr "" #: .././repair/phase1.c:58 msgid "Phase 1 - find and verify superblock...\n" msgstr "" #: .././repair/phase1.c:74 msgid "error reading primary superblock\n" msgstr "" #: .././repair/phase1.c:80 #, c-format msgid "bad primary superblock - %s !!!\n" msgstr "" #: .././repair/phase1.c:87 #, c-format msgid "couldn't verify primary superblock - %s !!!\n" msgstr "" #: .././repair/phase1.c:105 msgid "superblock has a features2 mismatch, correcting\n" msgstr "" #: .././repair/phase1.c:122 #, c-format msgid "Enabling lazy-counters\n" msgstr "" #: .././repair/phase1.c:127 #, c-format msgid "Disabling lazy-counters\n" msgstr "" #: .././repair/phase1.c:130 #, c-format msgid "Lazy-counters are already %s\n" msgstr "" #: .././repair/phase1.c:131 msgid "enabled" msgstr "" #: .././repair/phase1.c:131 msgid "disabled" msgstr "" #: .././repair/phase1.c:138 msgid "writing modified primary superblock\n" msgstr "" #: .././repair/phase1.c:141 msgid "would write modified primary superblock\n" msgstr "" #: .././repair/scan.c:90 .././repair/scan.c:135 #, c-format msgid "can't read btree block %d/%d\n" msgstr "" #: .././repair/scan.c:197 #, c-format msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" msgstr "" #: .././repair/scan.c:203 #, c-format msgid "" "expected level %d got %d in inode %, (%s fork) bmbt block %\n" msgstr "" #: .././repair/scan.c:223 #, c-format msgid "" "bad fwd (right) sibling pointer (saw % parent block says %)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" #: .././repair/scan.c:233 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu parent block says %)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" #: .././repair/scan.c:248 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu should be NULL (0))\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" #: .././repair/scan.c:289 #, c-format msgid "inode 0x%bmap block 0x% claimed, state is %d\n" msgstr "" #: .././repair/scan.c:296 #, c-format msgid "inode 0x% bmap block 0x% claimed, state is %d\n" msgstr "" #: .././repair/scan.c:311 #, c-format msgid "bad state %d, inode % bmap block 0x%\n" msgstr "" #: .././repair/scan.c:338 .././repair/scan.c:389 #, c-format msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" msgstr "" #: .././repair/scan.c:368 #, c-format msgid "" "out-of-order bmap key (file offset) in inode %, %s fork, fsbno %" "\n" msgstr "" #: .././repair/scan.c:406 .././repair/dinode.c:1187 #, c-format msgid "bad bmap btree ptr 0x%llx in ino %\n" msgstr "" #: .././repair/scan.c:433 #, c-format msgid "" "correcting bt key (was %llu, now %) in inode %\n" "\t\t%s fork, btree block %\n" msgstr "" #: .././repair/scan.c:445 #, c-format msgid "" "bad btree key (is %llu, should be %) in inode %\n" "\t\t%s fork, btree block %\n" msgstr "" #: .././repair/scan.c:463 #, c-format msgid "" "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" #: .././repair/scan.c:537 #, c-format msgid "bad magic # %#x in bt%s block %d/%d\n" msgstr "" #: .././repair/scan.c:555 #, c-format msgid "expected level %d got %d in bt%s block %d/%d\n" msgstr "" #: .././repair/scan.c:569 #, c-format msgid "" "%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" #: .././repair/scan.c:589 .././repair/scan.c:688 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" msgstr "" #: .././repair/scan.c:607 #, c-format msgid "invalid start block %u in record %u of %s btree block %u/%u\n" msgstr "" #: .././repair/scan.c:613 #, c-format msgid "invalid length %u in record %u of %s btree block %u/%u\n" msgstr "" #: .././repair/scan.c:658 #, c-format msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" msgstr "" #: .././repair/scan.c:755 #, c-format msgid "badly aligned inode rec (starting inode = %)\n" msgstr "" #: .././repair/scan.c:771 #, c-format msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" msgstr "" #: .././repair/scan.c:779 #, c-format msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" msgstr "" #: .././repair/scan.c:804 #, c-format msgid "" "inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" msgstr "" #: .././repair/scan.c:826 #, c-format msgid "" "inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" msgstr "" #: .././repair/scan.c:873 #, c-format msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" msgstr "" #: .././repair/scan.c:919 #, c-format msgid "bad magic # %#x in inobt block %d/%d\n" msgstr "" #: .././repair/scan.c:927 #, c-format msgid "expected level %d got %d in inobt block %d/%d\n" msgstr "" #: .././repair/scan.c:949 #, c-format msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" #: .././repair/scan.c:972 #, c-format msgid "dubious inode btree block header %d/%d\n" msgstr "" #: .././repair/scan.c:1065 #, c-format msgid "can't read agfl block for ag %d\n" msgstr "" #: .././repair/scan.c:1076 #, c-format msgid "bad agbno %u in agfl, agno %d\n" msgstr "" #: .././repair/scan.c:1085 #, c-format msgid "freeblk count %d != flcount %d in ag %d\n" msgstr "" #: .././repair/scan.c:1107 #, c-format msgid "bad agbno %u for btbno root, agno %d\n" msgstr "" #: .././repair/scan.c:1116 #, c-format msgid "bad agbno %u for btbcnt root, agno %d\n" msgstr "" #: .././repair/scan.c:1132 #, c-format msgid "agf_btreeblks %u, counted % in ag %u\n" msgstr "" #: .././repair/scan.c:1151 #, c-format msgid "bad agbno %u for inobt root, agno %d\n" msgstr "" #: .././repair/scan.c:1170 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" msgstr "" #: .././repair/scan.c:1201 #, c-format msgid "can't get root superblock for ag %d\n" msgstr "" #: .././repair/scan.c:1207 msgid "can't allocate memory for superblock\n" msgstr "" #: .././repair/scan.c:1217 #, c-format msgid "can't read agf block for ag %d\n" msgstr "" #: .././repair/scan.c:1228 #, c-format msgid "can't read agi block for ag %d\n" msgstr "" #: .././repair/scan.c:1252 #, c-format msgid "reset bad sb for ag %d\n" msgstr "" #: .././repair/scan.c:1255 #, c-format msgid "would reset bad sb for ag %d\n" msgstr "" #: .././repair/scan.c:1260 #, c-format msgid "reset bad agf for ag %d\n" msgstr "" #: .././repair/scan.c:1263 #, c-format msgid "would reset bad agf for ag %d\n" msgstr "" #: .././repair/scan.c:1268 #, c-format msgid "reset bad agi for ag %d\n" msgstr "" #: .././repair/scan.c:1271 #, c-format msgid "would reset bad agi for ag %d\n" msgstr "" #: .././repair/scan.c:1281 #, c-format msgid "bad uncorrected agheader %d, skipping ag...\n" msgstr "" #: .././repair/scan.c:1340 msgid "no memory for ag header counts\n" msgstr "" #: .././repair/scan.c:1363 #, c-format msgid "sb_icount %, counted %\n" msgstr "" #: .././repair/scan.c:1368 #, c-format msgid "sb_ifree %, counted %\n" msgstr "" #: .././repair/scan.c:1373 #, c-format msgid "sb_fdblocks %, counted %\n" msgstr "" #: .././repair/threads.c:90 #, c-format msgid "cannot create worker threads, error = [%d] %s\n" msgstr "" #: .././repair/threads.c:108 #, c-format msgid "cannot allocate worker item, error = [%d] %s\n" msgstr "" #: .././repair/versions.c:73 #, c-format msgid "bogus quota flags 0x%x set in superblock" msgstr "" #: .././repair/versions.c:86 msgid ", bogus flags will be cleared\n" msgstr "" #: .././repair/versions.c:88 msgid ", bogus flags would be cleared\n" msgstr "" #: .././repair/versions.c:141 msgid "This filesystem has uninitialized extent flags.\n" msgstr "" #: .././repair/versions.c:149 msgid "This filesystem is marked shared.\n" msgstr "" #: .././repair/versions.c:155 msgid "" "This filesystem uses feature(s) not yet supported in this release.\n" "Please run a more recent version of xfs_repair.\n" msgstr "" #: .././repair/versions.c:161 #, c-format msgid "WARNING: unknown superblock version %d\n" msgstr "" #: .././repair/versions.c:164 msgid "This filesystem contains features not understood by this program.\n" msgstr "" #: .././repair/versions.c:172 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twill be downgraded. This may cause loss of filesystem meta-data\n" msgstr "" #: .././repair/versions.c:177 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twould be downgraded. This might cause loss of filesystem\n" "\tmeta-data.\n" msgstr "" #: .././repair/versions.c:191 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attributes will be removed.\n" msgstr "" #: .././repair/versions.c:196 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attributes would be removed.\n" msgstr "" #: .././repair/versions.c:209 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attr2 attributes will be removed.\n" msgstr "" #: .././repair/versions.c:214 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attr2 attributes would be removed.\n" msgstr "" #: .././repair/versions.c:227 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem will be downgraded and\n" "\tall version 2 inodes will be converted to version 1 inodes.\n" "\tThis may cause some hard links to files to be destroyed\n" msgstr "" #: .././repair/versions.c:233 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem would be downgraded and\n" "\tall version 2 inodes would be converted to version 1 inodes.\n" "\tThis might cause some hard links to files to be destroyed\n" msgstr "" #: .././repair/versions.c:247 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem will be downgraded and\n" "\tall quota information will be removed.\n" msgstr "" #: .././repair/versions.c:252 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem would be downgraded and\n" "\tall quota information would be removed.\n" msgstr "" #: .././repair/versions.c:276 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem will be downgraded.\n" "\tThis will permanently degrade the performance of this filesystem.\n" msgstr "" #: .././repair/versions.c:281 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem would be downgraded.\n" "\tThis would permanently degrade the performance of this filesystem.\n" msgstr "" #: .././repair/avl.c:1011 .././repair/avl64.c:1032 #, c-format msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" msgstr "" #: .././repair/avl.c:1206 .././repair/avl64.c:1227 #, c-format msgid "Command [fpdir] : " msgstr "" #: .././repair/avl.c:1215 .././repair/avl64.c:1236 #, c-format msgid "end of range ? " msgstr "" #: .././repair/avl.c:1226 .././repair/avl64.c:1247 #, c-format msgid "Cannot find %d\n" msgstr "" #: .././repair/avl.c:1239 .././repair/avl64.c:1260 #, c-format msgid "size of range ? " msgstr "" #: .././repair/avl.c:1250 .././repair/avl64.c:1271 #, c-format msgid "End of range ? " msgstr "" #: .././repair/avl.c:1254 .././repair/avl64.c:1275 #, c-format msgid "checklen 0/1 ? " msgstr "" #: .././repair/avl.c:1261 .././repair/avl64.c:1282 #, c-format msgid "Found something\n" msgstr "" #: .././repair/phase5.c:211 msgid "could not set up btree block array\n" msgstr "" #: .././repair/phase5.c:223 msgid "error - not enough free space in filesystem\n" msgstr "" #: .././repair/phase5.c:438 #, c-format msgid "can't rebuild fs trees -- not enough free space on ag %u\n" msgstr "" #: .././repair/phase5.c:462 #, c-format msgid "ag %u - not enough free space to build freespace btrees\n" msgstr "" #: .././repair/phase5.c:497 #, c-format msgid "not enough free blocks left to describe all free blocks in AG %u\n" msgstr "" #: .././repair/phase5.c:1310 #, c-format msgid "lost %d blocks in ag %u\n" msgstr "" #: .././repair/phase5.c:1313 #, c-format msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" msgstr "" #: .././repair/phase5.c:1360 .././repair/xfs_repair.c:849 msgid "couldn't get superblock\n" msgstr "" #: .././repair/phase5.c:1409 .././repair/phase6.c:3624 #: .././repair/phase4.c:125 .././repair/phase3.c:76 #, c-format msgid " - agno = %d\n" msgstr "" #: .././repair/phase5.c:1432 #, c-format msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" msgstr "" #: .././repair/phase5.c:1467 #, c-format msgid "unable to rebuild AG %u. No free space.\n" msgstr "" #: .././repair/phase5.c:1494 #, c-format msgid "lost %d blocks in agno %d, sorry.\n" msgstr "" #: .././repair/phase5.c:1563 msgid "Phase 5 - rebuild AG headers and trees...\n" msgstr "" #: .././repair/phase5.c:1593 msgid "cannot alloc sb_icount_ag buffers\n" msgstr "" #: .././repair/phase5.c:1597 msgid "cannot alloc sb_ifree_ag buffers\n" msgstr "" #: .././repair/phase5.c:1601 msgid "cannot alloc sb_fdblocks_ag buffers\n" msgstr "" #: .././repair/phase5.c:1620 msgid " - generate realtime summary info and bitmap...\n" msgstr "" #: .././repair/phase5.c:1625 msgid " - reset superblock...\n" msgstr "" #: .././repair/attr_repair.c:105 msgid "" "entry contains illegal value in attribute named SGI_ACL_FILE or " "SGI_ACL_DEFAULT\n" msgstr "" #: .././repair/attr_repair.c:127 msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" msgstr "" #: .././repair/attr_repair.c:133 msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" msgstr "" #: .././repair/attr_repair.c:172 #, c-format msgid "there are no attributes in the fork for inode %\n" msgstr "" #: .././repair/attr_repair.c:180 #, c-format msgid "would junk the attribute fork since count is 0 for inode %\n" msgstr "" #: .././repair/attr_repair.c:200 msgid "zero length name entry in attribute fork," msgstr "" #: .././repair/attr_repair.c:203 .././repair/attr_repair.c:223 #, c-format msgid " truncating attributes for inode % to %d\n" msgstr "" #: .././repair/attr_repair.c:208 .././repair/attr_repair.c:229 #, c-format msgid " would truncate attributes for inode % to %d\n" msgstr "" #: .././repair/attr_repair.c:220 msgid "name or value attribute lengths are too large,\n" msgstr "" #: .././repair/attr_repair.c:242 msgid "entry contains illegal character in shortform attribute name\n" msgstr "" #: .././repair/attr_repair.c:248 msgid "entry has INCOMPLETE flag on in shortform attribute\n" msgstr "" #: .././repair/attr_repair.c:265 #, c-format msgid "removing attribute entry %d for inode %\n" msgstr "" #: .././repair/attr_repair.c:277 #, c-format msgid "would remove attribute entry %d for inode %\n" msgstr "" #: .././repair/attr_repair.c:292 #, c-format msgid "" "would have corrected attribute entry count in inode % from %d to %d\n" msgstr "" #: .././repair/attr_repair.c:296 #, c-format msgid "corrected attribute entry count in inode %, was %d, now %d\n" msgstr "" #: .././repair/attr_repair.c:307 #, c-format msgid "" "would have corrected attribute totsize in inode % from %d to %d\n" msgstr "" #: .././repair/attr_repair.c:312 #, c-format msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" msgstr "" #: .././repair/attr_repair.c:342 #, c-format msgid "remote block for attributes of inode % is missing\n" msgstr "" #: .././repair/attr_repair.c:350 #, c-format msgid "can't read remote block for attributes of inode %\n" msgstr "" #: .././repair/attr_repair.c:388 #, c-format msgid "" "attribute entry %d in attr block %u, inode % has bad name (namelen = " "%d)\n" msgstr "" #: .././repair/attr_repair.c:405 #, c-format msgid "" "bad hashvalue for attribute entry %d in attr block %u, inode %\n" msgstr "" #: .././repair/attr_repair.c:415 #, c-format msgid "" "bad security value for attribute entry %d in attr block %u, inode %\n" msgstr "" #: .././repair/attr_repair.c:448 #, c-format msgid "" "inconsistent remote attribute entry %d in attr block %u, ino %\n" msgstr "" #: .././repair/attr_repair.c:458 #, c-format msgid "cannot malloc enough for remotevalue attribute for inode %\n" msgstr "" #: .././repair/attr_repair.c:460 msgid "SKIPPING this remote attribute\n" msgstr "" #: .././repair/attr_repair.c:466 #, c-format msgid "remote attribute get failed for entry %d, inode %\n" msgstr "" #: .././repair/attr_repair.c:473 #, c-format msgid "remote attribute value check failed for entry %d, inode %\n" msgstr "" #: .././repair/attr_repair.c:510 #, c-format msgid "bad attribute count %d in attr block %u, inode %\n" msgstr "" #: .././repair/attr_repair.c:525 #, c-format msgid "bad attribute nameidx %d in attr block %u, inode %\n" msgstr "" #: .././repair/attr_repair.c:534 #, c-format msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" msgstr "" #: .././repair/attr_repair.c:545 #, c-format msgid "" "attribute entry %d in attr block %u, inode % claims already used " "space\n" msgstr "" #: .././repair/attr_repair.c:568 #, c-format msgid "" "attribute entry %d in attr block %u, inode % claims used space\n" msgstr "" #: .././repair/attr_repair.c:592 #, c-format msgid "" "- resetting first used heap value from %d to %d in block %u of attribute " "fork of inode %\n" msgstr "" #: .././repair/attr_repair.c:600 #, c-format msgid "" "- would reset first used value from %d to %d in block %u of attribute fork " "of inode %\n" msgstr "" #: .././repair/attr_repair.c:610 #, c-format msgid "" "- resetting usedbytes cnt from %d to %d in block %u of attribute fork of " "inode %\n" msgstr "" #: .././repair/attr_repair.c:618 #, c-format msgid "" "- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %" "\n" msgstr "" #: .././repair/attr_repair.c:670 #, c-format msgid "can't map block %u for attribute fork for inode %\n" msgstr "" #: .././repair/attr_repair.c:679 #, c-format msgid "" "can't read file block %u (fsbno %) for attribute fork of inode %" "\n" msgstr "" #: .././repair/attr_repair.c:689 #, c-format msgid "bad attribute leaf magic %#x for inode %\n" msgstr "" #: .././repair/attr_repair.c:720 #, c-format msgid "" "bad sibling back pointer for block %u in attribute fork for inode %\n" msgstr "" #: .././repair/attr_repair.c:747 #, c-format msgid "bad hash path in attribute fork for inode %\n" msgstr "" #: .././repair/attr_repair.c:846 #, c-format msgid "block 0 of inode % attribute fork is missing\n" msgstr "" #: .././repair/attr_repair.c:853 #, c-format msgid "agno of attribute fork of inode % out of regular partition\n" msgstr "" #: .././repair/attr_repair.c:861 #, c-format msgid "can't read block 0 of inode % attribute fork\n" msgstr "" #: .././repair/attr_repair.c:876 #, c-format msgid "" "clearing forw/back pointers in block 0 for attributes in inode %\n" msgstr "" #: .././repair/attr_repair.c:883 #, c-format msgid "" "would clear forw/back pointers in block 0 for attributes in inode %\n" msgstr "" #: .././repair/attr_repair.c:913 #, c-format msgid "bad attribute leaf magic # %#x for dir ino %\n" msgstr "" #: .././repair/attr_repair.c:938 #, c-format msgid "Too many ACL entries, count %d\n" msgstr "" #: .././repair/attr_repair.c:947 msgid "cannot malloc enough for ACL attribute\n" msgstr "" #: .././repair/attr_repair.c:948 msgid "SKIPPING this ACL\n" msgstr "" #: .././repair/attr_repair.c:994 .././repair/dinode.c:2182 #, c-format msgid "illegal attribute format %d, ino %\n" msgstr "" #: .././repair/dino_chunks.c:58 #, c-format msgid "cannot read agbno (%u/%u), disk block %\n" msgstr "" #: .././repair/dino_chunks.c:149 #, c-format msgid "uncertain inode block %d/%d already known\n" msgstr "" #: .././repair/dino_chunks.c:165 .././repair/dino_chunks.c:437 #: .././repair/dino_chunks.c:496 #, c-format msgid "inode block %d/%d multiply claimed, (state %d)\n" msgstr "" #: .././repair/dino_chunks.c:172 .././repair/dino_chunks.c:501 #, c-format msgid "inode block %d/%d bad state, (state %d)\n" msgstr "" #: .././repair/dino_chunks.c:444 #, c-format msgid "uncertain inode block overlap, agbno = %d, ino = %\n" msgstr "" #: .././repair/dino_chunks.c:483 #, c-format msgid "uncertain inode block % already known\n" msgstr "" #: .././repair/dino_chunks.c:620 #, c-format msgid "failed to allocate %zd bytes of memory\n" msgstr "" #: .././repair/dino_chunks.c:631 #, c-format msgid "cannot read inode %, disk block %, cnt %d\n" msgstr "" #: .././repair/dino_chunks.c:747 .././repair/dino_chunks.c:922 #, c-format msgid "bad state in block map %d\n" msgstr "" #: .././repair/dino_chunks.c:751 .././repair/dino_chunks.c:928 #, c-format msgid "inode block % multiply claimed, state was %d\n" msgstr "" #: .././repair/dino_chunks.c:788 #, c-format msgid "imap claims in-use inode % is free, " msgstr "" #: .././repair/dino_chunks.c:793 msgid "correcting imap\n" msgstr "" #: .././repair/dino_chunks.c:795 msgid "would correct imap\n" msgstr "" #: .././repair/dino_chunks.c:841 #, c-format msgid "cleared root inode %\n" msgstr "" #: .././repair/dino_chunks.c:845 #, c-format msgid "would clear root inode %\n" msgstr "" #: .././repair/dino_chunks.c:853 #, c-format msgid "cleared realtime bitmap inode %\n" msgstr "" #: .././repair/dino_chunks.c:857 #, c-format msgid "would clear realtime bitmap inode %\n" msgstr "" #: .././repair/dino_chunks.c:865 #, c-format msgid "cleared realtime summary inode %\n" msgstr "" #: .././repair/dino_chunks.c:869 #, c-format msgid "would clear realtime summary inode %\n" msgstr "" #: .././repair/dino_chunks.c:873 #, c-format msgid "cleared inode %\n" msgstr "" #: .././repair/dino_chunks.c:876 #, c-format msgid "would have cleared inode %\n" msgstr "" #: .././repair/dino_chunks.c:1083 .././repair/dino_chunks.c:1118 #: .././repair/dino_chunks.c:1232 msgid "found inodes not in the inode allocation tree\n" msgstr "" #: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 msgid "couldn't allocate new extent descriptor.\n" msgstr "" #: .././repair/incore_ext.c:232 msgid "duplicate bno extent range\n" msgstr "" #: .././repair/incore_ext.c:369 msgid ": duplicate bno extent range\n" msgstr "" #: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 msgid "duplicate extent range\n" msgstr "" #: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 msgid "couldn't malloc dup extent tree descriptor table\n" msgstr "" #: .././repair/incore_ext.c:761 msgid "couldn't malloc free by-bno extent tree descriptor table\n" msgstr "" #: .././repair/incore_ext.c:766 msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" msgstr "" #: .././repair/incore_ext.c:772 msgid "couldn't malloc bno extent tree descriptor\n" msgstr "" #: .././repair/incore_ext.c:776 msgid "couldn't malloc bcnt extent tree descriptor\n" msgstr "" #: .././repair/incore_ext.c:787 msgid "couldn't malloc dup rt extent tree descriptor\n" msgstr "" #: .././repair/incore_ino.c:47 msgid "could not allocate nlink array\n" msgstr "" #: .././repair/incore_ino.c:233 msgid "inode map malloc failed\n" msgstr "" #: .././repair/incore_ino.c:340 msgid "add_aginode_uncertain - duplicate inode range\n" msgstr "" #: .././repair/incore_ino.c:435 msgid "add_inode - duplicate inode range\n" msgstr "" #: .././repair/incore_ino.c:529 #, c-format msgid "good inode list is --\n" msgstr "" #: .././repair/incore_ino.c:532 #, c-format msgid "uncertain inode list is --\n" msgstr "" #: .././repair/incore_ino.c:537 #, c-format msgid "agno %d -- no inodes\n" msgstr "" #: .././repair/incore_ino.c:541 #, c-format msgid "agno %d\n" msgstr "" #: .././repair/incore_ino.c:545 #, c-format msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" msgstr "" #: .././repair/incore_ino.c:596 msgid "couldn't malloc parent list table\n" msgstr "" #: .././repair/incore_ino.c:607 .././repair/incore_ino.c:653 msgid "couldn't memalign pentries table\n" msgstr "" #: .././repair/incore_ino.c:711 msgid "could not malloc inode extra data\n" msgstr "" #: .././repair/incore_ino.c:777 msgid "couldn't malloc inode tree descriptor table\n" msgstr "" #: .././repair/incore_ino.c:781 msgid "couldn't malloc uncertain ino tree descriptor table\n" msgstr "" #: .././repair/incore_ino.c:786 msgid "couldn't malloc inode tree descriptor\n" msgstr "" #: .././repair/incore_ino.c:790 msgid "couldn't malloc uncertain ino tree descriptor\n" msgstr "" #: .././repair/incore_ino.c:798 msgid "couldn't malloc uncertain inode cache area\n" msgstr "" #: .././repair/phase6.c:63 #, c-format msgid "malloc failed add_dotdot_update (%zu bytes)\n" msgstr "" #: .././repair/phase6.c:174 #, c-format msgid "malloc failed in dir_hash_add (%zu bytes)\n" msgstr "" #: .././repair/phase6.c:228 msgid "ok" msgstr "" #: .././repair/phase6.c:229 msgid "duplicate leaf" msgstr "" #: .././repair/phase6.c:230 msgid "hash value mismatch" msgstr "" #: .././repair/phase6.c:231 msgid "no data entry" msgstr "" #: .././repair/phase6.c:232 msgid "no leaf entry" msgstr "" #: .././repair/phase6.c:233 msgid "bad stale count" msgstr "" #: .././repair/phase6.c:241 #, c-format msgid "bad hash table for directory inode % (%s): " msgstr "" #: .././repair/phase6.c:244 msgid "rebuilding\n" msgstr "" #: .././repair/phase6.c:246 msgid "would rebuild\n" msgstr "" #: .././repair/phase6.c:282 msgid "calloc failed in dir_hash_init\n" msgstr "" #: .././repair/phase6.c:412 msgid "ran out of disk space!\n" msgstr "" #: .././repair/phase6.c:414 #, c-format msgid "xfs_trans_reserve returned %d\n" msgstr "" #: .././repair/phase6.c:443 .././repair/phase6.c:536 #, c-format msgid "couldn't iget realtime bitmap inode -- error - %d\n" msgstr "" #: .././repair/phase6.c:493 #, c-format msgid "couldn't allocate realtime bitmap, error = %d\n" msgstr "" #: .././repair/phase6.c:506 #, c-format msgid "allocation of the realtime bitmap failed, error = %d\n" msgstr "" #: .././repair/phase6.c:549 #, c-format msgid "couldn't map realtime bitmap block %, error = %d\n" msgstr "" #: .././repair/phase6.c:562 #, c-format msgid "" "can't access block % (fsbno %) of realtime bitmap inode %" "\n" msgstr "" #: .././repair/phase6.c:605 .././repair/phase6.c:676 #, c-format msgid "couldn't iget realtime summary inode -- error - %d\n" msgstr "" #: .././repair/phase6.c:618 #, c-format msgid "couldn't map realtime summary inode block %, error = %d\n" msgstr "" #: .././repair/phase6.c:631 #, c-format msgid "" "can't access block % (fsbno %) of realtime summary inode %" "\n" msgstr "" #: .././repair/phase6.c:732 #, c-format msgid "couldn't allocate realtime summary inode, error = %d\n" msgstr "" #: .././repair/phase6.c:745 #, c-format msgid "allocation of the realtime summary ino failed, error = %d\n" msgstr "" #: .././repair/phase6.c:775 #, c-format msgid "could not iget root inode -- error - %d\n" msgstr "" #: .././repair/phase6.c:845 #, c-format msgid "%d - couldn't iget root inode to obtain %s\n" msgstr "" #: .././repair/phase6.c:876 #, c-format msgid "%s inode allocation failed %d\n" msgstr "" #: .././repair/phase6.c:907 #, c-format msgid "can't make %s, createname error %d\n" msgstr "" #: .././repair/phase6.c:927 #, c-format msgid "%s directory creation failed -- bmapf error %d\n" msgstr "" #: .././repair/phase6.c:970 #, c-format msgid "%d - couldn't iget orphanage inode\n" msgstr "" #: .././repair/phase6.c:983 #, c-format msgid "%d - couldn't iget disconnected inode\n" msgstr "" #: .././repair/phase6.c:1003 .././repair/phase6.c:1047 #: .././repair/phase6.c:1104 .././repair/phase6.c:1747 #, c-format msgid "space reservation failed (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1014 .././repair/phase6.c:1059 #: .././repair/phase6.c:1115 #, c-format msgid "name create failed in %s (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1027 #, c-format msgid "creation of .. entry failed (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1036 #, c-format msgid "bmap finish failed (err - %d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1078 #, c-format msgid "name replace op failed (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1085 .././repair/phase6.c:1125 #: .././repair/phase6.c:1770 #, c-format msgid "bmap finish failed (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1163 .././repair/phase6.c:1564 msgid "dir" msgstr "" #: .././repair/phase6.c:1172 .././repair/phase6.c:1176 #, c-format msgid "" "can't map block %d in %s inode %, xfs_bmapi returns %d, nmap = %d\n" msgstr "" #: .././repair/phase6.c:1185 .././repair/phase6.c:1189 #: .././repair/phase6.c:1643 .././repair/phase6.c:1647 #, c-format msgid "block %d in %s ino % doesn't exist\n" msgstr "" #: .././repair/phase6.c:1244 .././repair/phase6.c:1248 #, c-format msgid "" "can't map block %d in %s ino %, xfs_bmapi returns %d, nmap = %d\n" msgstr "" #: .././repair/phase6.c:1256 .././repair/phase6.c:1260 #, c-format msgid "block %d in %s inode % doesn't exist\n" msgstr "" #: .././repair/phase6.c:1283 msgid ", marking entry to be junked\n" msgstr "" #: .././repair/phase6.c:1287 msgid ", would junk entry\n" msgstr "" #: .././repair/phase6.c:1404 #, c-format msgid "" "entry \"%s\" in dir inode % points to non-existent inode %" msgstr "" #: .././repair/phase6.c:1422 #, c-format msgid "entry \"%s\" in dir inode % points to free inode %" msgstr "" #: .././repair/phase6.c:1438 .././repair/phase6.c:2105 #: .././repair/phase6.c:2733 .././repair/phase6.c:3063 #, c-format msgid "%s (ino %) in root (%) is not a directory" msgstr "" #: .././repair/phase6.c:1460 .././repair/phase6.c:2126 #: .././repair/phase6.c:2751 .././repair/phase6.c:3081 #, c-format msgid "entry \"%s\" (ino %) in dir % is a duplicate name" msgstr "" #: .././repair/phase6.c:1491 #, c-format msgid "" "entry \"%s\" in dir ino % points to an already connected dir inode %" ",\n" msgstr "" #: .././repair/phase6.c:1500 .././repair/phase6.c:2226 #: .././repair/phase6.c:2785 .././repair/phase6.c:3113 #, c-format msgid "" "entry \"%s\" in dir ino % doesn't have a .. entry, will set it in " "ino %.\n" msgstr "" #: .././repair/phase6.c:1508 #, c-format msgid "" "entry \"%s\" in dir ino % not consistent with .. value (%) " "in ino %,\n" msgstr "" #: .././repair/phase6.c:1522 .././repair/phase6.c:2249 #, c-format msgid "\twill clear entry \"%s\"\n" msgstr "" #: .././repair/phase6.c:1525 .././repair/phase6.c:2252 #, c-format msgid "\twould clear entry \"%s\"\n" msgstr "" #: .././repair/phase6.c:1570 #, c-format msgid "cannot map block 0 of directory inode %\n" msgstr "" #: .././repair/phase6.c:1593 #, c-format msgid "" "bad magic # (0x%x) for dir ino % leaf block (bno %u fsbno %" ")\n" msgstr "" #: .././repair/phase6.c:1630 .././repair/phase6.c:1634 #, c-format msgid "" "can't map leaf block %d in dir %, xfs_bmapi returns %d, nmap = %d\n" msgstr "" #: .././repair/phase6.c:1686 #, c-format msgid "rebuilding directory inode %\n" msgstr "" #: .././repair/phase6.c:1711 #, c-format msgid "xfs_bmap_last_offset failed -- error - %d\n" msgstr "" #: .././repair/phase6.c:1718 #, c-format msgid "xfs_bunmapi failed -- error - %d\n" msgstr "" #: .././repair/phase6.c:1760 #, c-format msgid "" "name create failed in ino % (%d), filesystem may be out of space\n" msgstr "" #: .././repair/phase6.c:1825 #, c-format msgid "shrink_inode failed inode % block %u\n" msgstr "" #: .././repair/phase6.c:1906 #, c-format msgid "realloc failed in longform_dir2_entry_check_data (%zu bytes)\n" msgstr "" #: .././repair/phase6.c:1963 #, c-format msgid "empty data block %u in directory inode %: " msgstr "" #: .././repair/phase6.c:1967 #, c-format msgid "corrupt block %u in directory inode %: " msgstr "" #: .././repair/phase6.c:1971 msgid "junking block\n" msgstr "" #: .././repair/phase6.c:1974 msgid "would junk block\n" msgstr "" #: .././repair/phase6.c:1998 #, c-format msgid "" "bad directory block magic # %#x for directory inode % block %d: " msgstr "" #: .././repair/phase6.c:2001 #, c-format msgid "fixing magic # to %#x\n" msgstr "" #: .././repair/phase6.c:2005 #, c-format msgid "would fix magic # to %#x\n" msgstr "" #: .././repair/phase6.c:2026 #, c-format msgid "directory inode % block %u has consecutive free entries: " msgstr "" #: .././repair/phase6.c:2029 msgid "joining together\n" msgstr "" #: .././repair/phase6.c:2038 msgid "would join together\n" msgstr "" #: .././repair/phase6.c:2070 #, c-format msgid "" "entry \"%s\" in directory inode % points to non-existent inode %" "" msgstr "" #: .././repair/phase6.c:2087 #, c-format msgid "" "entry \"%s\" in directory inode % points to free inode %" msgstr "" #: .././repair/phase6.c:2157 #, c-format msgid "" "entry \"%s\" (ino %) in dir % is not in the the first block" msgstr "" #: .././repair/phase6.c:2182 #, c-format msgid "entry \"%s\" in dir % is not the first entry" msgstr "" #: .././repair/phase6.c:2217 #, c-format msgid "" "entry \"%s\" in dir % points to an already connected directory inode " "%\n" msgstr "" #: .././repair/phase6.c:2236 #, c-format msgid "" "entry \"%s\" in dir inode % inconsistent with .. value (%) " "in ino %\n" msgstr "" #: .././repair/phase6.c:2290 .././repair/dir2.c:305 .././repair/dir2.c:663 #: .././repair/dir2.c:1709 #, c-format msgid "can't read block %u for directory inode %\n" msgstr "" #: .././repair/phase6.c:2307 .././repair/phase6.c:2387 #, c-format msgid "leaf block %u for directory inode % bad header\n" msgstr "" #: .././repair/phase6.c:2326 #, c-format msgid "leaf block %u for directory inode % bad tail\n" msgstr "" #: .././repair/phase6.c:2365 #, c-format msgid "can't read leaf block %u for directory inode %\n" msgstr "" #: .././repair/phase6.c:2377 #, c-format msgid "unknown magic number %#x for block %u in directory inode %\n" msgstr "" #: .././repair/phase6.c:2411 #, c-format msgid "can't read freespace block %u for directory inode %\n" msgstr "" #: .././repair/phase6.c:2424 #, c-format msgid "free block %u for directory inode % bad header\n" msgstr "" #: .././repair/phase6.c:2436 #, c-format msgid "free block %u entry %i for directory ino % bad\n" msgstr "" #: .././repair/phase6.c:2446 #, c-format msgid "free block %u for directory inode % bad nused\n" msgstr "" #: .././repair/phase6.c:2457 #, c-format msgid "missing freetab entry %u for directory inode %\n" msgstr "" #: .././repair/phase6.c:2497 #, c-format msgid "malloc failed in longform_dir2_entry_check (% bytes)\n" msgstr "" #: .././repair/phase6.c:2527 #, c-format msgid "realloc failed in longform_dir2_entry_check (%zu bytes)\n" msgstr "" #: .././repair/phase6.c:2533 #, c-format msgid "can't read data block %u for directory inode %\n" msgstr "" #: .././repair/phase6.c:2639 #, c-format msgid "shortform dir inode % has null data entries \n" msgstr "" #: .././repair/phase6.c:2707 #, c-format msgid "" "entry \"%s\" in shortform dir % references non-existent ino %" "\n" msgstr "" #: .././repair/phase6.c:2720 #, c-format msgid "" "entry \"%s\" in shortform dir inode % points to free inode %" "\n" msgstr "" #: .././repair/phase6.c:2776 #, c-format msgid "" "entry \"%s\" in dir % references already connected dir ino %" ".\n" msgstr "" #: .././repair/phase6.c:2793 #, c-format msgid "" "entry \"%s\" in dir % not consistent with .. value (%) in " "dir ino %.\n" msgstr "" #: .././repair/phase6.c:2833 .././repair/phase6.c:3166 msgid "junking entry\n" msgstr "" #: .././repair/phase6.c:2837 .././repair/phase6.c:3170 msgid "would junk entry\n" msgstr "" #: .././repair/phase6.c:2876 .././repair/phase6.c:3228 #, c-format msgid "setting size to % bytes to reflect junked entries\n" msgstr "" #: .././repair/phase6.c:2928 #, c-format msgid "would set .. in sf dir inode % to %\n" msgstr "" #: .././repair/phase6.c:2932 #, c-format msgid "setting .. in sf dir inode % to %\n" msgstr "" #: .././repair/phase6.c:3036 #, c-format msgid "" "entry \"%s\" in shortform directory % references non-existent inode %" "\n" msgstr "" #: .././repair/phase6.c:3050 #, c-format msgid "" "entry \"%s\" in shortform directory inode % points to free inode %" "\n" msgstr "" #: .././repair/phase6.c:3103 #, c-format msgid "" "entry \"%s\" in directory inode % references already connected inode " "%.\n" msgstr "" #: .././repair/phase6.c:3123 #, c-format msgid "" "entry \"%s\" in directory inode % not consistent with .. value (%" ") in inode %,\n" msgstr "" #: .././repair/phase6.c:3194 #, c-format msgid "would fix i8count in inode %\n" msgstr "" #: .././repair/phase6.c:3207 #, c-format msgid "fixing i8count in inode %\n" msgstr "" #: .././repair/phase6.c:3267 .././repair/phase6.c:3271 .././repair/phase7.c:85 #, c-format msgid "couldn't map inode %, err = %d\n" msgstr "" #: .././repair/phase6.c:3382 msgid "missing root directory .. entry, cannot fix in V1 dir filesystem\n" msgstr "" #: .././repair/phase6.c:3389 #, c-format msgid "" "%d bad entries found in dir inode %, cannot fix in V1 dir " "filesystem\n" msgstr "" #: .././repair/phase6.c:3396 #, c-format msgid "" "missing \".\" entry in dir ino %, cannot in fix V1 dir filesystem\n" msgstr "" #: .././repair/phase6.c:3414 msgid "recreating root directory .. entry\n" msgstr "" #: .././repair/phase6.c:3434 #, c-format msgid "can't make \"..\" entry in root inode %, createname error %d\n" msgstr "" #: .././repair/phase6.c:3445 msgid "would recreate root directory .. entry\n" msgstr "" #: .././repair/phase6.c:3469 #, c-format msgid "would create missing \".\" entry in dir ino %\n" msgstr "" #: .././repair/phase6.c:3476 #, c-format msgid "creating missing \".\" entry in dir ino %\n" msgstr "" #: .././repair/phase6.c:3500 #, c-format msgid "can't make \".\" entry in dir ino %, createname error %d\n" msgstr "" #: .././repair/phase6.c:3589 #, c-format msgid "disconnected dir inode %, " msgstr "" #: .././repair/phase6.c:3591 #, c-format msgid "disconnected inode %, " msgstr "" #: .././repair/phase6.c:3593 msgid "cannot fix in V1 dir filesystem\n" msgstr "" #: .././repair/phase6.c:3597 #, c-format msgid "moving to %s\n" msgstr "" #: .././repair/phase6.c:3600 #, c-format msgid "would move to %s\n" msgstr "" #: .././repair/phase6.c:3691 msgid "Phase 6 - check inode connectivity...\n" msgstr "" #: .././repair/phase6.c:3705 msgid "" "need to reinitialize root directory, but not supported on V1 dir filesystem\n" msgstr "" #: .././repair/phase6.c:3708 msgid "reinitializing root directory\n" msgstr "" #: .././repair/phase6.c:3713 msgid "would reinitialize root directory\n" msgstr "" #: .././repair/phase6.c:3719 msgid "reinitializing realtime bitmap inode\n" msgstr "" #: .././repair/phase6.c:3723 msgid "would reinitialize realtime bitmap inode\n" msgstr "" #: .././repair/phase6.c:3729 msgid "reinitializing realtime summary inode\n" msgstr "" #: .././repair/phase6.c:3733 msgid "would reinitialize realtime summary inode\n" msgstr "" #: .././repair/phase6.c:3739 msgid " - resetting contents of realtime bitmap and summary inodes\n" msgstr "" #: .././repair/phase6.c:3742 .././repair/phase6.c:3747 msgid "Warning: realtime bitmap may be inconsistent\n" msgstr "" #: .././repair/phase6.c:3753 msgid " - traversing filesystem ...\n" msgstr "" #: .././repair/phase6.c:3776 msgid " - traversal finished ...\n" msgstr "" #: .././repair/phase6.c:3777 #, c-format msgid " - moving disconnected inodes to %s ...\n" msgstr "" #: .././repair/incore.c:230 #, c-format msgid "couldn't allocate realtime block map, size = %\n" msgstr "" #: .././repair/incore.c:295 msgid "couldn't allocate block map btree roots\n" msgstr "" #: .././repair/incore.c:299 msgid "couldn't allocate block map locks\n" msgstr "" #: .././repair/phase2.c:65 #, c-format msgid "" "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" msgstr "" #: .././repair/phase2.c:71 #, c-format msgid "zero_log: head block % tail block %\n" msgstr "" #: .././repair/phase2.c:77 msgid "" "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n" msgstr "" #: .././repair/phase2.c:81 msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" #: .././repair/phase2.c:123 msgid "" "This filesystem has an external log. Specify log device with the -l " "option.\n" msgstr "" #: .././repair/phase2.c:126 #, c-format msgid "Phase 2 - using external log on %s\n" msgstr "" #: .././repair/phase2.c:128 msgid "Phase 2 - using internal log\n" msgstr "" #: .././repair/phase2.c:132 msgid " - zero log...\n" msgstr "" #: .././repair/phase2.c:136 msgid " - scan filesystem freespace and inode maps...\n" msgstr "" #: .././repair/phase2.c:152 msgid "root inode chunk not found\n" msgstr "" #: .././repair/phase2.c:171 msgid " - found root inode chunk\n" msgstr "" #: .././repair/phase2.c:177 msgid "root inode marked free, " msgstr "" #: .././repair/phase2.c:180 .././repair/phase2.c:189 .././repair/phase2.c:198 #: .././repair/dir2.c:1578 .././repair/dir2.c:1610 msgid "correcting\n" msgstr "" #: .././repair/phase2.c:182 .././repair/phase2.c:191 .././repair/phase2.c:200 #: .././repair/dir2.c:1582 .././repair/dir2.c:1614 msgid "would correct\n" msgstr "" #: .././repair/phase2.c:186 msgid "realtime bitmap inode marked free, " msgstr "" #: .././repair/phase2.c:195 msgid "realtime summary inode marked free, " msgstr "" #: .././repair/progress.c:16 msgid "inodes" msgstr "" #: .././repair/progress.c:20 msgid "directories" msgstr "" #: .././repair/progress.c:22 msgid "allocation groups" msgstr "" #: .././repair/progress.c:24 msgid "AGI unlinked buckets" msgstr "" #: .././repair/progress.c:28 msgid "realtime extents" msgstr "" #: .././repair/progress.c:30 msgid "unlinked lists" msgstr "" #: .././repair/progress.c:37 #, c-format msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" msgstr "" #: .././repair/progress.c:39 #, c-format msgid " - %02d:%02d:%02d: %s - %llu %s done\n" msgstr "" #: .././repair/progress.c:51 msgid "scanning filesystem freespace" msgstr "" #: .././repair/progress.c:53 msgid "scanning agi unlinked lists" msgstr "" #: .././repair/progress.c:55 msgid "check uncertain AG inodes" msgstr "" #: .././repair/progress.c:57 msgid "process known inodes and inode discovery" msgstr "" #: .././repair/progress.c:59 msgid "process newly discovered inodes" msgstr "" #: .././repair/progress.c:61 msgid "setting up duplicate extent list" msgstr "" #: .././repair/progress.c:63 msgid "initialize realtime bitmap" msgstr "" #: .././repair/progress.c:65 msgid "reset realtime bitmaps" msgstr "" #: .././repair/progress.c:67 msgid "check for inodes claiming duplicate blocks" msgstr "" #: .././repair/progress.c:69 msgid "rebuild AG headers and trees" msgstr "" #: .././repair/progress.c:71 msgid "traversing filesystem" msgstr "" #: .././repair/progress.c:73 msgid "traversing all unattached subtrees" msgstr "" #: .././repair/progress.c:75 msgid "moving disconnected inodes to lost+found" msgstr "" #: .././repair/progress.c:77 msgid "verify and correct link counts" msgstr "" #: .././repair/progress.c:79 msgid "verify link counts" msgstr "" #: .././repair/progress.c:118 msgid "cannot malloc pointer to done vector\n" msgstr "" #: .././repair/progress.c:134 msgid "unable to create progress report thread\n" msgstr "" #: .././repair/progress.c:173 msgid "progress_rpt: cannot malloc progress msg buffer\n" msgstr "" #: .././repair/progress.c:187 msgid "progress_rpt: cannot create timer\n" msgstr "" #: .././repair/progress.c:190 msgid "progress_rpt: cannot set timer\n" msgstr "" #: .././repair/progress.c:214 msgid "progress_rpt: cannot lock progress mutex\n" msgstr "" #: .././repair/progress.c:251 .././repair/progress.c:354 #, c-format msgid "%s" msgstr "" #: .././repair/progress.c:259 #, c-format msgid "" "\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" msgstr "" #: .././repair/progress.c:264 #, c-format msgid "" "\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time %" "s\n" msgstr "" #: .././repair/progress.c:272 msgid "progress_rpt: error unlock msg mutex\n" msgstr "" #: .././repair/progress.c:278 msgid "cannot delete timer\n" msgstr "" #: .././repair/progress.c:292 msgid "set_progress_msg: cannot lock progress mutex\n" msgstr "" #: .././repair/progress.c:302 msgid "set_progress_msg: cannot unlock progress mutex\n" msgstr "" #: .././repair/progress.c:322 msgid "print_final_rpt: cannot lock progress mutex\n" msgstr "" #: .././repair/progress.c:358 msgid "print_final_rpt: cannot unlock progress mutex\n" msgstr "" #: .././repair/progress.c:407 #, c-format msgid "%02d:%02d:%02d" msgstr "" #: .././repair/progress.c:429 #, c-format msgid "%d week" msgstr "" #: .././repair/progress.c:430 .././repair/progress.c:440 #: .././repair/progress.c:456 .././repair/progress.c:474 #: .././repair/progress.c:489 msgid "s" msgstr "" #: .././repair/progress.c:439 #, c-format msgid "%d day" msgstr "" #: .././repair/progress.c:446 .././repair/progress.c:463 #: .././repair/progress.c:481 .././repair/progress.c:491 msgid ", " msgstr "" #: .././repair/progress.c:455 #, c-format msgid "%d hour" msgstr "" #: .././repair/progress.c:473 #, c-format msgid "%d minute" msgstr "" #: .././repair/progress.c:488 #, c-format msgid "%d second" msgstr "" #: .././repair/progress.c:509 #, c-format msgid "" "\n" " XFS_REPAIR Summary %s\n" msgstr "" #: .././repair/progress.c:511 msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" msgstr "" #: .././repair/progress.c:516 .././repair/progress.c:519 #, c-format msgid "Phase %d:\tSkipped\n" msgstr "" #: .././repair/progress.c:523 #, c-format msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" msgstr "" #: .././repair/progress.c:529 #, c-format msgid "" "\n" "Total run time: %s\n" msgstr "" #: .././repair/dinode.c:46 #, c-format msgid "clearing inode % attributes\n" msgstr "" #: .././repair/dinode.c:49 #, c-format msgid "would have cleared inode % attributes\n" msgstr "" #: .././repair/dinode.c:424 #, c-format msgid "" "inode % - bad rt extent start block number %, offset %" "\n" msgstr "" #: .././repair/dinode.c:432 #, c-format msgid "" "inode % - bad rt extent last block number %, offset %" "\n" msgstr "" #: .././repair/dinode.c:440 #, c-format msgid "" "inode % - bad rt extent overflows - start %, end %, " "offset %\n" msgstr "" #: .././repair/dinode.c:457 #, c-format msgid "malformed rt inode extent [% %] (fs rtext size = %u)\n" msgstr "" #: .././repair/dinode.c:478 #, c-format msgid "" "data fork in rt ino % claims dup rt extent,off - %, start - %" ", count %\n" msgstr "" #: .././repair/dinode.c:497 #, c-format msgid "bad state in rt block map %\n" msgstr "" #: .././repair/dinode.c:503 #, c-format msgid "" "data fork in rt inode % found metadata block % in rt bmap\n" msgstr "" #: .././repair/dinode.c:511 #, c-format msgid "data fork in rt inode % claims used rt block %\n" msgstr "" #: .././repair/dinode.c:517 #, c-format msgid "illegal state %d in rt block map %\n" msgstr "" #: .././repair/dinode.c:573 msgid "real-time" msgstr "" #: .././repair/dinode.c:575 msgid "regular" msgstr "" #: .././repair/dinode.c:585 #, c-format msgid "" "bmap rec out of order, inode % entry %d [o s c] [% % " "%], %d [% % %]\n" msgstr "" #: .././repair/dinode.c:601 #, c-format msgid "" "zero length extent (off = %, fsbno = %) in ino %\n" msgstr "" #: .././repair/dinode.c:632 #, c-format msgid "" "inode % - bad extent starting block number %, offset %" "\n" msgstr "" #: .././repair/dinode.c:640 #, c-format msgid "" "inode % - bad extent last block number %, offset %\n" msgstr "" #: .././repair/dinode.c:648 #, c-format msgid "" "inode % - bad extent overflows - start %, end %, " "offset %\n" msgstr "" #: .././repair/dinode.c:658 #, c-format msgid "" "inode % - extent offset too large - start %, count %" ", offset %\n" msgstr "" #: .././repair/dinode.c:678 #, c-format msgid "" "Fatal error: inode % - blkmap_set_ext(): %s\n" "\t%s fork, off - %, start - %, cnt %\n" msgstr "" #: .././repair/dinode.c:709 #, c-format msgid "" "%s fork in ino % claims dup extent, off - %, start - %" ", cnt %\n" msgstr "" #: .././repair/dinode.c:728 #, c-format msgid "%s fork in ino % claims free block %\n" msgstr "" #: .././repair/dinode.c:736 #, c-format msgid "bad state in block map %\n" msgstr "" #: .././repair/dinode.c:742 #, c-format msgid "%s fork in inode % claims metadata block %\n" msgstr "" #: .././repair/dinode.c:750 #, c-format msgid "%s fork in %s inode % claims used block %\n" msgstr "" #: .././repair/dinode.c:756 #, c-format msgid "illegal state %d in block map %\n" msgstr "" #: .././repair/dinode.c:769 #, c-format msgid "correcting nextents for inode %\n" msgstr "" #: .././repair/dinode.c:841 #, c-format msgid "cannot read inode (%u/%u), disk block %\n" msgstr "" #: .././repair/dinode.c:952 .././repair/dinode.c:1009 #, c-format msgid "cannot read bmap block %\n" msgstr "" #: .././repair/dinode.c:973 #, c-format msgid "# of bmap records in inode % exceeds max (%u, max - %u)\n" msgstr "" #: .././repair/dinode.c:981 #, c-format msgid "" "- # of bmap records in inode % less than minimum (%u, min - %u), " "proceeding ...\n" msgstr "" #: .././repair/dinode.c:1023 #, c-format msgid "" "# of bmap records in inode % greater than maximum (%u, max - %u)\n" msgstr "" #: .././repair/dinode.c:1030 #, c-format msgid "" "- # of bmap records in inode % less than minimum (%u, min - %u), " "continuing...\n" msgstr "" #: .././repair/dinode.c:1046 #, c-format msgid "could not map block %\n" msgstr "" #: .././repair/dinode.c:1080 #, c-format msgid "get_bmapi() called for local inode %\n" msgstr "" #: .././repair/dinode.c:1088 #, c-format msgid "bad inode format for inode %\n" msgstr "" #: .././repair/dinode.c:1152 #, c-format msgid "bad level %d in inode % bmap btree root block\n" msgstr "" #: .././repair/dinode.c:1158 #, c-format msgid "bad numrecs 0 in inode % bmap btree root block\n" msgstr "" #: .././repair/dinode.c:1167 #, c-format msgid "" "indicated size of %s btree root (%d bytes) greater than space in inode %" " %s fork\n" msgstr "" #: .././repair/dinode.c:1206 #, c-format msgid "" "correcting key in bmbt root (was %llu, now %) in inode % %s " "fork\n" msgstr "" #: .././repair/dinode.c:1218 #, c-format msgid "" "bad key in bmbt root (is %llu, would reset to %) in inode % %" "s fork\n" msgstr "" #: .././repair/dinode.c:1235 #, c-format msgid "out of order bmbt root key % in inode % %s fork\n" msgstr "" #: .././repair/dinode.c:1252 #, c-format msgid "" "extent count for ino % %s fork too low (%) for file format\n" msgstr "" #: .././repair/dinode.c:1263 #, c-format msgid "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" msgstr "" #: .././repair/dinode.c:1266 #, c-format msgid "\tin inode % (%s fork) bmap btree block %\n" msgstr "" #: .././repair/dinode.c:1339 #, c-format msgid "local inode % data fork is too large (size = %lld, max = %d)\n" msgstr "" #: .././repair/dinode.c:1347 #, c-format msgid "local inode % attr fork too large (size %d, max = %d)\n" msgstr "" #: .././repair/dinode.c:1354 #, c-format msgid "local inode % attr too small (size = %d, min size = %zd)\n" msgstr "" #: .././repair/dinode.c:1378 #, c-format msgid "" "mismatch between format (%d) and size (%) in symlink ino %\n" msgstr "" #: .././repair/dinode.c:1385 #, c-format msgid "" "mismatch between format (%d) and size (%) in symlink inode %" "\n" msgstr "" #: .././repair/dinode.c:1400 #, c-format msgid "bad number of extents (%d) in symlink % data fork\n" msgstr "" #: .././repair/dinode.c:1413 #, c-format msgid "bad extent #%d offset (%) in symlink % data fork\n" msgstr "" #: .././repair/dinode.c:1419 #, c-format msgid "bad extent #%d count (%) in symlink % data fork\n" msgstr "" #: .././repair/dinode.c:1474 #, c-format msgid "symlink in inode % too long (%llu chars)\n" msgstr "" #: .././repair/dinode.c:1507 #, c-format msgid "cannot read inode %, file block %d, disk block %\n" msgstr "" #: .././repair/dinode.c:1529 #, c-format msgid "found illegal null character in symlink inode %\n" msgstr "" #: .././repair/dinode.c:1543 .././repair/dinode.c:1553 #, c-format msgid "component of symlink in inode % too long\n" msgstr "" #: .././repair/dinode.c:1579 #, c-format msgid "inode % has bad inode type (IFMNT)\n" msgstr "" #: .././repair/dinode.c:1590 #, c-format msgid "size of character device inode % != 0 (% bytes)\n" msgstr "" #: .././repair/dinode.c:1595 #, c-format msgid "size of block device inode % != 0 (% bytes)\n" msgstr "" #: .././repair/dinode.c:1600 #, c-format msgid "size of socket inode % != 0 (% bytes)\n" msgstr "" #: .././repair/dinode.c:1605 #, c-format msgid "size of fifo inode % != 0 (% bytes)\n" msgstr "" #: .././repair/dinode.c:1609 #, c-format msgid "Internal error - process_misc_ino_types, illegal type %d\n" msgstr "" #: .././repair/dinode.c:1636 #, c-format msgid "size of character device inode % != 0 (% blocks)\n" msgstr "" #: .././repair/dinode.c:1641 #, c-format msgid "size of block device inode % != 0 (% blocks)\n" msgstr "" #: .././repair/dinode.c:1646 #, c-format msgid "size of socket inode % != 0 (% blocks)\n" msgstr "" #: .././repair/dinode.c:1651 #, c-format msgid "size of fifo inode % != 0 (% blocks)\n" msgstr "" #: .././repair/dinode.c:1729 #, c-format msgid "root inode % has bad type 0x%x\n" msgstr "" #: .././repair/dinode.c:1733 msgid "resetting to directory\n" msgstr "" #: .././repair/dinode.c:1737 msgid "would reset to directory\n" msgstr "" #: .././repair/dinode.c:1743 #, c-format msgid "user quota inode % has bad type 0x%x\n" msgstr "" #: .././repair/dinode.c:1752 #, c-format msgid "group quota inode % has bad type 0x%x\n" msgstr "" #: .././repair/dinode.c:1762 #, c-format msgid "realtime summary inode % has bad type 0x%x, " msgstr "" #: .././repair/dinode.c:1765 .././repair/dinode.c:1786 msgid "resetting to regular file\n" msgstr "" #: .././repair/dinode.c:1769 .././repair/dinode.c:1790 msgid "would reset to regular file\n" msgstr "" #: .././repair/dinode.c:1774 #, c-format msgid "bad # of extents (%u) for realtime summary inode %\n" msgstr "" #: .././repair/dinode.c:1783 #, c-format msgid "realtime bitmap inode % has bad type 0x%x, " msgstr "" #: .././repair/dinode.c:1795 #, c-format msgid "bad # of extents (%u) for realtime bitmap inode %\n" msgstr "" #: .././repair/dinode.c:1830 #, c-format msgid "" "mismatch between format (%d) and size (%) in directory ino %" "\n" msgstr "" #: .././repair/dinode.c:1836 #, c-format msgid "directory inode % has bad size %\n" msgstr "" #: .././repair/dinode.c:1844 #, c-format msgid "bad data fork in symlink %\n" msgstr "" #: .././repair/dinode.c:1865 #, c-format msgid "found inode % claiming to be a real-time file\n" msgstr "" #: .././repair/dinode.c:1874 #, c-format msgid "" "realtime bitmap inode % has bad size % (should be %" ")\n" msgstr "" #: .././repair/dinode.c:1885 #, c-format msgid "" "realtime summary inode % has bad size % (should be %d)\n" msgstr "" #: .././repair/dinode.c:1913 #, c-format msgid "bad attr fork offset %d in dev inode %, should be %d\n" msgstr "" #: .././repair/dinode.c:1924 #, c-format msgid "bad attr fork offset %d in inode %, max=%d\n" msgstr "" #: .././repair/dinode.c:1931 #, c-format msgid "unexpected inode format %d\n" msgstr "" #: .././repair/dinode.c:1952 #, c-format msgid "correcting nblocks for inode %, was %llu - counted %\n" msgstr "" #: .././repair/dinode.c:1959 #, c-format msgid "bad nblocks %llu for inode %, would reset to %\n" msgstr "" #: .././repair/dinode.c:1967 #, c-format msgid "too many data fork extents (%) in inode %\n" msgstr "" #: .././repair/dinode.c:1974 #, c-format msgid "correcting nextents for inode %, was %d - counted %\n" msgstr "" #: .././repair/dinode.c:1982 #, c-format msgid "bad nextents %d for inode %, would reset to %\n" msgstr "" #: .././repair/dinode.c:1990 #, c-format msgid "too many attr fork extents (%) in inode %\n" msgstr "" #: .././repair/dinode.c:1997 #, c-format msgid "correcting anextents for inode %, was %d - counted %\n" msgstr "" #: .././repair/dinode.c:2004 #, c-format msgid "bad anextents %d for inode %, would reset to %\n" msgstr "" #: .././repair/dinode.c:2016 #, c-format msgid "nblocks (%) smaller than nextents for inode %\n" msgstr "" #: .././repair/dinode.c:2069 .././repair/dinode.c:2107 #, c-format msgid "unknown format %d, ino % (mode = %d)\n" msgstr "" #: .././repair/dinode.c:2074 #, c-format msgid "bad data fork in inode %\n" msgstr "" #: .././repair/dinode.c:2145 #, c-format msgid "bad attribute format %d in inode %, " msgstr "" #: .././repair/dinode.c:2148 msgid "resetting value\n" msgstr "" #: .././repair/dinode.c:2152 msgid "would reset value\n" msgstr "" #: .././repair/dinode.c:2197 #, c-format msgid "bad attribute fork in inode %" msgstr "" #: .././repair/dinode.c:2201 msgid ", clearing attr fork\n" msgstr "" #: .././repair/dinode.c:2210 msgid ", would clear attr fork\n" msgstr "" #: .././repair/dinode.c:2238 #, c-format msgid "illegal attribute fmt %d, ino %\n" msgstr "" #: .././repair/dinode.c:2258 #, c-format msgid "problem with attribute contents in inode %\n" msgstr "" #: .././repair/dinode.c:2266 msgid "would clear attr fork\n" msgstr "" #: .././repair/dinode.c:2309 #, c-format msgid "version 2 inode % claims > %u links, " msgstr "" #: .././repair/dinode.c:2313 msgid "updating superblock version number\n" msgstr "" #: .././repair/dinode.c:2316 msgid "would update superblock version number\n" msgstr "" #: .././repair/dinode.c:2324 #, c-format msgid "WARNING: version 2 inode % claims > %u links, " msgstr "" #: .././repair/dinode.c:2327 #, c-format msgid "" "converting back to version 1,\n" "this may destroy %d links\n" msgstr "" #: .././repair/dinode.c:2337 #, c-format msgid "" "would convert back to version 1,\n" "\tthis might destroy %d links\n" msgstr "" #: .././repair/dinode.c:2352 #, c-format msgid "found version 2 inode %, " msgstr "" #: .././repair/dinode.c:2354 msgid "converting back to version 1\n" msgstr "" #: .././repair/dinode.c:2360 msgid "would convert back to version 1\n" msgstr "" #: .././repair/dinode.c:2374 #, c-format msgid "" "clearing obsolete nlink field in version 2 inode %, was %d, now 0\n" msgstr "" #: .././repair/dinode.c:2380 #, c-format msgid "" "would clear obsolete nlink field in version 2 inode %, currently %d\n" msgstr "" #: .././repair/dinode.c:2449 #, c-format msgid "bad magic number 0x%x on inode %%c" msgstr "" #: .././repair/dinode.c:2454 msgid " resetting magic number\n" msgstr "" #: .././repair/dinode.c:2458 msgid " would reset magic number\n" msgstr "" #: .././repair/dinode.c:2466 #, c-format msgid "bad version number 0x%x on inode %%c" msgstr "" #: .././repair/dinode.c:2471 msgid " resetting version number\n" msgstr "" #: .././repair/dinode.c:2475 msgid " would reset version number\n" msgstr "" #: .././repair/dinode.c:2485 #, c-format msgid "bad (negative) size % on inode %\n" msgstr "" #: .././repair/dinode.c:2518 #, c-format msgid "imap claims a free inode % is in use, " msgstr "" #: .././repair/dinode.c:2520 msgid "correcting imap and clearing inode\n" msgstr "" #: .././repair/dinode.c:2524 msgid "would correct imap and clear inode\n" msgstr "" #: .././repair/dinode.c:2541 #, c-format msgid "bad inode format in inode %\n" msgstr "" #: .././repair/dinode.c:2557 #, c-format msgid "Bad flags set in inode %\n" msgstr "" #: .././repair/dinode.c:2568 #, c-format msgid "inode % has RT flag set but there is no RT device\n" msgstr "" #: .././repair/dinode.c:2580 #, c-format msgid "inode % not rt bitmap\n" msgstr "" #: .././repair/dinode.c:2594 #, c-format msgid "directory flags set on non-directory inode %\n" msgstr "" #: .././repair/dinode.c:2608 #, c-format msgid "file flags set on non-file inode %\n" msgstr "" #: .././repair/dinode.c:2617 msgid ", fixing bad flags.\n" msgstr "" #: .././repair/dinode.c:2621 msgid ", would fix bad flags.\n" msgstr "" #: .././repair/dinode.c:2672 #, c-format msgid "bad inode type %#o inode %\n" msgstr "" #: .././repair/dinode.c:2696 #, c-format msgid "bad non-zero extent size %u for non-realtime/extsize inode %, " msgstr "" #: .././repair/dinode.c:2699 msgid "resetting to zero\n" msgstr "" #: .././repair/dinode.c:2703 msgid "would reset to zero\n" msgstr "" #: .././repair/dinode.c:2759 #, c-format msgid "problem with directory contents in inode %\n" msgstr "" #: .././repair/dinode.c:2767 #, c-format msgid "problem with symbolic link in inode %\n" msgstr "" #: .././repair/dinode.c:2862 #, c-format msgid "processing inode %d/%d\n" msgstr "" #: .././repair/dir2.c:57 #, c-format msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" msgstr "" #: .././repair/dir2.c:98 .././repair/dir2.c:209 .././repair/dir2.c:245 msgid "couldn't malloc dir2 buffer list\n" msgstr "" #: .././repair/dir2.c:125 msgid "couldn't malloc dir2 buffer header\n" msgstr "" #: .././repair/dir2.c:142 msgid "couldn't malloc dir2 buffer data\n" msgstr "" #: .././repair/dir2.c:315 #, c-format msgid "found non-root LEAFN node in inode % bno = %u\n" msgstr "" #: .././repair/dir2.c:324 #, c-format msgid "bad dir magic number 0x%x in inode % bno = %u\n" msgstr "" #: .././repair/dir2.c:345 #, c-format msgid "bad header depth for directory inode %\n" msgstr "" #: .././repair/dir2.c:406 #, c-format msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "" #: .././repair/dir2.c:469 #, c-format msgid "directory block used/count inconsistency - %d / %hu\n" msgstr "" #: .././repair/dir2.c:491 #, c-format msgid "bad directory block in inode %\n" msgstr "" #: .././repair/dir2.c:512 #, c-format msgid "" "correcting bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir2.c:520 #, c-format msgid "" "would correct bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir2.c:676 #, c-format msgid "bad magic number %x in block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:684 #, c-format msgid "bad back pointer in block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:690 #, c-format msgid "entry count %d too large in block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:697 #, c-format msgid "bad level %d in block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:740 #, c-format msgid "" "correcting bad hashval in interior dir block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir2.c:748 #, c-format msgid "" "would correct bad hashval in interior dir block\n" "\tin (level %d) in inode %.\n" msgstr "" #: .././repair/dir2.c:782 msgid "couldn't malloc dir2 shortform copy\n" msgstr "" #: .././repair/dir2.c:920 msgid "current" msgstr "" #: .././repair/dir2.c:923 .././repair/dir2.c:1443 msgid "invalid" msgstr "" #: .././repair/dir2.c:926 .././repair/dir2.c:1445 msgid "realtime bitmap" msgstr "" #: .././repair/dir2.c:929 .././repair/dir2.c:1447 msgid "realtime summary" msgstr "" #: .././repair/dir2.c:932 .././repair/dir2.c:1449 msgid "user quota" msgstr "" #: .././repair/dir2.c:935 .././repair/dir2.c:1451 msgid "group quota" msgstr "" #: .././repair/dir2.c:953 .././repair/dir2.c:1481 msgid "free" msgstr "" #: .././repair/dir2.c:970 .././repair/dir2.c:1461 msgid "non-existent" msgstr "" #: .././repair/dir2.c:975 #, c-format msgid "" "entry \"%*.*s\" in shortform directory % references %s inode %" "\n" msgstr "" #: .././repair/dir2.c:1005 #, c-format msgid "zero length entry in shortform dir %" msgstr "" #: .././repair/dir2.c:1008 #, c-format msgid ", junking %d entries\n" msgstr "" #: .././repair/dir2.c:1011 #, c-format msgid ", would junk %d entries\n" msgstr "" #: .././repair/dir2.c:1086 #, c-format msgid "entry contains offset out of order in shortform dir %\n" msgstr "" #: .././repair/dir2.c:1189 #, c-format msgid "would have corrected i8 count in directory % from %d to %d\n" msgstr "" #: .././repair/dir2.c:1193 #, c-format msgid "corrected i8 count in directory %, was %d, now %d\n" msgstr "" #: .././repair/dir2.c:1207 #, c-format msgid "" "would have corrected directory % size from % to %\n" msgstr "" #: .././repair/dir2.c:1224 #, c-format msgid "directory % offsets too high\n" msgstr "" #: .././repair/dir2.c:1230 #, c-format msgid "would have corrected entry offsets in directory %\n" msgstr "" #: .././repair/dir2.c:1234 #, c-format msgid "corrected entry offsets in directory %\n" msgstr "" #: .././repair/dir2.c:1289 #, c-format msgid "bad .. entry in directory inode %, points to self, " msgstr "" #: .././repair/dir2.c:1401 #, c-format msgid "corrupt block %u in directory inode %\n" msgstr "" #: .././repair/dir2.c:1404 msgid "\twill junk block\n" msgstr "" #: .././repair/dir2.c:1406 msgid "\twould junk block\n" msgstr "" #: .././repair/dir2.c:1490 #, c-format msgid "" "entry \"%*.*s\" at block %d offset % in directory inode % " "references %s inode %\n" msgstr "" #: .././repair/dir2.c:1501 #, c-format msgid "" "entry at block %u offset % in directory inode %has 0 " "namelength\n" msgstr "" #: .././repair/dir2.c:1514 #, c-format msgid "\tclearing inode number in entry at offset %...\n" msgstr "" #: .././repair/dir2.c:1521 #, c-format msgid "\twould clear inode number in entry at offset %...\n" msgstr "" #: .././repair/dir2.c:1534 #, c-format msgid "" "entry at block %u offset % in directory inode % has illegal " "name \"%*.*s\": " msgstr "" #: .././repair/dir2.c:1564 #, c-format msgid "bad .. entry in directory inode %, points to self: " msgstr "" #: .././repair/dir2.c:1575 #, c-format msgid "bad .. entry in root directory inode %, was %: " msgstr "" #: .././repair/dir2.c:1594 #, c-format msgid "multiple .. entries in directory inode %: " msgstr "" #: .././repair/dir2.c:1607 #, c-format msgid "bad . entry in directory inode %, was %: " msgstr "" #: .././repair/dir2.c:1619 #, c-format msgid "multiple . entries in directory inode %: " msgstr "" #: .././repair/dir2.c:1629 #, c-format msgid "entry \"%*.*s\" in directory inode % points to self: " msgstr "" #: .././repair/dir2.c:1640 msgid "clearing entry\n" msgstr "" #: .././repair/dir2.c:1655 #, c-format msgid "bad bestfree table in block %u in directory inode %: " msgstr "" #: .././repair/dir2.c:1658 msgid "repairing table\n" msgstr "" #: .././repair/dir2.c:1662 msgid "would repair table\n" msgstr "" #: .././repair/dir2.c:1700 #, c-format msgid "block %u for directory inode % is missing\n" msgstr "" #: .././repair/dir2.c:1719 #, c-format msgid "" "bad directory block magic # %#x in block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:1763 #, c-format msgid "bad entry count in block %u of directory inode %\n" msgstr "" #: .././repair/dir2.c:1771 #, c-format msgid "bad hash ordering in block %u of directory inode %\n" msgstr "" #: .././repair/dir2.c:1780 #, c-format msgid "bad stale count in block %u of directory inode %\n" msgstr "" #: .././repair/dir2.c:1838 #, c-format msgid "can't read file block %u for directory inode %\n" msgstr "" #: .././repair/dir2.c:1849 #, c-format msgid "bad directory leaf magic # %#x for directory inode % block %u\n" msgstr "" #: .././repair/dir2.c:1879 #, c-format msgid "bad sibling back pointer for block %u in directory inode %\n" msgstr "" #: .././repair/dir2.c:2013 #, c-format msgid "block % for directory inode % is missing\n" msgstr "" #: .././repair/dir2.c:2022 #, c-format msgid "can't read block % for directory inode %\n" msgstr "" #: .././repair/dir2.c:2029 #, c-format msgid "" "bad directory block magic # %#x in block % for directory inode %" "\n" msgstr "" #: .././repair/dir2.c:2106 #, c-format msgid "bad size/format for directory %\n" msgstr "" #: .././repair/phase7.c:43 #, c-format msgid "resetting inode % nlinks from %u to %u\n" msgstr "" #: .././repair/phase7.c:49 #, c-format msgid "" "nlinks %u will overflow v1 ino, ino % will be converted to version " "2\n" msgstr "" #: .././repair/phase7.c:56 #, c-format msgid "would have reset inode % nlinks from %u to %u\n" msgstr "" #: .././repair/phase7.c:89 #, c-format msgid "couldn't map inode %, err = %d, can't compare link counts\n" msgstr "" #: .././repair/phase7.c:128 msgid "Phase 7 - verify and correct link counts...\n" msgstr "" #: .././repair/phase7.c:130 msgid "Phase 7 - verify link counts...\n" msgstr "" #: .././repair/phase4.c:202 msgid "Phase 4 - check for duplicate blocks...\n" msgstr "" #: .././repair/phase4.c:203 msgid " - setting up duplicate extent list...\n" msgstr "" #: .././repair/phase4.c:217 msgid "root inode would be lost\n" msgstr "" #: .././repair/phase4.c:219 msgid "root inode lost\n" msgstr "" #: .././repair/phase4.c:236 #, c-format msgid "unknown block state, ag %d, block %d\n" msgstr "" #: .././repair/phase4.c:269 #, c-format msgid "unknown rt extent state, extent %\n" msgstr "" #: .././repair/phase4.c:318 msgid " - check for inodes claiming duplicate blocks...\n" msgstr "" #: .././repair/prefetch.c:465 msgid "prefetch corruption\n" msgstr "" #: .././repair/prefetch.c:611 .././repair/prefetch.c:711 #, c-format msgid "failed to create prefetch thread: %s\n" msgstr "" #: .././repair/prefetch.c:748 msgid "failed to initialize prefetch mutex\n" msgstr "" #: .././repair/prefetch.c:750 .././repair/prefetch.c:752 msgid "failed to initialize prefetch cond var\n" msgstr "" #: .././repair/xfs_repair.c:81 #, c-format msgid "" "Usage: %s [options] device\n" "\n" "Options:\n" " -f The device is a file\n" " -L Force log zeroing. Do this as a last resort.\n" " -l logdev Specifies the device where the external log resides.\n" " -m maxmem Maximum amount of memory to be used in megabytes.\n" " -n No modify mode, just checks the filesystem for damage.\n" " -P Disables prefetching.\n" " -r rtdev Specifies the device where the realtime section resides.\n" " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" " -t interval Reporting interval in minutes.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n" msgstr "" #: .././repair/xfs_repair.c:107 msgid "no error" msgstr "" #: .././repair/xfs_repair.c:108 msgid "bad magic number" msgstr "" #: .././repair/xfs_repair.c:109 msgid "bad blocksize field" msgstr "" #: .././repair/xfs_repair.c:110 msgid "bad blocksize log field" msgstr "" #: .././repair/xfs_repair.c:111 msgid "bad or unsupported version" msgstr "" #: .././repair/xfs_repair.c:113 msgid "filesystem mkfs-in-progress bit set" msgstr "" #: .././repair/xfs_repair.c:115 msgid "inconsistent filesystem geometry information" msgstr "" #: .././repair/xfs_repair.c:117 msgid "bad inode size or inconsistent with number of inodes/block" msgstr "" #: .././repair/xfs_repair.c:118 msgid "bad sector size" msgstr "" #: .././repair/xfs_repair.c:120 msgid "AGF geometry info conflicts with filesystem geometry" msgstr "" #: .././repair/xfs_repair.c:122 msgid "AGI geometry info conflicts with filesystem geometry" msgstr "" #: .././repair/xfs_repair.c:124 msgid "AG superblock geometry info conflicts with filesystem geometry" msgstr "" #: .././repair/xfs_repair.c:125 msgid "attempted to perform I/O beyond EOF" msgstr "" #: .././repair/xfs_repair.c:127 msgid "inconsistent filesystem geometry in realtime filesystem component" msgstr "" #: .././repair/xfs_repair.c:129 msgid "maximum indicated percentage of inodes > 100%" msgstr "" #: .././repair/xfs_repair.c:131 msgid "inconsistent inode alignment value" msgstr "" #: .././repair/xfs_repair.c:133 msgid "not enough secondary superblocks with matching geometry" msgstr "" #: .././repair/xfs_repair.c:135 msgid "bad stripe unit in superblock" msgstr "" #: .././repair/xfs_repair.c:137 msgid "bad stripe width in superblock" msgstr "" #: .././repair/xfs_repair.c:139 msgid "bad shared version number in superblock" msgstr "" #: .././repair/xfs_repair.c:144 #, c-format msgid "bad error code - %d\n" msgstr "" #: .././repair/xfs_repair.c:152 #, c-format msgid "-%c %s option cannot have a value\n" msgstr "" #: .././repair/xfs_repair.c:248 msgid "-o bhash option cannot be used with -m option\n" msgstr "" #: .././repair/xfs_repair.c:300 msgid "-m option cannot be used with -o bhash option\n" msgstr "" #: .././repair/xfs_repair.c:342 #, c-format msgid "" "\n" "fatal error -- " msgstr "" #: .././repair/xfs_repair.c:454 #, c-format msgid "sb root inode value % %sinconsistent with calculated value %u\n" msgstr "" #: .././repair/xfs_repair.c:461 #, c-format msgid "resetting superblock root inode pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:465 #, c-format msgid "would reset superblock root inode pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:477 #, c-format msgid "" "sb realtime bitmap inode % %sinconsistent with calculated value %u\n" msgstr "" #: .././repair/xfs_repair.c:484 #, c-format msgid "resetting superblock realtime bitmap ino pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:488 #, c-format msgid "would reset superblock realtime bitmap ino pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:500 #, c-format msgid "" "sb realtime summary inode % %sinconsistent with calculated value %u\n" msgstr "" #: .././repair/xfs_repair.c:507 #, c-format msgid "resetting superblock realtime summary ino pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:511 #, c-format msgid "would reset superblock realtime summary ino pointer to %u\n" msgstr "" #: .././repair/xfs_repair.c:554 msgid "" "Primary superblock would have been modified.\n" "Cannot proceed further in no_modify mode.\n" "Exiting now.\n" msgstr "" #: .././repair/xfs_repair.c:577 msgid "" "Cannot get host filesystem geometry.\n" "Repair may fail if there is a sector size mismatch between\n" "the image and the host filesystem.\n" msgstr "" #: .././repair/xfs_repair.c:589 msgid "" "Sector size on host filesystem larger than image sector size.\n" "Cannot turn off direct IO, so exiting.\n" msgstr "" #: .././repair/xfs_repair.c:599 #, c-format msgid "%s: cannot repair this filesystem. Sorry.\n" msgstr "" #: .././repair/xfs_repair.c:624 #, c-format msgid " - reporting progress in intervals of %s\n" msgstr "" #: .././repair/xfs_repair.c:671 #, c-format msgid "" " - max_mem = %lu, icount = %, imem = %, dblock = %" ", dmem = %\n" msgstr "" #: .././repair/xfs_repair.c:684 #, c-format msgid "" "Required memory for repair is greater that the maximum specified\n" "with the -m option. Please increase it to at least %lu.\n" msgstr "" #: .././repair/xfs_repair.c:689 #, c-format msgid "" "Not enough RAM available for repair to enable prefetching.\n" "This will be _slow_.\n" "You need at least %luMB RAM to run with prefetching enabled.\n" msgstr "" #: .././repair/xfs_repair.c:707 #, c-format msgid " - block cache size set to %d entries\n" msgstr "" #: .././repair/xfs_repair.c:736 msgid "Found unsupported filesystem features. Exiting now.\n" msgstr "" #: .././repair/xfs_repair.c:754 #, c-format msgid "No modify flag set, skipping phase 5\n" msgstr "" #: .././repair/xfs_repair.c:773 msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" msgstr "" #: .././repair/xfs_repair.c:779 msgid "Warning: no quota inodes were found. Quotas disabled.\n" msgstr "" #: .././repair/xfs_repair.c:782 msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" msgstr "" #: .././repair/xfs_repair.c:787 msgid "Warning: quota inodes were cleared. Quotas disabled.\n" msgstr "" #: .././repair/xfs_repair.c:790 msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" msgstr "" #: .././repair/xfs_repair.c:796 msgid "" "Warning: user quota information was cleared.\n" "User quotas can not be enforced until limit information is recreated.\n" msgstr "" #: .././repair/xfs_repair.c:800 msgid "" "Warning: user quota information would be cleared.\n" "User quotas could not be enforced until limit information was recreated.\n" msgstr "" #: .././repair/xfs_repair.c:808 msgid "" "Warning: group quota information was cleared.\n" "Group quotas can not be enforced until limit information is recreated.\n" msgstr "" #: .././repair/xfs_repair.c:812 msgid "" "Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n" msgstr "" #: .././repair/xfs_repair.c:820 msgid "" "Warning: project quota information was cleared.\n" "Project quotas can not be enforced until limit information is recreated.\n" msgstr "" #: .././repair/xfs_repair.c:824 msgid "" "Warning: project quota information would be cleared.\n" "Project quotas could not be enforced until limit information was recreated.\n" msgstr "" #: .././repair/xfs_repair.c:835 msgid "No modify flag set, skipping filesystem flush and exiting.\n" msgstr "" #: .././repair/xfs_repair.c:854 msgid "Note - quota info will be regenerated on next quota mount.\n" msgstr "" #: .././repair/xfs_repair.c:862 #, c-format msgid "" "Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n" msgstr "" #: .././repair/xfs_repair.c:885 msgid "done\n" msgstr "" #: .././repair/bmap.c:53 #, c-format msgid "" "Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" "If this is not a corruption, then you will need a 64 bit system\n" "to repair this filesystem.\n" msgstr "" #: .././repair/bmap.c:66 #, c-format msgid "malloc failed in blkmap_alloc (%zu bytes)\n" msgstr "" #: .././repair/bmap.c:174 #, c-format msgid "blkmap_getn malloc failed (% bytes)\n" msgstr "" #: .././repair/bmap.c:273 #, c-format msgid "" "Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" "You need a 64 bit system to repair this filesystem.\n" msgstr "" #: .././repair/bmap.c:281 #, c-format msgid "" "Number of extents requested in blkmap_grow (%d) overflowed the\n" "maximum number of supported extents (%d).\n" msgstr "" #: .././repair/bmap.c:289 msgid "realloc failed in blkmap_grow\n" msgstr "" #: .././repair/phase3.c:45 #, c-format msgid "cannot read agi block % for ag %u\n" msgstr "" #: .././repair/phase3.c:127 msgid "Phase 3 - for each AG...\n" msgstr "" #: .././repair/phase3.c:129 msgid " - scan and clear agi unlinked lists...\n" msgstr "" #: .././repair/phase3.c:131 msgid " - scan (but don't clear) agi unlinked lists...\n" msgstr "" #: .././repair/phase3.c:151 msgid " - process known inodes and perform inode discovery...\n" msgstr "" #: .././repair/phase3.c:162 msgid " - process newly discovered inodes...\n" msgstr "" #: .././rtcp/xfs_rtcp.c:30 #, c-format msgid "%s [-e extsize] [-p] source target\n" msgstr "" #: .././rtcp/xfs_rtcp.c:69 #, c-format msgid "%s: must specify files to copy\n" msgstr "" #: .././rtcp/xfs_rtcp.c:84 #, c-format msgid "%s: stat64 of %s failed\n" msgstr "" #: .././rtcp/xfs_rtcp.c:91 #, c-format msgid "%s: final argument is not directory\n" msgstr "" #: .././rtcp/xfs_rtcp.c:138 #, c-format msgid "%s: failed stat64 on %s: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:159 #, c-format msgid "%s: %s filesystem has no realtime partition\n" msgstr "" #: .././rtcp/xfs_rtcp.c:180 .././rtcp/xfs_rtcp.c:208 #, c-format msgid "%s: open of %s failed: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:197 #, c-format msgid "%s: set attributes on %s failed: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:215 #, c-format msgid "%s: get attributes of %s failed: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:260 #, c-format msgid "%s: %s is not a realtime file.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:234 #, c-format msgid "%s: %s file extent size is %d, instead of %d.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:246 .././rtcp/xfs_rtcp.c:269 #, c-format msgid "%s: open of %s source failed: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:283 #, c-format msgid "%s: couldn't get direct I/O information: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:293 #, c-format msgid "%s: extent size %d not a multiple of %d.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:307 #, c-format msgid "The size of %s is not a multiple of %d.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:310 #, c-format msgid "%s will be padded to %lld bytes.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:316 #, c-format msgid "" "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" msgstr "" #: .././rtcp/xfs_rtcp.c:358 #, c-format msgid "%s: write error: %s\n" msgstr "" #: .././rtcp/xfs_rtcp.c:386 #, c-format msgid "%s: could not open %s: %s\n" msgstr "" xfsprogs-3.1.9ubuntu2/po/de.po0000664000000000000000000152066711307015331013175 0ustar # Translation of xfsprogs to German # Copyright (C) Chris Leick , 2009. # This file is distributed under the same license as the xfsprogs package. # Chris Leick , 2009. # msgid "" msgstr "" "Project-Id-Version: xfsprogs 3.0.3\n" "Report-Msgid-Bugs-To: nathans@debian.org\n" "POT-Creation-Date: 2009-09-29 09:36-0300\n" "PO-Revision-Date: 2009-10-21 21:08+0100\n" "Last-Translator: Chris Leick \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: .././copy/xfs_copy.c:102 #, c-format msgid "Check logfile \"%s\" for more details\n" msgstr "Prüfen Sie die Protokolldatei »%s«, um mehr Details zu erhalten\n" #: .././copy/xfs_copy.c:108 #, c-format msgid "%s: could not write to logfile \"%s\".\n" msgstr "%s: Es konnte nicht in die Protokolldatei »%s« geschrieben werden.\n" #: .././copy/xfs_copy.c:111 #, c-format msgid "Aborting XFS copy -- logfile error -- reason: %s\n" msgstr "Kopieren von XFS wird abgebrochen -- Protokollfehler -- Grund: %s\n" #: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:286 .././copy/xfs_copy.c:563 #: .././copy/xfs_copy.c:570 msgid "Aborting XFS copy - reason" msgstr "Kopieren von XFS wird abgebrochen - Grund" #: .././copy/xfs_copy.c:140 msgid "THE FOLLOWING COPIES FAILED TO COMPLETE\n" msgstr "DAS VERVOLLSTÄNDIGEN DER FOLGENDEN KOPIEN SCHEITERTE\n" #: .././copy/xfs_copy.c:144 msgid "write error" msgstr "Schreibfehler" #: .././copy/xfs_copy.c:146 msgid "lseek64 error" msgstr "lseek64-Fehler" #: .././copy/xfs_copy.c:147 #, c-format msgid " at offset %lld\n" msgstr " bei Versatz %lld\n" #: .././copy/xfs_copy.c:151 #, c-format msgid "All copies completed.\n" msgstr "Alle Kopien vervollständigt.\n" #: .././copy/xfs_copy.c:154 #, c-format msgid "See \"%s\" for more details.\n" msgstr "Lesen Sie »%s«, um mehr Details zu erhalten.\n" #: .././copy/xfs_copy.c:255 #, c-format msgid "%s: write error on target %d \"%s\" at offset %lld\n" msgstr "%s: Schreibfehler auf Ziel %d »%s« bei Versatz %lld\n" #: .././copy/xfs_copy.c:260 #, c-format msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" msgstr "%s: lseek64-Fehler auf Ziel %d »%s« bei Versatz %lld\n" #: .././copy/xfs_copy.c:266 #, c-format msgid "Aborting target %d - reason" msgstr "Ziel %d wird abgebrochen - Grund" #: .././copy/xfs_copy.c:270 msgid "Aborting XFS copy - no more targets.\n" msgstr "Kopieren von XFS wird abgebrochen - keine Ziele mehr.\n" #: .././copy/xfs_copy.c:281 #, c-format msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" msgstr "%s: Thread %d unerwartet beendet, Ziel »%s« unvollständig\n" #: .././copy/xfs_copy.c:283 #, c-format msgid "%s: offset was probably %lld\n" msgstr "%s: Versatz war vermutlich %lld\n" #: .././copy/xfs_copy.c:294 #, c-format msgid "%s: Unknown child died (should never happen!)\n" msgstr "%s: Unbekannter Kindprozess beendet (sollte nie vorkommen!)\n" #: .././copy/xfs_copy.c:304 #, c-format msgid "Usage: %s [-bd] [-L logfile] source target [target ...]\n" msgstr "Aufruf: %s [-bd] [-L Protokolldatei] Quelle Ziel [Ziel ...]\n" #: .././copy/xfs_copy.c:386 #, c-format msgid "%s: lseek64 failure at offset %lld\n" msgstr "%s: lseek64-Fehlschlag bei Versatz %lld\n" #: .././copy/xfs_copy.c:401 #, c-format msgid "assert error: buf->length = %d, buf->size = %d\n" msgstr "bestätigter Fehler: buf->length = %d, buf->size = %d\n" #: .././copy/xfs_copy.c:408 #, c-format msgid "%s: read failure at offset %lld\n" msgstr "%s: Lese-Fehlschlag bei Versatz %lld\n" #: .././copy/xfs_copy.c:543 .././db/init.c:93 .././estimate/xfs_estimate.c:141 #: .././fsr/xfs_fsr.c:243 .././growfs/xfs_growfs.c:182 .././io/init.c:180 #: .././logprint/logprint.c:196 .././mkfs/xfs_mkfs.c:1362 #: .././quota/init.c:131 .././repair/xfs_repair.c:322 .././rtcp/xfs_rtcp.c:57 #, c-format msgid "%s version %s\n" msgstr "%s Version %s\n" #: .././copy/xfs_copy.c:561 #, c-format msgid "%s: couldn't open log file \"%s\"\n" msgstr "%s: Protokolldatei »%s« kann nicht geöffnet werden.\n" #: .././copy/xfs_copy.c:568 #, c-format msgid "%s: couldn't set up logfile stream\n" msgstr "%s: Protokoll-Datenstrom konnte nicht erzeugt werden\n" #: .././copy/xfs_copy.c:580 msgid "Couldn't allocate target array\n" msgstr "Ziel-Array konnte nicht bereitgestellt werden.\n" #: .././copy/xfs_copy.c:595 #, c-format msgid "%s: couldn't register atexit function.\n" msgstr "%s: atexit-Funktion konnte nicht registriert werden.\n" #: .././copy/xfs_copy.c:604 #, c-format msgid "%s: couldn't open source \"%s\"\n" msgstr "%s: Konnte Quelle »%s« nicht öffnen.\n" #: .././copy/xfs_copy.c:610 #, c-format msgid "%s: couldn't stat source \"%s\"\n" msgstr "%s: kann Quellenstatus »%s« nicht abfragen.\n" #: .././copy/xfs_copy.c:620 #, c-format msgid "%s: Cannot set direct I/O flag on \"%s\".\n" msgstr "%s: Direkte I/O-Markierung auf »%s« kann nicht gesetzt werden.\n" #: .././copy/xfs_copy.c:625 #, c-format msgid "%s: xfsctl on file \"%s\" failed.\n" msgstr "%s: xfsctl auf Datei »%s« fehlgeschlagen.\n" #: .././copy/xfs_copy.c:648 #, c-format msgid "%s: Warning -- a filesystem is mounted on the source device.\n" msgstr "%s: Warnung -- ein Dateisystem ist auf dem Quellgerät eingehängt.\n" #: .././copy/xfs_copy.c:651 msgid "\t\tGenerated copies may be corrupt unless the source is\n" msgstr "" "\t\tGenerierte Kopien könnten fehlerhaft sein, sofern die Quelle nicht\n" #: .././copy/xfs_copy.c:653 msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" msgstr "" "\t\tabgehängt oder nur mit Lesezugriff eingehängt ist.\n" "\t\tKopieren durchführen ...\n" #: .././copy/xfs_copy.c:670 #, c-format msgid "" "%s: couldn't initialize XFS library\n" "%s: Aborting.\n" msgstr "" "%s: XFS-Bibliothek konnte nicht initialisiert werden.\n" "%s: Abbruch.\n" #: .././copy/xfs_copy.c:684 #, c-format msgid "" "%s: %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" "%s: %s-Dateisystem konnte nicht initialisiert werden.\n" "%s: Abbruch.\n" #: .././copy/xfs_copy.c:688 #, c-format msgid "" "%s %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" "%s: %s-Dateisystem konnte nicht initialisiert werden.\n" "%s: Abbruch.\n" #: .././copy/xfs_copy.c:692 #, c-format msgid "" "%s: %s has an external log.\n" "%s: Aborting.\n" msgstr "" "%s: %s hat ein externes Protokoll.\n" "%s: Abbruch.\n" #: .././copy/xfs_copy.c:696 #, c-format msgid "" "%s: %s has a real-time section.\n" "%s: Aborting.\n" msgstr "" "%s: %s hat einen Echtzeit-Bereich.\n" "%s: Abbruch.\n" #: .././copy/xfs_copy.c:721 msgid "" "Error: filesystem block size is smaller than the disk sectorsize.\n" "Aborting XFS copy now.\n" msgstr "" "Fehler: Die Blockgröße des Dateisystems ist kleiner als die Sektorgröße\n" "der Platte. XFS-Kopieren wird nun abgebrochen.\n" #: .././copy/xfs_copy.c:742 #, c-format msgid "Creating file %s\n" msgstr "Datei %s wird erzeugt.\n" #: .././copy/xfs_copy.c:760 #, c-format msgid "" "%s: a filesystem is mounted on target device \"%s\".\n" "%s cannot copy to mounted filesystems. Aborting\n" msgstr "" "%s: Ein Dateisystem ist auf dem Zielgerät »%s« eingehängt.\n" "%s kann nicht auf eingehängte Dateisysteme schreiben. Abbruch\n" #: .././copy/xfs_copy.c:771 #, c-format msgid "%s: couldn't open target \"%s\"\n" msgstr "%s: Ziel »%s« kann nicht geöffnet werden.\n" #: .././copy/xfs_copy.c:781 #, c-format msgid "%s: cannot grow data section.\n" msgstr "%s: Datenbereich kann nicht vergrößert werden.\n" #: .././copy/xfs_copy.c:789 #, c-format msgid "%s: xfsctl on \"%s\" failed.\n" msgstr "%s: xfsctl auf »%s« fehlgeschlagen.\n" #: .././copy/xfs_copy.c:808 #, c-format msgid "%s: failed to write last block\n" msgstr "%s: Letzter Block konnte nicht geschrieben werden.\n" #: .././copy/xfs_copy.c:810 #, c-format msgid "\tIs target \"%s\" too small?\n" msgstr "\tIst das Ziel »%s« zu klein?\n" #: .././copy/xfs_copy.c:820 msgid "Couldn't initialize global thread mask\n" msgstr "Globale Thread-Maske kann nicht initialisiert werden\n" #: .././copy/xfs_copy.c:827 msgid "Error initializing wbuf 0\n" msgstr "Fehler beim Initialisieren von wbuf 0\n" #: .././copy/xfs_copy.c:835 msgid "Error initializing btree buf 1\n" msgstr "Fehler beim Initialisieren von btree buf 1\n" #: .././copy/xfs_copy.c:840 msgid "Error creating first semaphore.\n" msgstr "Fehler beim Erstellen des ersten Semaphor.\n" #: .././copy/xfs_copy.c:855 msgid "Couldn't malloc space for thread args\n" msgstr "" "Für die Thread-Argumente konnte kein Speicherplatz bereit\n" "gestellt werden.\n" #: .././copy/xfs_copy.c:867 #, c-format msgid "Error creating thread mutex %d\n" msgstr "Fehler beim Erzeugen des Thread-Mutex %d\n" #: .././copy/xfs_copy.c:884 #, c-format msgid "Error creating thread for target %d\n" msgstr "Fehler beim Erzeugen des Threads für Ziel %d\n" #: .././copy/xfs_copy.c:974 msgid "WARNING: source filesystem inconsistent.\n" msgstr "WARNUNG: Quell-Dateisystem ist nicht konsistent.\n" #: .././copy/xfs_copy.c:976 msgid " A leaf btree rec isn't a leaf. Aborting now.\n" msgstr " Ein Blatt »btree rec« ist kein Blatt. Es wird nun abgebrochen.\n" #: .././db/check.c:372 msgid "free block usage information" msgstr "Information über freie Blöcke" #: .././db/check.c:375 msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." msgstr "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." #: .././db/check.c:376 msgid "get block usage and check consistency" msgstr "Blockbenutzung erhalten und Konsistenz prüfen" #: .././db/check.c:379 msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." msgstr "" "[-n Anzahl] [-x Mindestlänge] [-y Maximallänge] [-s füllen] [-0123] " "[-t Typ] ..." #: .././db/check.c:380 msgid "trash randomly selected block(s)" msgstr "zufällig ausgewähle Blöcke wegwerfen" #: .././db/check.c:383 msgid "[-n] [-c blockcount]" msgstr "[-n] [-c Blockanzahl]" #: .././db/check.c:384 msgid "print usage for current block(s)" msgstr "Benutzung für aktuelle Blöcke ausgeben" #: .././db/check.c:387 msgid "[-s] [-i ino] ..." msgstr "[-s] [-i ino] ..." #: .././db/check.c:388 msgid "print inode-name pairs" msgstr "Inode-Namenspaare ausgeben" #: .././db/check.c:408 #, c-format msgid "-i %lld bad inode number\n" msgstr "-i %lld falsche Inode-Nummer\n" #: .././db/check.c:420 #, c-format msgid "inode %lld add link, now %u\n" msgstr "Inode %lld Verweis hinzufügen, nun %u\n" #: .././db/check.c:447 #, c-format msgid "inode %lld parent %lld\n" msgstr "Inode %lld Übergeordnet %lld\n" #: .././db/check.c:760 msgid "block usage information not allocated\n" msgstr "Blockbenutzungsinformationen nicht zugeteilt\n" #: .././db/check.c:798 msgid "already have block usage information\n" msgstr "Blockbenutzungsinformationen bereits erhalten\n" #: .././db/check.c:814 .././db/check.c:922 msgid "WARNING: this may be a newer XFS filesystem.\n" msgstr "WARNUNG: Dies könnte ein neueres XFS-Dateisystem sein\n" #: .././db/check.c:850 #, c-format msgid "sb_icount %lld, counted %lld\n" msgstr "sb_icount %lld, gezählt %lld\n" #: .././db/check.c:856 #, c-format msgid "sb_ifree %lld, counted %lld\n" msgstr "sb_ifree %lld, gezählt %lld\n" #: .././db/check.c:862 #, c-format msgid "sb_fdblocks %lld, counted %lld\n" msgstr "sb_fdblocks %lld, gezählt %lld\n" #: .././db/check.c:868 #, c-format msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" msgstr "sb_fdblocks %lld, gesamte AGF-Anzahl %lld\n" #: .././db/check.c:874 #, c-format msgid "sb_frextents %lld, counted %lld\n" msgstr "sb_frextents %lld, gezählt %lld\n" #: .././db/check.c:881 #, c-format msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" msgstr "sb_features2 (0x%x) entspricht nicht sb_bad_features2 (0x%x)\n" #: .././db/check.c:890 #, c-format msgid "sb versionnum missing attr bit %x\n" msgstr "sb-Versionsnummer fehlt attr-Bit %x\n" #: .././db/check.c:897 #, c-format msgid "sb versionnum missing nlink bit %x\n" msgstr "sb-Versionsnummer fehlt nlink-Bit %x\n" #: .././db/check.c:904 #, c-format msgid "sb versionnum missing quota bit %x\n" msgstr "sb-Versionsnummer fehlt Quota-Bit %x\n" #: .././db/check.c:911 #, c-format msgid "sb versionnum extra align bit %x\n" msgstr "zusätzliches sb-Versionsnummerausrichtungs-Bit %x\n" #: .././db/check.c:951 msgid "zeroed" msgstr "auf Null gesetzt" #: .././db/check.c:951 msgid "set" msgstr "setze" #: .././db/check.c:951 msgid "flipped" msgstr "umgeblättert" #: .././db/check.c:951 msgid "randomized" msgstr "randomisiert" #: .././db/check.c:961 #, c-format msgid "can't read block %u/%u for trashing\n" msgstr "Block %u/%u zum Wegwerfen kann nicht gelesen werden\n" #: .././db/check.c:991 #, c-format msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" msgstr "blocktrash: %u/%u %s Block %d Bit%s startet %d:%d %s\n" #: .././db/check.c:1023 .././db/check.c:1180 msgid "must run blockget first\n" msgstr "zuerst muss blockget ausgeführt werden\n" #: .././db/check.c:1067 #, c-format msgid "bad blocktrash count %s\n" msgstr "falsche blocktrash-Anzahl %s\n" #: .././db/check.c:1081 #, c-format msgid "bad blocktrash type %s\n" msgstr "falscher blocktrash-Typ %s\n" #: .././db/check.c:1090 #, c-format msgid "bad blocktrash min %s\n" msgstr "falsches blocktrash-Minimum %s\n" #: .././db/check.c:1098 #, c-format msgid "bad blocktrash max %s\n" msgstr "falsches blocktrash-Maximum %s\n" #: .././db/check.c:1103 msgid "bad option for blocktrash command\n" msgstr "falscher Option für blocktrash-Befehl\n" #: .././db/check.c:1108 msgid "bad min/max for blocktrash command\n" msgstr "falsches Minimum/Maximum für blocktrash-Befehl\n" #: .././db/check.c:1134 msgid "blocktrash: no matching blocks\n" msgstr "blocktrash: keine passenden Blöcke\n" #: .././db/check.c:1138 #, c-format msgid "blocktrash: seed %u\n" msgstr "blocktrash: %u füllen\n" #: .././db/check.c:1196 #, c-format msgid "bad blockuse count %s\n" msgstr "falsche blockuse-Anzahl %s\n" #: .././db/check.c:1202 .././db/check.c:1887 msgid "must run blockget -n first\n" msgstr "zuerst muss »blockget -n« ausgeführt werden\n" #: .././db/check.c:1208 msgid "bad option for blockuse command\n" msgstr "falsche Option für Befehl blockuse\n" #: .././db/check.c:1215 #, c-format msgid "block %llu (%u/%u) type %s" msgstr "Block %llu (%u/%u) Typ %s" #: .././db/check.c:1219 #, c-format msgid " inode %lld" msgstr "Inode %lld" #: .././db/check.c:1257 #, c-format msgid "block %u/%u expected type %s got %s\n" msgstr "Block %u/%u erwartete Typ %s bekam %s\n" #: .././db/check.c:1289 #, c-format msgid "blocks %u/%u..%u claimed by inode %lld\n" msgstr "Blöcke %u/%u..%u werden von Inode %lld beansprucht\n" #: .././db/check.c:1297 #, c-format msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" msgstr "Block %u/%u von Inode %lld beansprucht, vorherige inum %lld\n" #: .././db/check.c:1326 #, c-format msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" msgstr "" "keine Übereinstimmung bei Verweisanzahl für Inode %lld (Name %s), " "nlink %d, gezählt %d\n" #: .././db/check.c:1334 #, c-format msgid "disconnected inode %lld, nlink %d\n" msgstr "getrennter Inode %lld, nlink %d\n" #: .././db/check.c:1338 #, c-format msgid "allocated inode %lld has 0 link count\n" msgstr "zugeteilter Inode %lld hat Verweisanzahl 0\n" #: .././db/check.c:1348 #, c-format msgid "inode %lld name %s\n" msgstr "Inode %lld Name %s\n" #: .././db/check.c:1382 .././db/check.c:1397 #, c-format msgid "block %u/%u out of range\n" msgstr "Block %u/%u außerhalb des Bereichs\n" #: .././db/check.c:1385 .././db/check.c:1400 #, c-format msgid "blocks %u/%u..%u out of range\n" msgstr "Blöcke %u/%u..%u außerhalb des Bereichs\n" #: .././db/check.c:1423 #, c-format msgid "rtblock %llu expected type %s got %s\n" msgstr "rtblock %llu erwartete Typ %s bekam %s\n" #: .././db/check.c:1443 #, c-format msgid "rtblocks %llu..%llu claimed by inode %lld\n" msgstr "" "rtblocks %llu..%llu von Inode %lld beansprucht\n" #: .././db/check.c:1452 #, c-format msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" msgstr "rtblock %llu von Inode %lld beansprucht, vorheriger inum %lld\n" #: .././db/check.c:1470 #, c-format msgid "root inode %lld is missing\n" msgstr "Wurzel-Inode %lld fehlt\n" #: .././db/check.c:1475 #, c-format msgid "root inode %lld is not a directory\n" msgstr "Wurzel-Inode %lld ist kein Verzeichnis\n" #: .././db/check.c:1491 #, c-format msgid "rtblock %llu out of range\n" msgstr "rtblock %llu außerhalb des Bereichs\n" #: .././db/check.c:1515 #, c-format msgid "blocks %u/%u..%u claimed by block %u/%u\n" msgstr "Blöcke %u/%u..%u von Block %u/%u beansprucht\n" #: .././db/check.c:1524 #, c-format msgid "setting block %u/%u to %s\n" msgstr "Block %u/%u wird auf %s gesetzt\n" #: .././db/check.c:1547 #, c-format msgid "setting rtblock %llu to %s\n" msgstr "rtblock %llu wird auf %s gesetzt\n" #: .././db/check.c:1568 .././repair/rt.c:151 #, c-format msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" msgstr "" "rt-Zusammenfassung stimmt nicht überein, Größe %d Block %llu, Datei: %d,\n" "berechnet: %d\n" #: .././db/check.c:1593 #, c-format msgid "block %u/%u type %s not expected\n" msgstr "Block %u/%u Typ %s nicht erwartet\n" #: .././db/check.c:1614 #, c-format msgid "rtblock %llu type %s not expected\n" msgstr "rtblock %llu Typ %s nicht erwartet\n" #: .././db/check.c:1651 #, c-format msgid "dir ino %lld missing leaf entry for %x/%x\n" msgstr "dir ino %lld fehlt der Blatteintrag für %x/%x\n" #: .././db/check.c:1770 #, c-format msgid "bad superblock magic number %x, giving up\n" msgstr "falsche Magische Nummer %x von Superblock, es wird aufgegeben\n" #: .././db/check.c:1824 msgid "bad option for blockget command\n" msgstr "falsche Option für blockget-Befehl\n" #: .././db/check.c:1904 #, c-format msgid "bad option -%c for ncheck command\n" msgstr "falsche Option -%c für ncheck-Befehl\n" #: .././db/check.c:1977 .././db/check.c:2944 #, c-format msgid "block 0 for directory inode %lld is missing\n" msgstr "Block 0 für Verzeichnis-Inode %lld fehlt\n" #: .././db/check.c:1997 .././db/check.c:2955 #, c-format msgid "can't read block 0 for directory inode %lld\n" msgstr "Block 0 für Verzeichnis-Inode %lld kann nicht gelesen werden\n" #: .././db/check.c:2043 #, c-format msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" msgstr "Inode %lld Umfang [%lld,%lld,%lld,%d]\n" #: .././db/check.c:2046 #, c-format msgid "bmap rec out of order, inode %lld entry %d\n" msgstr "bmap rec außer Betrieb, Inode %lld Eintrag %d \n" #: .././db/check.c:2052 #, c-format msgid "inode %lld bad rt block number %lld, offset %lld\n" msgstr "Inode %lld falsche rt-Blocknummer %lld, Versatz %lld\n" #: .././db/check.c:2062 .././db/check.c:2068 #, c-format msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" msgstr "Inode %lld falsche Block-Nummer %lld [%d,%d], Versatz %lld\n" #: .././db/check.c:2086 .././db/check.c:2100 #, c-format msgid "inode %lld block %lld at offset %lld\n" msgstr "Inode %lld Block %lld bei Versatz %lld\n" #: .././db/check.c:2128 #, c-format msgid "level for ino %lld %s fork bmap root too large (%u)\n" msgstr "Stufe für ino %lld %s-Fork bmap-Wurzel zu groß (%u)\n" #: .././db/check.c:2131 .././db/check.c:2143 .././db/check.c:2170 #: .././db/bmap.c:216 .././repair/scan.c:153 .././repair/dinode.c:631 #: .././repair/dinode.c:1178 msgid "data" msgstr "Daten" #: .././db/check.c:2131 .././db/check.c:2143 .././db/check.c:2170 #: .././db/bmap.c:216 .././repair/scan.c:155 .././repair/dinode.c:633 #: .././repair/dinode.c:1180 msgid "attr" msgstr "attr" #: .././db/check.c:2140 #, c-format msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" msgstr "numrecs für ino %lld %s-Fork bmap-Wurzel zu groß (%u)\n" #: .././db/check.c:2167 .././repair/dinode.c:1291 #, c-format msgid "extent count for ino %lld %s fork too low (%d) for file format\n" msgstr "Umfanganzahl für ino %lld %s-Fork zu niedrig (%d) für Dateiformat\n" #: .././db/check.c:2217 .././db/check.c:3295 #, c-format msgid "bad directory data magic # %#x for dir ino %lld block %d\n" msgstr "falsche magische Verzeichnisdaten-# %#x für ino %lld Block %d\n" #: .././db/check.c:2234 #, c-format msgid "bad block directory tail for dir ino %lld\n" msgstr "falsches Verzeichnisblockende für dir ino %lld\n" #: .././db/check.c:2279 #, c-format msgid "dir %lld block %d bad free entry at %d\n" msgstr "dir %lld Block %d falscher freier Eintrag bei %d\n" #: .././db/check.c:2303 #, c-format msgid "dir %lld block %d zero length entry at %d\n" msgstr "dir %lld Block %d Eintrag der Länge Null bei %d\n" #: .././db/check.c:2312 #, c-format msgid "dir %lld block %d bad entry at %d\n" msgstr "dir %lld Block %d falscher Eintrag bei %d\n" #: .././db/check.c:2330 #, c-format msgid "dir %lld block %d entry %*.*s %lld\n" msgstr "dir %lld Block %d Eintrag %*.*s %lld\n" #: .././db/check.c:2337 #, c-format msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" msgstr "dir %lld Block %d Eintrag %*.*s falsche Inode-Nummer %lld\n" #: .././db/check.c:2347 .././db/check.c:3018 #, c-format msgid "multiple .. entries in dir %lld (%lld, %lld)\n" msgstr "mehrere .. Einträge in dir %lld (%lld, %lld)\n" #: .././db/check.c:2364 .././db/check.c:3035 #, c-format msgid "dir %lld entry . inode number mismatch (%lld)\n" msgstr "dir %lld Eintrag . Inode-Nummer stimmt nicht überein (%lld)\n" #: .././db/check.c:2377 #, c-format msgid "dir %lld block %d bad count %u\n" msgstr "dir %lld Block %d falsche Anzahl %u\n" #: .././db/check.c:2388 .././db/check.c:3309 #, c-format msgid "dir %lld block %d extra leaf entry %x %x\n" msgstr "dir %lld Block %d zusätzlicher Blatteintrag %x %x\n" #: .././db/check.c:2400 #, c-format msgid "dir %lld block %d bad bestfree data\n" msgstr "dir %lld Block %d falsche bestfree-Daten\n" #: .././db/check.c:2408 #, c-format msgid "dir %lld block %d bad block tail count %d (stale %d)\n" msgstr "dir %lld Block %d falsche Blockgrößenanzahl %d (abgelaufen %d)\n" #: .././db/check.c:2417 #, c-format msgid "dir %lld block %d bad stale tail count %d\n" msgstr "dir %lld Block %d falsche Anzahl abgelaufener Blöcke %d\n" #: .././db/check.c:2423 #, c-format msgid "dir %lld block %d consecutive free entries\n" msgstr "dir %lld Block %d aufeinander folgende freie Einträge\n" #: .././db/check.c:2429 #, c-format msgid "dir %lld block %d entry/unused tag mismatch\n" msgstr "dir %lld Block %d Eintrag/nichtbenutzte Markierung passt nicht\n" #: .././db/check.c:2482 #, c-format msgid "no . entry for directory %lld\n" msgstr "kein .-Eintrag für Verzeichnis %lld\n" #: .././db/check.c:2487 #, c-format msgid "no .. entry for directory %lld\n" msgstr "kein ..-Eintrag für Verzeichnis %lld\n" #: .././db/check.c:2491 #, c-format msgid ". and .. same for non-root directory %lld\n" msgstr ".- und ..-Einträge für Nicht-Wurzelverzeichnis %lld gleich\n" #: .././db/check.c:2496 #, c-format msgid "root directory %lld has .. %lld\n" msgstr "Wurzelverzeichnis %lld hat .. %lld\n" #: .././db/check.c:2526 .././db/check.c:2561 #, c-format msgid "bad size (%lld) or format (%d) for directory inode %lld\n" msgstr "falsche Größe (%lld) oder Format (%d) für Verzeichnis-Inode %lld\n" #: .././db/check.c:2589 #, c-format msgid "bad number of extents %d for inode %lld\n" msgstr "falsche Anzahl von Ausweitungen %d für Inode %lld\n" #: .././db/check.c:2659 #, c-format msgid "bad magic number %#x for inode %lld\n" msgstr "falsche Magische Nummer %#x für Inode %lld\n" #: .././db/check.c:2666 #, c-format msgid "bad version number %#x for inode %lld\n" msgstr "falsche Versionsnummer %#x für Inode %lld\n" #: .././db/check.c:2674 #, c-format msgid "bad nblocks %lld for free inode %lld\n" msgstr "falsche nblocks %lld für freien Inode %lld\n" #: .././db/check.c:2685 #, c-format msgid "bad nlink %d for free inode %lld\n" msgstr "falscher nlink %d für freien Inode %lld\n" #: .././db/check.c:2691 #, c-format msgid "bad mode %#o for free inode %lld\n" msgstr "falscher Modus %#o für freien Inode %lld\n" #: .././db/check.c:2699 #, c-format msgid "bad next unlinked %#x for inode %lld\n" msgstr "falsche nächste gelöste Verknüpfung %#x für Inode %lld\n" #: .././db/check.c:2709 #, c-format msgid "bad format %d for inode %lld type %#o\n" msgstr "falsches Format %d für Inode %lld Typ %#o\n" #: .././db/check.c:2716 #, c-format msgid "bad fork offset %d for inode %lld\n" msgstr "falsche Abspaltungsversatz %d für Inode %lld\n" #: .././db/check.c:2723 #, c-format msgid "bad attribute format %d for inode %lld\n" msgstr "falsches Attributformat %d für Inode %lld\n" #: .././db/check.c:2729 #, c-format msgid "" "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s" "%s%s\n" msgstr "" "Inode %lld Modus %#o fmt %s afmt %s nex %d anex %d nblk %lld sz " "%lld%s%s%s%s%s%s%s\n" #: .././db/check.c:2849 #, c-format msgid "bad nblocks %lld for inode %lld, counted %lld\n" msgstr "falsche nblocks %lld für Inode %lld, gezählt %lld\n" #: .././db/check.c:2856 #, c-format msgid "bad nextents %d for inode %lld, counted %d\n" msgstr "falsche nextents %d für Inode %lld, gezählt %d\n" #: .././db/check.c:2862 #, c-format msgid "bad anextents %d for inode %lld, counted %d\n" msgstr "falsche anextents %d für Inode %lld, gezählt %d\n" #: .././db/check.c:2914 #, c-format msgid "local inode %lld data is too large (size %lld)\n" msgstr "" "lokales Inode-%lld-Daten-Unterelement ist zu groß (Größe = %lld)\n" #: .././db/check.c:2923 #, c-format msgid "local inode %lld attr is too large (size %d)\n" msgstr "lokales Inode-%lld-attr ist zu groß (Größe = %d)\n" #: .././db/check.c:2988 #, c-format msgid "bad directory leaf magic # %#x for dir ino %lld\n" msgstr "falsche magische Verzeichnis-Blatt # %#x für dir ino %lld\n" #: .././db/check.c:3001 .././db/check.c:3766 #, c-format msgid "dir %lld entry %*.*s %lld\n" msgstr "dir %lld Eintrag %*.*s %lld\n" #: .././db/check.c:3008 .././db/check.c:3662 .././db/check.c:3754 #, c-format msgid "dir %lld entry %*.*s bad inode number %lld\n" msgstr "dir %lld Eintrag %*.*s falsche Inode-Nummer %lld\n" #: .././db/check.c:3087 .././db/check.c:3356 #, c-format msgid "dir inode %lld block %u=%llu\n" msgstr "dir inode %lld Block %u=%llu\n" #: .././db/check.c:3099 .././db/check.c:3366 #, c-format msgid "can't read block %u for directory inode %lld\n" msgstr "Block %u für Verzeichnis-Inode %lld kann nicht gelesen werden\n" #: .././db/check.c:3113 .././db/check.c:3379 #, c-format msgid "multiple .. entries in dir %lld\n" msgstr "mehrfache .. Einträge in Verzeichnis-Inode %lld\n" #: .././db/check.c:3135 #, c-format msgid "missing free index for data block %d in dir ino %lld\n" msgstr "freier Index für Datenblock %d in dir ino %lld fehlt\n" #: .././db/check.c:3161 #, c-format msgid "bad free block magic # %#x for dir ino %lld block %d\n" msgstr "falsche frei magische Block-# %#x für ino %lld Block %d\n" #: .././db/check.c:3171 #, c-format msgid "bad free block firstdb %d for dir ino %lld block %d\n" msgstr "falscher freier Block firstdb %d für dir ino %lld Block %d\n" #: .././db/check.c:3184 #, c-format msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" msgstr "falscher freier Block nvalid/nused %d/%d für dir ino %lld Block %d\n" #: .././db/check.c:3198 #, c-format msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" msgstr "" "falscher freier Block ent %d ist %d, sollte %d sein für dir ino %lld " "Block %d\n" #: .././db/check.c:3212 #, c-format msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" msgstr "" "falscher freier nused-Block %d sollte %d sein für dir ino %lld Block %d\n" #: .././db/check.c:3241 #, c-format msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" msgstr "" "Falscher Blattblock Vorwärts-/Rückwärtszeiger %d/%d für dir ino %lld Block " "%d\n" #: .././db/check.c:3250 #, c-format msgid "single leaf block for dir ino %lld block %d should be at block %d\n" msgstr "" "einzelner Blattblock für dir ino %lld Block %d sollte bei Block %d sein\n" #: .././db/check.c:3262 #, c-format msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" msgstr "" "bestfree %d für dir ino %lld Block %d passt nicht zu Tabellenwert %d\n" #: .././db/check.c:3286 #, c-format msgid "bad node block level %d for dir ino %lld block %d\n" msgstr "falsche Knotenblockstufe %d für dir ino %lld Block %d\n" #: .././db/check.c:3318 #, c-format msgid "dir %lld block %d stale mismatch %d/%d\n" msgstr "dir %lld Block %d abgelaufene Nichtübereinstimmung %d/%d\n" #: .././db/check.c:3350 #, c-format msgid "can't read root block for directory inode %lld\n" msgstr "Block für Verzeichnis-Inode %lld kann nicht gelesen werden\n" #: .././db/check.c:3439 #, c-format msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" msgstr "" "Block %lld für %s Quota-Inode (fsblock %lld) kann nicht gelesen " "werden\n" #: .././db/check.c:3449 #, c-format msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" msgstr "%s dqblk %lld Eintrag %d id %u bc %lld ic %lld rc %lld\n" #: .././db/check.c:3457 #, c-format msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" msgstr "falsche Magische Nummer %#x für %s dqblk %lld Eintrag %d ID %u\n\n" #: .././db/check.c:3466 #, c-format msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" msgstr "falsche Versionsnummer %#x für %s dqblk %lld Eintrag %d ID %u\n" #: .././db/check.c:3476 #, c-format msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" msgstr "Falsche Markierungen %#x für %s dqblk %lld Eintrag %d ID %u\n" #: .././db/check.c:3485 #, c-format msgid "bad id %u for %s dqblk %lld entry %d id %u\n" msgstr "falsche ID %u für %s dqblk %lld Eintrag %d ID %u\n" #: .././db/check.c:3531 #, c-format msgid "block %lld for rtbitmap inode is missing\n" msgstr "Block %lld für rtbitmap-Inode fehlt\n" #: .././db/check.c:3542 #, c-format msgid "can't read block %lld for rtbitmap inode\n" msgstr "Block %lld für rtbitmap-Inode kann nicht gelesen werden\n" #: .././db/check.c:3598 #, c-format msgid "block %lld for rtsummary inode is missing\n" msgstr "Block %lld für rtsummary-Inode fehlt\n" #: .././db/check.c:3609 #, c-format msgid "can't read block %lld for rtsummary inode\n" msgstr "Block %lld für rtsummary-Inode kann nicht gelesen werden\n" #: .././db/check.c:3642 .././db/check.c:3746 #, c-format msgid "dir %lld entry . %lld\n" msgstr "dir %lld Eintrag . %lld\n" #: .././db/check.c:3650 #, c-format msgid "dir %llu bad size in entry at %d\n" msgstr "dir %llu falsche Größe im Eintrag bei %d\n" #: .././db/check.c:3674 #, c-format msgid "dir %lld entry %*.*s offset %d %lld\n" msgstr "dir %lld Eintrag %*.*s Versatz %d %lld\n" #: .././db/check.c:3679 #, c-format msgid "dir %lld entry %*.*s bad offset %d\n" msgstr "dir %lld Eintrag %*.*s falscher Versatz %d\n" #: .././db/check.c:3692 #, c-format msgid "dir %llu size is %lld, should be %u\n" msgstr "dir %llu Größe ist %lld, sollte %u sein\n" #: .././db/check.c:3700 #, c-format msgid "dir %llu offsets too high\n" msgstr "dir %llu Versätze zu groß\n" #: .././db/check.c:3711 .././db/check.c:3780 #, c-format msgid "dir %lld entry .. bad inode number %lld\n" msgstr "dir %lld Eintrag .. falsche Inode-Nummer %lld\n" #: .././db/check.c:3716 .././db/check.c:3785 #, c-format msgid "dir %lld entry .. %lld\n" msgstr "dir %lld Eintrag .. %lld\n" #: .././db/check.c:3719 #, c-format msgid "dir %lld i8count mismatch is %d should be %d\n" msgstr "dir %lld i8count Nichtübereinstimmung ist %d sollte %d sein\n" #: .././db/check.c:3771 #, c-format msgid "dir %llu size is %lld, should be %d\n" msgstr "dir %llu Größe ist %lld, sollte %d sein\n" #: .././db/check.c:3862 #, c-format msgid "%s quota id %u, have/exp" msgstr "%s Quota-ID %u, have/exp" #: .././db/check.c:3865 #, c-format msgid " bc %lld/%lld" msgstr " bc %lld/%lld" #: .././db/check.c:3869 #, c-format msgid " ic %lld/%lld" msgstr " ic %lld/%lld" #: .././db/check.c:3873 #, c-format msgid " rc %lld/%lld" msgstr " rc %lld/%lld" #: .././db/check.c:3929 #, c-format msgid "can't read superblock for ag %u\n" msgstr "Superblock für ag %u kann nicht gelesen werden\n" #: .././db/check.c:3938 #, c-format msgid "bad sb magic # %#x in ag %u\n" msgstr "falsche magische sb-# %#x in ag %u\n" #: .././db/check.c:3944 #, c-format msgid "bad sb version # %#x in ag %u\n" msgstr "falsche sb-Version # %#x in ag %u\n" #: .././db/check.c:3954 .././db/sb.c:201 msgid "mkfs not completed successfully\n" msgstr "mkfs nicht erfolgreich vervollständigt\n" #: .././db/check.c:3966 .././db/frag.c:368 #, c-format msgid "can't read agf block for ag %u\n" msgstr "agf-Block für ag %u kann nicht gelesen werden\n" #: .././db/check.c:3972 #, c-format msgid "bad agf magic # %#x in ag %u\n" msgstr "falsche magische agf-# %#x in ag %u\n" #: .././db/check.c:3978 #, c-format msgid "bad agf version # %#x in ag %u\n" msgstr "falsche agf-Version # %#x im ag %u\n" #: .././db/check.c:3994 .././db/frag.c:377 #, c-format msgid "can't read agi block for ag %u\n" msgstr "agi-Block für ag %u kann nicht gelesen werden\n" #: .././db/check.c:4000 #, c-format msgid "bad agi magic # %#x in ag %u\n" msgstr "falsche magische agi-# %#x in ag %u\n" #: .././db/check.c:4006 #, c-format msgid "bad agi version # %#x in ag %u\n" msgstr "falsche agi-Version # %#x in ag %u\n" #: .././db/check.c:4031 #, c-format msgid "agf_freeblks %u, counted %u in ag %u\n" msgstr "agf_freeblks %u, gezählt %u in ag %u\n" #: .././db/check.c:4038 #, c-format msgid "agf_longest %u, counted %u in ag %u\n" msgstr "agf_longest %u, gezählt %u in ag %u\n" #: .././db/check.c:4046 #, c-format msgid "agf_btreeblks %u, counted %u in ag %u\n" msgstr "agf_btreeblks %u, gezählt %u in ag %u\n" #: .././db/check.c:4054 #, c-format msgid "agi_count %u, counted %u in ag %u\n" msgstr "agi_count %u, gezählt %u in ag %u\n" #: .././db/check.c:4061 #, c-format msgid "agi_freecount %u, counted %u in ag %u\n" msgstr "agi_freecount %u, gezählt %u in ag %u\n" #: .././db/check.c:4070 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" msgstr "agi gelöster Verweis Behälter %d ist %u in ag %u (Inode=%lld)\n" #: .././db/check.c:4107 #, c-format msgid "can't read agfl block for ag %u\n" msgstr "agfl-Block für ag %u kann nicht gelesen werden\n" #: .././db/check.c:4126 #, c-format msgid "freeblk count %u != flcount %u in ag %u\n" msgstr "freeblk-Anzahl %u != flcount %u in ag %u\n" #: .././db/check.c:4155 .././db/check.c:4183 .././db/frag.c:400 #: .././db/frag.c:423 .././db/freesp.c:270 #, c-format msgid "can't read btree block %u/%u\n" msgstr "btree-Block %u/%u kann nicht gelesen werden\n" #: .././db/check.c:4216 #, c-format msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" msgstr "falsche magische # %#x in Inode %lld bmbt-Block %u/%u\n" #: .././db/check.c:4223 #, c-format msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" msgstr "erwartete Stufe %d hat %d in Inode %lld bmbt-Block %u/%u\n" #: .././db/check.c:4235 .././db/check.c:4252 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" msgstr "" "falsche btree nrecs (%u, Min=%u, Max=%u) in Inode %lld bmap-Block %lld\n" #: .././db/check.c:4280 #, c-format msgid "bad magic # %#x in btbno block %u/%u\n" msgstr "falsche magische # %#x in btbno-Block %u/%u\n" #: .././db/check.c:4289 #, c-format msgid "expected level %d got %d in btbno block %u/%u\n" msgstr "erwartete Stufe %d hat %d in btbno-Block %u/%u\n" #: .././db/check.c:4298 .././db/check.c:4326 .././db/check.c:4371 #: .././db/check.c:4402 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" msgstr "falsche btree nrecs (%u, Min=%u, Max=%u) in btbno-Block %u/%u\n" #: .././db/check.c:4313 #, c-format msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" msgstr "außer Betreib bno btree Datensatz %d (%u %u) Block %u/%u\n" #: .././db/check.c:4353 #, c-format msgid "bad magic # %#x in btcnt block %u/%u\n" msgstr "falsche magische # %#x in btcnt-Block %u/%u\n" #: .././db/check.c:4362 #, c-format msgid "expected level %d got %d in btcnt block %u/%u\n" msgstr "erwartete Stufe %d hat %d in btcnt-Block %u/%u\n" #: .././db/check.c:4390 #, c-format msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" msgstr "außer Betreib cnt btree Datensatz %d (%u %u) Block %u/%u\n" #: .././db/check.c:4433 #, c-format msgid "bad magic # %#x in inobt block %u/%u\n" msgstr "falsche magische # %#x in inobt-Block %u/%u\n" #: .././db/check.c:4440 #, c-format msgid "expected level %d got %d in inobt block %u/%u\n" msgstr "erwartete Stufe %d hat %d in inobt-Block %u/%u\n" #: .././db/check.c:4449 .././db/check.c:4515 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" msgstr "falsche btree nrecs (%u, Min=%u, Max=%u) in inobt-Block %u/%u\n" #: .././db/check.c:4484 .././db/frag.c:493 #, c-format msgid "can't read inode block %u/%u\n" msgstr "btree-Block %u/%u kann nicht gelesen werden\n" #: .././db/check.c:4502 #, c-format msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" msgstr "" "ir_freecount/free Nichtübereinstimmung, Inode Speicherstück %u/%u, " "freecount %d nfree %d\n" #: .././db/check.c:4557 #, c-format msgid "setting inode to %lld for block %u/%u\n" msgstr "Inode wird auf %lld gesetzt für Block %u/%u\n" #: .././db/check.c:4589 #, c-format msgid "setting inode to %lld for rtblock %llu\n" msgstr "Inode wird auf %lld gesetzt für rtblock %llu\n" #: .././db/check.c:4605 #, c-format msgid "inode %lld nlink %u %s dir\n" msgstr "Inode %lld nlink %u %s dir\n" #: .././db/addr.c:35 msgid "[field-expression]" msgstr "[Feldausdruck]" #: .././db/addr.c:36 msgid "set current address" msgstr "derzeitige Adresse setzen" #: .././db/addr.c:42 msgid "" "\n" " 'addr' uses the given field to set the filesystem address and type\n" "\n" " Examples:\n" "\n" " sb\n" " a rootino - set the type to inode and set position to the root inode\n" " a u.bmx[0].startblock (for inode with blockmap)\n" "\n" msgstr "" "\n" " »addr« benutzt das gegebene Feld, um die Dateisystemadresse und den Typ\n" " zu setzen\n" "\n" " Beispiele:\n" "\n" " sb\n" " ein Wurzel-ino - setzt den Typ auf Inode und setzt die Position auf den\n" " Wurzel-Inode\n" " ein u.bmx[0].startblock (für Inode mit blockmap)\n" "\n" #: .././db/addr.c:72 .././db/attrset.c:86 .././db/attrset.c:189 #: .././db/print.c:74 .././db/type.c:102 .././db/write.c:101 msgid "no current type\n" msgstr "kein aktueller Typ\n" #: .././db/addr.c:82 #, c-format msgid "no fields for type %s\n" msgstr "keine Felder für Typ %s\n" #: .././db/addr.c:95 msgid "array not allowed for addr command\n" msgstr "Array nicht für addr-Befehl erlaubt\n" #: .././db/addr.c:105 #, c-format msgid "no next type for field %s\n" msgstr "kein nächster Typ für Feld %s\n" #: .././db/addr.c:112 #, c-format msgid "no addr function for field %s (type %s)\n" msgstr "keine addr-Funktion für Feld %s (Typ %s)\n" #: .././db/frag.c:173 #, c-format msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" msgstr "aktuell %llu, ideal %llu, Unterteilungsfaktor %.2f%%\n" #: .././db/frag.c:214 msgid "bad option for frag command\n" msgstr "falsche Opzion für frag-Befehl\n" #: .././db/frag.c:352 #, c-format msgid "inode %lld actual %lld ideal %lld\n" msgstr "Inode %lld aktuell %lld ideal %lld\n" #: .././db/frag.c:446 .././db/frag.c:457 #, c-format msgid "invalid numrecs (%u) in %s block\n" msgstr "ungültige numrecs (%u) in %s-Block\n" #: .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 .././db/agf.c:35 msgid "[agno]" msgstr "[agno]" #: .././db/agfl.c:37 msgid "set address to agfl block" msgstr "Adresse auf agfl Block setzen" #: .././db/agfl.c:63 msgid "" "\n" " set allocation group freelist\n" "\n" " Example:\n" "\n" " agfl 5\n" " Located in the fourth sector of each allocation group,\n" " the agfl freelist for internal btree space allocation is maintained\n" " for each allocation group. This acts as a reserved pool of space\n" " separate from the general filesystem freespace (not used for user data).\n" "\n" msgstr "" "\n" " Zuteilungsgruppen-freelist setzen\n" "\n" " Beispiel:\n" "\n" " agfl 5\n" " Die agfl freelist, die sich für interne btree-Speicherzuteilung im\n" " vierten Abschnitt jeder Zuteilungsgruppe befindet, wird für jede\n" " Zuteilungsgruppe verwaltet. Dies agiert als ein reservierter Speicherpool\n" " getrennt vom allgemeinen Dateisystem-freespace (nicht für Benutzerdaten\n" " benutzt).\n" "\n" #: .././db/agfl.c:90 .././db/agi.c:89 .././db/sb.c:151 .././db/agf.c:104 #, c-format msgid "bad allocation group number %s\n" msgstr "falsche Zuteilungsgruppennummer %s\n" #: .././db/agi.c:36 msgid "set address to agi header" msgstr "Adressen auf agi-Kopfzeilen setzen" #: .././db/agi.c:64 msgid "" "\n" " set allocation group inode btree\n" "\n" " Example:\n" "\n" " agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" "\n" " Located in the 3rd 512 byte block of each allocation group,\n" " the agi inode btree tracks all used/free inodes in the allocation group.\n" " Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" "\n" msgstr "" "\n" " Zuteilungsgruppen-Inode btree setzen\n" "\n" " Beispiel:\n" "\n" " agi 3 (setzt Ort auf 3. Zuteilungsgruppen-Inode btree und Typ auf " "»agi«)\n" "\n" " Der im dritten 512-Byte-Block von jeder Zuteilungsruppe gelegene\n" " agi-Inode btree spürt alle benutzten/freien Inodes in der\n" " Zuteilungsgruppe auf. Inodes sind in 16k-»chunks« zugeteilt, jeder\n" " btree-Eintrag folgt einem »chunk«.\n" "\n" #: .././db/attrset.c:38 msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" msgstr "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] Name" #: .././db/attrset.c:39 msgid "set the named attribute on the current inode" msgstr "das Namens-Attribut des aktuellen Inodes setzen" #: .././db/attrset.c:42 msgid "[-r|-s|-p|-u] [-n] name" msgstr "[-r|-s|-p|-u] [-n] Name" #: .././db/attrset.c:43 msgid "remove the named attribute from the current inode" msgstr "das genannte Attribut aus dem aktuellen Inode entfernen" #: .././db/attrset.c:49 msgid "" "\n" " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" " the extended attribute allocation and removal code.\n" " Both commands require an attribute name to be specified, and the attr_set\n" " command allows an optional value length (-v) to be provided as well.\n" " There are 4 namespace flags:\n" " -r -- 'root'\n" " -u -- 'user'\t\t(default)\n" " -s -- 'secure'\n" "\n" " For attr_set, these options further define the type of set operation:\n" " -C -- 'create' - create attribute, fail if it already exists\n" " -R -- 'replace' - replace attribute, fail if it does not exist\n" " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" "\n" msgstr "" "\n" " Die »attr_set«- und xattr_remove«-Befehle stellen Schittstellen für die\n" " Fehlersuche in der erweiterten Attributszuteilung und Code-Entfernung\n" " zur Verfügung. Beide Befehle benötigen zur Angabe einen Attributs-Namen\n" " und der attr_set-Befehl erlaubt außerdem die Angabe einer optionalen\n" " Wertlänge (-v).\n" " Es gibt vier Namensraumkennzeichen:\n" " -r -- 'root'\n" " -u -- 'user'\t\t(Vorgabe)\n" " -s -- 'secure'\n" "\n" " Für attr-set definieren diese Optionen weiterhin den Typ der\n" " Einstelloperation:\n" " -C -- »createy - erzeugt Attribut, scheitert, wenn es bereits besteht\n" " -R -- »replace« - ersetzt Attribut, scheitert, wenn es nicht besteht\n" " Außerdem kann der Rückwärtskompatibilitätsmodus »noattr2« (-n) emuliert\n" " werden.\n" #: .././db/attrset.c:90 .././db/attrset.c:193 msgid "current type is not inode\n" msgstr "aktueller Typ ist nicht Inode\n" #: .././db/attrset.c:125 #, c-format msgid "bad attr_set valuelen %s\n" msgstr "falsche attr_set valuelen %s\n" #: .././db/attrset.c:131 msgid "bad option for attr_set command\n" msgstr "falsche Option für attr_set-Befehl\n" #: .././db/attrset.c:137 msgid "too few options for attr_set (no name given)\n" msgstr "zu wenige Optionen für attr_set (kein Name angegeben)\n" #: .././db/attrset.c:147 #, c-format msgid "cannot allocate buffer (%d)\n" msgstr "Puffer (%d) kann nicht zugeteilt werden\n" #: .././db/attrset.c:156 .././db/attrset.c:231 #, c-format msgid "failed to iget inode %llu\n" msgstr "iget von Inode %llu fehlgeschlagen\n" #: .././db/attrset.c:162 #, c-format msgid "failed to set attr %s on inode %llu\n" msgstr "attr %s auf Inode %llu zu setzen ist fehlgeschlagen\n" #: .././db/attrset.c:217 msgid "bad option for attr_remove command\n" msgstr "falsche Option für attr_remove-Befehl\n" #: .././db/attrset.c:223 msgid "too few options for attr_remove (no name given)\n" msgstr "zu wenige Optionen für attr_remove (kein Name angegeben)\n" #: .././db/attrset.c:237 #, c-format msgid "failed to remove attr %s from inode %llu\n" msgstr "Entfernen von attr %s von Inode %llu fehlgeschlagen\n" #: .././db/block.c:43 .././db/block.c:49 msgid "filoff" msgstr "filoff" #: .././db/block.c:44 msgid "set address to file offset (attr fork)" msgstr "Adresse auf Dateiversatz setzen (attr fork)" #: .././db/block.c:46 msgid "[d]" msgstr "[d]" #: .././db/block.c:47 msgid "set address to daddr value" msgstr "Adresse auf daddr-Wert setzen" #: .././db/block.c:50 msgid "set address to file offset (data fork)" msgstr "Adresse auf Dateiversatz setzen (Daten-fork)" #: .././db/block.c:52 msgid "[fsb]" msgstr "[fsb]" #: .././db/block.c:53 msgid "set address to fsblock value" msgstr "Adresse auf fsblock-Wert setzen" #: .././db/block.c:59 msgid "" "\n" " Example:\n" "\n" " 'ablock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's attribute fork. The filesystem block size is specified in\n" " the superblock.\n" "\n" msgstr "" "\n" " Beispiel:\n" "\n" " »ablock 23« - setzt die Dateiposition auf den 23. Dateisystemblock im\n" " Attributs-Fork des Inodes. Die Dateisystemblockgröße ist im Superblock\n" " angegeben.\n" "\n" #: .././db/block.c:82 .././db/block.c:177 #, c-format msgid "bad block number %s\n" msgstr "falsche Blocknummer %s\n" #: .././db/block.c:90 msgid "no attribute data for file\n" msgstr "Attributsdaten für Datei\n" #: .././db/block.c:96 msgid "file attr block is unmapped\n" msgstr "attr-Block der Datei ist nicht abgebildet\n" #: .././db/block.c:119 msgid "" "\n" " Example:\n" "\n" " 'daddr 102' - sets position to the 102nd absolute disk block\n" " (512 byte block).\n" msgstr "" "\n" " Beispiel:\n" "\n" " »daddr 102« - setzt Position auf den 102. absoluten Plattenblock\n" " (512 Byte-Block).\n" #: .././db/block.c:135 #, c-format msgid "current daddr is %lld\n" msgstr "aktuelle daddr ist %lld\n" #: .././db/block.c:141 #, c-format msgid "bad daddr %s\n" msgstr "falsche daddr %s\n" #: .././db/block.c:153 msgid "" "\n" " Example:\n" "\n" " 'dblock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's data fork. The filesystem block size is specified in the\n" " superblock.\n" "\n" msgstr "" "\n" " Beispiel:\n" "\n" " »dblock 23« - setzt die Dateiposition auf den 23. Dateisystemblock im\n" " Daten-Fork des Inodes. Die Dateisystemblockgröße ist im Superblock\n" " angegeben.\n" "\n" #: .././db/block.c:185 msgid "no type for file data\n" msgstr "kein Typ für Dateidaten\n" #: .././db/block.c:192 msgid "file data block is unmapped\n" msgstr "Dateidatenblock ist nicht abgebildet\n" #: .././db/block.c:210 msgid "" "\n" " Example:\n" "\n" " 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" " The filesystem block size is specified in the superblock and set during\n" " mkfs time. Offset is absolute (not AG relative).\n" "\n" msgstr "" "\n" " Beispiel:\n" "\n" " »fsblock 1023« - setzt die Dateiposition auf den 1023. Dateisystemblock.\n" " Die Dateisystemblockgröße ist im Superblock angegeben und wurde während \n" " der mkfs-Zeit gesetzt. Versatz ist absolut (nicht AG-relativ).\n" "\n" #: .././db/block.c:229 #, c-format msgid "current fsblock is %lld\n" msgstr "aktueller fsblock ist %lld\n" #: .././db/block.c:235 .././db/block.c:241 #, c-format msgid "bad fsblock %s\n" msgstr "falscher fsblock %s\n" #: .././db/bmap.c:39 msgid "[-ad] [block [len]]" msgstr "[-ad] [Block [len]]" #: .././db/bmap.c:40 msgid "show block map for current file" msgstr "Blockkarte für aktuelle Datei anzeigen" #: .././db/bmap.c:153 .././db/inode.c:386 msgid "no current inode\n" msgstr "kein aktueller Inode\n" #: .././db/bmap.c:166 msgid "bad option for bmap command\n" msgstr "falsche Option für bmap-Befehl\n" #: .././db/bmap.c:183 #, c-format msgid "bad block number for bmap %s\n" msgstr "falsche Blocknummer für bmap %s\n" #: .././db/bmap.c:191 #, c-format msgid "bad len for bmap %s\n" msgstr "falsche len für bmap %s\n" #: .././db/bmap.c:214 #, c-format msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" msgstr "%s Versatz %lld Startblock %llu (%u/%u) zählt %llu Flag %u\n" #: .././db/command.c:82 .././db/help.c:56 .././libxcmd/help.c:49 #, c-format msgid "command %s not found\n" msgstr "Befehl %s nicht gefunden\n" #: .././db/command.c:86 #, c-format msgid "bad argument count %d to %s, expected " msgstr "falsche Argument-Anzahl %d bis %s, erwartet" #: .././db/command.c:88 #, c-format msgid "at least %d" msgstr "mindestens %d" #: .././db/command.c:92 #, c-format msgid "between %d and %d" msgstr "zwischen %d und %d" #: .././db/command.c:93 msgid " arguments\n" msgstr "Argumente\n" #: .././db/convert.c:171 #, c-format msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" msgstr "falsche Argument-Anzahl %d zu konvertieren, 3,5,7,9 Argumente erwartet\n" #: .././db/convert.c:176 .././db/convert.c:183 #, c-format msgid "unknown conversion type %s\n" msgstr "unbekannte Umwandlungstyp %s\n" #: .././db/convert.c:187 msgid "result type same as argument\n" msgstr "Ergebnistyp entspricht Argument\n" #: .././db/convert.c:191 #, c-format msgid "conflicting conversion type %s\n" msgstr "widersprüchlicher Umwandlungstyp %s\n" #: .././db/convert.c:270 #, c-format msgid "%s is not a number\n" msgstr "%s ist keine Zahl\n" #: .././db/debug.c:27 msgid "[flagbits]" msgstr "[flagbits]" #: .././db/debug.c:28 msgid "set debug option bits" msgstr "Bits für Fehlersuchoptionen setzen" #: .././db/debug.c:42 #, c-format msgid "bad value for debug %s\n" msgstr "falscher Wert für Fehlersuche %s\n" #: .././db/dquot.c:37 msgid "[projid|gid|uid]" msgstr "[projid|gid|uid]" #: .././db/dquot.c:38 msgid "set current address to project, group or user quota block" msgstr "aktuelle Adresse auf Projekt, Gruppe oder Benutzer-Quota setzen" #: .././db/dquot.c:124 msgid "bad option for dquot command\n" msgstr "falsche Option für dquot-Befehl\n" #: .././db/dquot.c:128 .././quota/project.c:347 msgid "project" msgstr "Projekt" #: .././db/dquot.c:128 msgid "group" msgstr "Gruppe" #: .././db/dquot.c:128 msgid "user" msgstr "Benutzer" #: .././db/dquot.c:130 #, c-format msgid "dquot command requires one %s id argument\n" msgstr "dquot-Befehl benötigt ein %s ID-Argument\n" #: .././db/dquot.c:137 #, c-format msgid "no %s quota inode present\n" msgstr "kein %s Quota-Inode vorhanden\n" #: .././db/dquot.c:142 #, c-format msgid "bad %s id for dquot %s\n" msgstr "falsche %s ID für dquot %s\n" #: .././db/dquot.c:154 #, c-format msgid "no %s quota data for id %d\n" msgstr "keine %s Quota-Daten für ID %d\n" #: .././db/echo.c:27 msgid "[args]..." msgstr "[args] ..." #: .././db/echo.c:28 msgid "echo arguments" msgstr "echo Argumente" #: .././db/faddr.c:40 .././db/faddr.c:63 msgid "no current allocation group, cannot set new addr\n" msgstr "" "keine aktuelle Zuteilungsgruppe, neue addr kann nicht gesetzt werden\n" #: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 #: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 #: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 msgid "null block number, cannot set new addr\n" msgstr "Nullblocknummer, neue addr kann nicht gesetzt werden\n" #: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 #: .././db/faddr.c:389 msgid "null inode number, cannot set new addr\n" msgstr "Null-Inode-Nummer, neue addr kann nicht gesetzt werden\n" #: .././db/faddr.c:88 msgid "null attribute block number, cannot set new addr\n" msgstr "Null-Attributsblocknummer, neue addr kann nicht gesetzt werden\n" #: .././db/faddr.c:94 msgid "attribute block is unmapped\n" msgstr "Attributsblock ist unmapped\n" #: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 #: .././db/faddr.c:239 msgid "file block is unmapped\n" msgstr "Dateiblock ist unmapped\n" #: .././db/faddr.c:285 msgid "null directory block number, cannot set new addr\n" msgstr "Null-Verzeichnisblocknummer, neue addr kann nicht gesetzt werden\n" #: .././db/faddr.c:292 msgid "directory block is unmapped\n" msgstr "Verzeichnisblock ist unmapped\n" #: .././db/flist.c:149 #, c-format msgid "field %s not found\n" msgstr "Feld %s nicht gefunden\n" #: .././db/flist.c:159 #, c-format msgid "no elements in %s\n" msgstr "keine Elemente in %s\n" #: .././db/flist.c:165 #, c-format msgid "indices %d-%d for field %s out of range %d-%d\n" msgstr "Indizes %d-%d für Feld %s außerhalb des Bereichs %d-%d\n" #: .././db/flist.c:173 #, c-format msgid "index %d for field %s out of range %d-%d\n" msgstr "Index %d für Feld %s außerhalb des Bereichs %d-%d\n" #: .././db/flist.c:187 #, c-format msgid "field %s is not an array\n" msgstr "Feld %s ist kein Array\n" #: .././db/flist.c:200 #, c-format msgid "field %s has no subfields\n" msgstr "Feld %s hat keine Unterfelder\n" #: .././db/flist.c:220 #, c-format msgid "fl@%p:\n" msgstr "fl@%p:\n" #: .././db/flist.c:221 #, c-format msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" msgstr "\tName=%s, fld=%p, Kind=%p, Geschwister=%p\n" #: .././db/flist.c:223 #, c-format msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" msgstr "\tniedrig=%d, hoch=%d, Kennzeichen=%d (%s%s), Versatz=%d\n" #: .././db/flist.c:225 msgid "oklow " msgstr "oklow" #: .././db/flist.c:226 msgid "okhigh" msgstr "okhigh" #: .././db/flist.c:227 #, c-format msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" msgstr "\tfld->name=%s, fld->ftyp=%d (%s)\n" #: .././db/flist.c:230 #, c-format msgid "\tfld->flags=%d (%s%s%s%s%s)\n" msgstr "\tfld->flags=%d (%s%s%s%s%s)\n" #: .././db/flist.c:322 #, c-format msgid "bad syntax in field name %s\n" msgstr "falsche Syntax in Feldname %s\n" #: .././db/flist.c:378 #, c-format msgid "missing closing quote %s\n" msgstr "fehlendes schließendes Anführungszeichen %s\n" #: .././db/flist.c:395 #, c-format msgid "bad character in field %s\n" msgstr "falsches Zeichen in Feld %s\n" #: .././db/fprint.c:98 msgid "null" msgstr "null" #: .././db/freesp.c:106 #, c-format msgid "total free extents %lld\n" msgstr "gesamte freie Extents %lld\n" #: .././db/freesp.c:107 #, c-format msgid "total free blocks %lld\n" msgstr "gesamte freie Blöcke %lld\n" #: .././db/freesp.c:108 #, c-format msgid "average free extent size %g\n" msgstr "durchschnittliche freie Extent-Größe %g\n" #: .././db/freesp.c:199 msgid "" "freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" msgstr "" "freesp-Argumente: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" #: .././db/freesp.c:400 msgid "from" msgstr "von" #: .././db/freesp.c:400 msgid "to" msgstr "bis" #: .././db/freesp.c:400 .././repair/progress.c:26 msgid "extents" msgstr "Extents" #: .././db/freesp.c:400 .././repair/progress.c:18 msgid "blocks" msgstr "Blöcke" #: .././db/freesp.c:400 msgid "pct" msgstr "pct" #: .././db/hash.c:30 msgid "string" msgstr "Zeichenkette" #: .././db/hash.c:31 msgid "calculate hash value" msgstr "Hash-Wert berechnen" #: .././db/hash.c:37 msgid "" "\n" " 'hash' prints out the calculated hash value for a string using the\n" "directory/attribute code hash function.\n" "\n" " Usage: \"hash \"\n" "\n" msgstr "" "\n" "»hash« gibt den berechneten Hash-Wert für eine Zeichenkette unter\n" "Benutzung der Verzeichnis-/Code-Hash-Funktion aus .\n" "\n" "Aufruf: »hash «\n" "\n" #: .././db/help.c:30 .././db/io.c:48 .././libxcmd/help.c:92 msgid "[command]" msgstr "[Befehl]" #: .././db/help.c:31 .././libxcmd/help.c:93 msgid "help for one or all commands" msgstr "Hilfe für einen oder alle Befehle" #: .././db/help.c:40 .././libxcmd/help.c:33 #, c-format msgid "" "\n" "Use 'help commandname' for extended help.\n" msgstr "" "\n" "»help Befehlsname« benutzen, um erweitere Hilfe zu erhalten.\n" #: .././db/help.c:89 #, c-format msgid "(or %s) " msgstr "(oder %s) " #: .././db/init.c:46 #, c-format msgid "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" msgstr "Aufruf: %s [-fFrxV] [-p Programm] [-l logdev] [-c Befehl]... Gerät\n" #: .././db/init.c:112 msgid "" "\n" "fatal error -- couldn't initialize XFS library\n" msgstr "" "\n" "fataler Fehler -- XFS-Bibliothek kann nicht initialisiert werden\n" #: .././db/init.c:118 #, c-format msgid "%s: %s is invalid (cannot read first 512 bytes)\n" msgstr "" "%s: %s ist ungültig (die ersten 512 Bytes können nicht gelesen werden)\n" #: .././db/init.c:129 #, c-format msgid "" "%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" msgstr "" "%s: %s ist kein gültige XFS-Dateisystem (unerwartete SB Magische\n" "Nummer 0x%08x)\n" #: .././db/init.c:141 #, c-format msgid "%s: device %s unusable (not an XFS filesystem?)\n" msgstr "%s: Gerät %s unbenutzbar (kein XFS-Dateisystem?)\n" #: .././db/inode.c:381 #, c-format msgid "bad value for inode number %s\n" msgstr "falscher Wert für Inode-Nummer %s\n" #: .././db/inode.c:388 #, c-format msgid "current inode number is %lld\n" msgstr "aktuelle Inode-Nummer ist %lld\n" #: .././db/inode.c:596 #, c-format msgid "bad inode number %lld\n" msgstr "falsche Inode-Nummer %lld\n" #: .././db/input.c:43 msgid "source-file" msgstr "Quelldatei" #: .././db/input.c:44 msgid "get commands from source-file" msgstr "Befehle aus Quelldatei beziehen" #: .././db/input.c:320 #, c-format msgid "can't open %s\n" msgstr "%s kann nicht geöffnet werden\n" #: .././db/io.c:46 msgid "pop location from the stack" msgstr "Ort vom Stack hervorholen" #: .././db/io.c:49 msgid "push location to the stack" msgstr "Ort auf den Stack bewegen" #: .././db/io.c:52 msgid "view the location stack" msgstr "den Stack-Ort ansehen" #: .././db/io.c:55 msgid "move forward to next entry in the position ring" msgstr "vorwärts zum nächsten Eintrag im Positionsring bewegen" #: .././db/io.c:58 msgid "move to the previous location in the position ring" msgstr "zum vorherigen Ort im Positionsring bewegen" #: .././db/io.c:61 msgid "show position ring or move to a specific entry" msgstr "Positionsring anzeigen oder zu einem bestimmten Eintrag bewegen" #: .././db/io.c:91 #, c-format msgid "can't set block offset to %d\n" msgstr "Blockversatz kann nicht auf %d gesetzt werden\n" #: .././db/io.c:104 msgid "can't pop anything from I/O stack\n" msgstr "vom I/O-Stack kann nichts hervorgeholt werden\n" #: .././db/io.c:132 msgid "" "\n" " Changes the address and data type to the first entry on the stack.\n" "\n" msgstr "" "\n" " Ändert die Adresse und den Datentyp auf den ersten Eintrag auf dem\n" " Stack.\n" "\n" #: .././db/io.c:146 #, c-format msgid "\tbyte offset %lld, length %d\n" msgstr "\tByte Versatz %lld, Länge %d\n" #: .././db/io.c:147 #, c-format msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" msgstr "\tPufferblock %lld (fsbno %lld), %d bb%s\n" #: .././db/io.c:151 msgid "\tblock map" msgstr "\tBlockekarte" #: .././db/io.c:156 #, c-format msgid "\tinode %lld, dir inode %lld, type %s\n" msgstr "\tInode %lld, dir Inode %lld, Typ %s\n" #: .././db/io.c:157 .././growfs/xfs_growfs.c:86 .././logprint/log_misc.c:151 #: .././mkfs/xfs_mkfs.c:1666 #, c-format msgid "none" msgstr "keine" #: .././db/io.c:167 msgid "no entries in location ring.\n" msgstr "keine Einträge im Positionsring.\n" #: .././db/io.c:171 msgid " type bblock bblen fsbno inode\n" msgstr " Typ bblock bblen fsbno Inode\n" #: .././db/io.c:225 #, c-format msgid "no such command %s\n" msgstr "kein solcher Befehl -- %s\n" #: .././db/io.c:229 #, c-format msgid "no push form allowed for %s\n" msgstr "keine Verschiebeform für %s erlaubt\n" #: .././db/io.c:253 msgid "" "\n" " Allows you to push the current address and data type on the stack for\n" " later return. 'push' also accepts an additional command to execute after\n" " storing the current address (ex: 'push a rootino' from the superblock).\n" "\n" msgstr "" "\n" " Erlaubt Ihnen die aktuelle Adresse und den Datentyp für eine spätere\n" " Rückgabe auf den Stack zu verschieben. »push« akzeptiert außerdem die\n" " Ausführung eines zusätzlichen Befehls nach dem Speichern der aktuellen\n" " Adresse (z.B.: »push a rootino« von einem Superblock).\n" "\n" #: .././db/io.c:269 .././db/io.c:310 msgid "ring is empty\n" msgstr "Ring ist leer\n" #: .././db/io.c:273 msgid "no further entries\n" msgstr "keine weiteren Einträge\n" #: .././db/io.c:293 msgid "" "\n" " The 'forward' ('f') command moves to the next location in the position\n" " ring, updating the current position and data type. If the current " "location\n" " is the top entry in the ring, then the 'forward' command will have\n" " no effect.\n" "\n" msgstr "" "\n" " Der »forward«-Befehl (»f«) bewegt zum nächsten Ort im Positionsring und\n" " aktualisiert dabei die aktuelle Position und den Datentyp. Wenn der\n" " aktuelle Ort der oberste Eintrag im Ring ist, dann hat der\n" " »forward«-Befehl keine Auswirkung.\n" "\n" #: .././db/io.c:314 msgid "no previous entries\n" msgstr "keine vorherigen Einträge\n" #: .././db/io.c:334 msgid "" "\n" " The 'back' ('b') command moves to the previous location in the position\n" " ring, updating the current position and data type. If the current " "location\n" " is the last entry in the ring, then the 'back' command will have no " "effect.\n" "\n" msgstr "" "\n" " Der »back«-Befehl (»b«) bewegt zum vorherigen Ort im Positionsring und\n" " aktualisiert dabei die aktuelle Position und den Datentyp. Wenn der\n" " aktuelle Ort der letzte Eintrag im Ring ist, dann hat der\n" "»forward«-Befehl keine Auswirkung.\n" "\n" #: .././db/io.c:357 #, c-format msgid "invalid entry: %d\n" msgstr "ungültiger Eintrag: %d\n" #: .././db/io.c:374 #, c-format msgid "" "\n" " The position ring automatically keeps track of each disk location and\n" " structure type for each change of position you make during your xfs_db\n" " session. The last %d most recent entries are kept in the ring.\n" "\n" " To display the current list of ring entries type 'ring' by itself on\n" " the command line. The entry highlighted by an asterisk ('*') is the\n" " current entry.\n" "\n" " To move to another entry in the ring type 'ring ' where is\n" " your desired entry from the ring position list.\n" "\n" " You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" " to the previous or next entry in the ring, respectively.\n" "\n" " Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" " location implicitly. Use the 'push' and 'pop' commands if you wish to\n" " store a specific location explicitly for later return.\n" "\n" msgstr "" "\n" " Der Positionsring verfolgt automatisch jeden Plattenort und -Strukturtyp\n" " von jeder Positionsänderung, die Sie während einer xfs_db-Sitzung\n" " vornehmen. Die aktuellsten %d Einträge werden im Ring behalten.\n" "\n" " Um die aktuelle Liste der Ringeinträge anzuzeigen tippen Sie\n" " selbstständig »ring« auf der Befehlszeile ein. Der von einem Stern (»*«)\n" " hervorgehobene Eintrag ist der aktuelle Eintrag.\n" "\n" " Um sich zu einem anderen Eintrag im Ring zu bewegen, tippen Sie\n" " »Ring « wobei Ihr gewümschter Eintrag von der\n" " Ringpositionsliste ist.\n" "\n" " Sie könnten außerdem die »forward«- (»f«) oder »back« (»b«) -Befehle\n" " benutzen, um sich zum vorherigen beziehungsweise nächsten Eintrag im Ring\n" " zu bewegen.\n" "\n" " Anmerkung: Anders als bei den »stack«-, »push«- und »pop«-Befehlen,\n" " verfolgt der Ring vorbehaltlos ihrem Ort. Benutzen Sie die »push«- und\n" " »pop«-Befehle, wenn Sie einen bestimmten Ort für eine spätere Rückkehr\n" " ausdrücklich speichern möchten.\n" "\n" #: .././db/io.c:438 .././db/io.c:481 #, c-format msgid "can't seek in filesystem at bb %lld\n" msgstr "im Dateisystem kann nicht bei bb %lld gesucht werden\n" #: .././db/io.c:515 msgid "nothing to write\n" msgstr "nichts zu schreiben\n" #: .././db/io.c:521 #, c-format msgid "incomplete write, block: %lld\n" msgstr "unvollständig geschrieben, Block: %lld\n" #: .././db/io.c:524 #, c-format msgid "write error: %s\n" msgstr "Schreibfehler: %s\n" #: .././db/io.c:529 #, c-format msgid "incomplete read, block: %lld\n" msgstr "unvollständig gelesen, Block: %lld\n" #: .././db/io.c:532 #, c-format msgid "read error: %s\n" msgstr "Lesefehler: %s\n" #: .././db/io.c:548 msgid "set_cur no stack element to set\n" msgstr "set_cur kein Stack-Element zu setzen\n" #: .././db/io.c:554 #, c-format msgid "xfs_db got a bbmap for %lld\n" msgstr "xfs_db hat eine bbmap für %lld\n" #: .././db/io.c:585 msgid "" "\n" " The stack is used to explicitly store your location and data type\n" " for later return. The 'push' operation stores the current address\n" " and type on the stack, the 'pop' operation returns you to the\n" " position and datatype of the top entry on the stack.\n" "\n" " The 'stack' allows explicit location saves, see 'ring' for implicit\n" " position tracking.\n" "\n" msgstr "" "\n" " Der Stack wird benutzt, um Ihren Ort und Datentyp explizit für eine\n" " spätere Rückgabe zu speichern. Die »push«-Operation speichert die\n" " aktuelle Adresse und den Typ auf dem Stack, die»pop«-Operation gibt\n" " Ihnen die Position und den Datentyp des obersten Eintrags auf dem Stack\n" " zurück.\n" "\n" " Der »Stack« erlaubt explizite Ortsspeicherungen. Sehen Sie »ring« für\n" " ausdrückliche Psoitionsvefolgung.\n" "\n" #: .././db/malloc.c:27 #, c-format msgid "%s: out of memory\n" msgstr "%s: außerhalb des Speichers\n" #: .././db/metadump.c:47 msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" msgstr "[-e] [-g] [-m max_extent] [-w] [-o] Dateiname" #: .././db/metadump.c:48 msgid "dump metadata to a file" msgstr "Metadatenauszug in eine Datei" #: .././db/metadump.c:78 #, c-format msgid "" "\n" " The 'metadump' command dumps the known metadata to a compact file suitable\n" " for compressing and sending to an XFS maintainer for corruption analysis \n" " or xfs_repair failures.\n" "\n" " Options:\n" " -e -- Ignore read errors and keep going\n" " -g -- Display dump progress\n" " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" " -o -- Don't obfuscate names and extended attributes\n" " -w -- Show warnings of bad metadata information\n" "\n" msgstr "" "\n" " Der »Metadaten«-Befehl macht einen Auszug der bekannten Metadaten in eine\n" " kompakte Datei, die geeignet ist, um komprimiert und an einen\n" " XFS-Betreuer zur Beschädigungsanalyse oder xfs_repair-Ausfälle gesendet\n" " zu werden.\n" "\n" " Optionen:\n" " -e -- Lesefehler ignorieren und am Laufen halten\n" " -g -- Auszugsfortschritt anzeigen\n" " -m -- Maximale Extent-Größe in Blocks zum Kopieren angeben\n" " (Vorgabe = %d Blöcke)\n" " -o -- Namen und erweiterte Attribute nicht verschleiern\n" " -w -- Warnungen von flaschen Metadateninformationen anzeigen\n" "\n" #: .././db/output.c:30 msgid "[stop|start ]" msgstr "[stop|start ]" #: .././db/output.c:31 msgid "start or stop logging to a file" msgstr "Protokollieren in eine Datei starten oder stoppen" #: .././db/output.c:68 #, c-format msgid "logging to %s\n" msgstr "Protokollieren nach %s\n" #: .././db/output.c:70 .././db/output.c:77 msgid "no log file\n" msgstr "kein Protokolldatei\n" #: .././db/output.c:80 #, c-format msgid "already logging to %s\n" msgstr "es wird bereits nach %s protokolliet\n" #: .././db/output.c:84 #, c-format msgid "can't open %s for writing\n" msgstr "%s kann nicht zum Schreiben geöffnet werden\n" #: .././db/output.c:90 msgid "bad log command, ignored\n" msgstr "falscher Protokollbefehl, ignoriert\n" #: .././db/print.c:41 msgid "[value]..." msgstr "[Wert] ..." #: .././db/print.c:42 msgid "print field values" msgstr "Feldwerte ausgeben" #: .././db/print.c:79 #, c-format msgid "no print function for type %s\n" msgstr "keine Ausgabefunktion für Typ %s\n" #: .././db/print.c:153 msgid "(empty)\n" msgstr "(leer)\n" #: .././db/print.c:215 msgid "(empty)" msgstr "(leer)" #: .././db/print.c:275 msgid "no arguments allowed\n" msgstr "keine Argumente erlaubt\n" #: .././db/quit.c:27 msgid "exit xfs_db" msgstr "xfs_db beenden" #: .././db/sb.c:43 msgid "set current address to sb header" msgstr "aktuelle Adresse auf sb-Kopfzeilen setzen" #: .././db/sb.c:45 msgid "[uuid]" msgstr "[uuid]" #: .././db/sb.c:46 msgid "write/print FS uuid" msgstr "FS uuid schreiben/ausgeben" #: .././db/sb.c:48 msgid "[label]" msgstr "[Etikett]" #: .././db/sb.c:49 msgid "write/print FS label" msgstr "FS-Etikett schreiben/ausgeben" #: .././db/sb.c:51 msgid "[feature | [vnum fnum]]" msgstr "[feature | [vnum fnum]]" #: .././db/sb.c:52 msgid "set feature bit(s) in the sb version field" msgstr "Merkmal-Bit(s) im sb-Versionsfeld setzen" #: .././db/sb.c:124 msgid "" "\n" " set allocation group superblock\n" "\n" " Example:\n" "\n" " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" "\n" " Located in the first sector of each allocation group, the superblock\n" " contains the base information for the filesystem.\n" " The superblock in allocation group 0 is the primary. The copies in the\n" " remaining allocation groups only serve as backup for filesystem recovery.\n" " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" "\n" msgstr "" "\n" " Zuweisungsgruppen-Superblock setzen\n\n" "\n" " Beispiel:\n" "\n" " 'sb 7' - setzt Ort auf den 7. Zuweisungsgruppen-Superblock, setzt Typ auf\n" " »sb«\n" "\n" " Im ersten Abschnitt jeder Zuweisungsgruppe gelegen, enthält der\n" " Superblock die Basisinformationen des Dateisystems.\n" " Der Superblock in Zuweisungsgruppe 0 ist der Primäre. Die Kopien in den\n" " verbleibenden Zuweisungsgruppen dienen nur als Sicherung zur\n" " Wiederherstellung des Dateisystems. Die icount/ifree/fdblocks/frextents\n" " werden nur im Superblock 0 aktualisiert.\n" "\n" #: .././db/sb.c:183 #, c-format msgid "can't read superblock for AG %u\n" msgstr "Superblock für AG %u kann nicht gelesen werden\n" #: .././db/sb.c:191 #, c-format msgid "bad sb magic # %#x in AG %u\n" msgstr "falsche magische sb # %#x in AG %u\n" #: .././db/sb.c:196 #, c-format msgid "bad sb version # %#x in AG %u\n" msgstr "falsche sb-Version # %#x in AG %u\n" #: .././db/sb.c:218 msgid "aborting - external log specified for FS with an internal log\n" msgstr "" "Abbruch - externes Protokoll für FS mit einem internen Protokoll angegeben\n" #: .././db/sb.c:224 msgid "aborting - no external log specified for FS with an external log\n" msgstr "" "Abbruch - kein externes Protokoll für FS mit einem externen Protokoll\n" "angegeben\n" #: .././db/sb.c:242 msgid "ERROR: cannot find log head/tail, run xfs_repair\n" msgstr "" "FEHLER: Protokoll head/tail wurde nicht gefunden, führen Sie xfs_repair\n" "aus\n" #: .././db/sb.c:247 #, c-format msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running %s. If you are unable to mount the filesystem, then use\n" "the xfs_repair -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" "FEHLER: Das Dateisystem hat wertvolle Metadaten-Änderungen in einem\n" "Protokoll, das wiederholt werden sollte. Hängen Sie das Dateisystem ein,\n" "um das Protokoll zu wiederholen und hängen Sie es wieder aus before Sie\n" "%s erneut auszuführen. Wenn Sie außer Stande sind, das Dateisystem\n" "einzuhängen, benutzen Sie die xfs_repair-Option -L, um das Protokoll zu\n" "zerstören und versuchen Sie eine Reparatur.\n" "Beachten Sie, dass die Zerstörung des Protokolls Schaden verursachen\n" "kann -- bitte versuchen Sie, das Dateisystem einzuhängen ehe Sie dies tun.\n" #: .././db/sb.c:264 msgid "Clearing log and setting UUID\n" msgstr "Protokoll wird geleert und UUID gesetzt\n" #: .././db/sb.c:273 msgid "ERROR: cannot clear the log\n" msgstr "FEHLER: Protokoll kann nicht geleert werden\n" #: .././db/sb.c:284 msgid "" "\n" " write/print FS uuid\n" "\n" " Example:\n" "\n" " 'uuid' - print UUID\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" " 'uuid generate' - generate and write\n" " 'uuid rewrite' - copy UUID from SB 0\n" "\n" "The print function checks the UUID in each SB and will warn if the UUIDs\n" "differ between AGs (the log is not checked). The write commands will\n" "set the uuid in all AGs to either a specified value, a newly generated\n" "value or the value found in the first superblock (SB 0) respectively.\n" "As a side effect of writing the UUID, the log is cleared (which is fine\n" "on a CLEANLY unmounted FS).\n" "\n" msgstr "" "\n" " FS-uuid schreiben/ausgeben\n" "\n" " Beispiel:\n" "\n" " 'uuid' - gibt UUID aus\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - schreibt UUID\n" " 'uuid generate' - generiert und schreibt\n" " 'uuid rewrite' - kopiert UUID von SB 0\n" "\n" "Die Ausgabefunktion prüft die UUID in jedem SB und wird warnen, wenn die\n" "UUIDs sich zwischen AGs unterscheiden (das Protokoll ist nicht geprüft).\n" "Die Schreibbefehle werden die UUIDs in allen AGs entweder auf einen\n" "angegebenen Wert, einen neu generierten Wert beziehungsweise den im ersten\n" "Superblock (SB 0) gefundenen Wert setzen. Als ein Nebeneffekt des\n" "Schreibens der UUID wird das Protokoll geleert (was bei einem ORDENTLICH\n" "ausgehängten FS fein ist).\n" "\n" #: .././db/sb.c:336 .././db/sb.c:488 msgid "invalid parameters\n" msgstr "ungültige Parameter\n" #: .././db/sb.c:343 .././db/sb.c:495 .././db/sb.c:631 #, c-format msgid "%s: not in expert mode, writing disabled\n" msgstr "%s: Nicht im Expertenmodus, schreiben ausgeschaltet\n" #: .././db/sb.c:355 msgid "failed to read UUID from AG 0\n" msgstr "Lesen der UUID von AG 0 fehlgeschlagen\n" #: .././db/sb.c:360 #, c-format msgid "old UUID = %s\n" msgstr "alte UUID = %s\n" #: .././db/sb.c:363 msgid "invalid UUID\n" msgstr "ungültige UUID\n" #: .././db/sb.c:372 .././db/sb.c:500 .././db/sb.c:699 msgid "writing all SBs\n" msgstr "Schreiben aller SBs\n" #: .././db/sb.c:375 #, c-format msgid "failed to set UUID in AG %d\n" msgstr "UUID in AG %d zu setzen fehlgeschlagen\n" #: .././db/sb.c:380 #, c-format msgid "new UUID = %s\n" msgstr "neue UUID = %s\n" #: .././db/sb.c:388 #, c-format msgid "failed to read UUID from AG %d\n" msgstr "Lesen der UUID von AG %d fehlgeschlagen\n" #: .././db/sb.c:394 #, c-format msgid "warning: UUID in AG %d differs to the primary SB\n" msgstr "Warnung:UUID in AG %d unterscheidet sich vom primären SB\n" #: .././db/sb.c:405 msgid "warning - external log specified for FS with an internal log\n" msgstr "" "Warnung - externes Protokoll für FS mit einem internen Protokoll angegeben\n" #: .././db/sb.c:408 msgid "warning - no external log specified for FS with an external log\n" msgstr "" "Warnung - kein externes Protokoll für FS mit einem externen Protokoll\n" "angegeben\n" #: .././db/sb.c:413 #, c-format msgid "UUID = %s\n" msgstr "UUID = %s\n" #: .././db/sb.c:424 msgid "" "\n" " write/print FS label\n" "\n" " Example:\n" "\n" " 'label' - print label\n" " 'label 123456789012' - write label\n" " 'label --' - write an empty label\n" "\n" "The print function checks the label in each SB and will warn if the labels\n" "differ between AGs. The write commands will set the label in all AGs to the\n" "specified value. The maximum length of a label is 12 characters - use of a\n" "longer label will result in truncation and a warning will be issued.\n" "\n" msgstr "" "\n" " FS-Etikett schreiben/ausgeben\n" "\n" " Beispiel:\n" "\n" " 'label' - Etikett ausgeben\n" " 'label 123456789012' - Etikett schreiben\n" " 'label --' - ein leeres Etikett schreiben\n" "\n" "Die Ausgabefunktion prüft das Etikett in jedem SB und wird warnen, wenn\n" "sich die Etiketten zwischen AGs unterscheiden. Die Schreibbefehlewerden\n" "Etiketten in allen AGs auf den angegebenen Wert setzen. Die maximale\n" "Länge eine Etiketts ist zwölf Zeichen - Benutzen eines längeren Etiketts\n" "führt zu Kürzung und eine Warnung wird ausgegeben.\n" "\n" #: .././db/sb.c:461 #, c-format msgid "%s: truncating label length from %d to %d\n" msgstr "%s: Etikettlänge von %d auf %d kürzen\n" #: .././db/sb.c:503 #, c-format msgid "failed to set label in AG %d\n" msgstr "Setzen von Etikett in AG %d fehlgeschlagen\n" #: .././db/sb.c:506 #, c-format msgid "new label = \"%s\"\n" msgstr "neues Etikett = »%s«\n" #: .././db/sb.c:513 #, c-format msgid "failed to read label in AG %d\n" msgstr "Lesen von Etikett in AG %d fehlgeschlagen\n" #: .././db/sb.c:519 #, c-format msgid "warning: AG %d label differs\n" msgstr "Warnung: AG %d Etikett unterschiedlich\n" #: .././db/sb.c:521 #, c-format msgid "label = \"%s\"\n" msgstr "Etikett = »%s«\n" #: .././db/sb.c:531 msgid "" "\n" " set/print feature bits in sb version\n" "\n" " Example:\n" "\n" " 'version' - print current feature bits\n" " 'version extflg' - enable unwritten extents\n" " 'version attr1' - enable v1 inline extended attributes\n" " 'version attr2' - enable v2 inline extended attributes\n" " 'version log2' - enable v2 log format\n" "\n" "The version function prints currently enabled features for a filesystem\n" "according to the version field of its primary superblock.\n" "It can also be used to enable selected features, such as support for\n" "unwritten extents. The updated version is written into all AGs.\n" "\n" msgstr "" "\n" " setzen/ausgeben von Merkmal-Bits in sb-Version\n" "\n" " »version« - gibt aktuelle Merkmal-Bis aus\n" " »version extflg« - ungeschriebene Extents einschalten\n" " »version attr1« - v1 erweiterte Inline-Attribute einschalten\n" " »version attr2« - v2 erweiterte Inline-Attribute einschalten\n" " »version log2« - v2 Protokolformat einschalten\n" "\n" "Die Versionsfunktion gibt aktuell eingeschaltete Merkmale für ein\n" "Dateisystem aus, entsprechende dem Versionsfeld seines primären\n" "Superblocks. Es kann außerdem benutzt werden, um ausgewählte Merkmale\n" "einzuschalten, wie etwa Unterstützung für ungeschriebene Bereiche. Die\n" "aktualisierte Version wird in alle AGs geschrieben.\n" "\n" #: .././db/sb.c:650 msgid "unwritten extents flag is already enabled\n" msgstr "Merkaml für ungeschriebene Bereiche ist bereits eingeschaltet\n" #: .././db/sb.c:670 msgid "version 2 log format is already in use\n" msgstr "Protokollformat der Version 2 wird bereits benutzt\n" #: .././db/sb.c:693 #, c-format msgid "%s: invalid version change command \"%s\"\n" msgstr "%s: ungültiger Versionswechselbefehl »%s«\n" #: .././db/sb.c:702 #, c-format msgid "failed to set versionnum in AG %d\n" msgstr "Versionsnummer in AG %d zu setzen fehlgeschlagen\n" #: .././db/sb.c:720 #, c-format msgid "versionnum [0x%x+0x%x] = %s\n" msgstr "versionnum [0x%x+0x%x] = %s\n" #: .././db/type.c:50 msgid "[newtype]" msgstr "[newtype]" #: .././db/type.c:51 msgid "set/show current data type" msgstr "aktuellen Datentyp setzen/anzeigen" #: .././db/type.c:104 #, c-format msgid "current type is \"%s\"\n" msgstr "aktueller Typ ist »%s«\n" #: .././db/type.c:106 msgid "" "\n" " supported types are:\n" " " msgstr "" "\n" " unterstützte Typen sind:\n" " " #: .././db/type.c:121 #, c-format msgid "no such type %s\n" msgstr "kein solcher Typ %s\n" #: .././db/type.c:124 msgid "no current object\n" msgstr "kein aktuelles Objekt\n" #: .././db/write.c:41 msgid "[field or value]..." msgstr "[Feld oder Wert] ..." #: .././db/write.c:42 msgid "write value to disk" msgstr "Wert auf Platte schreiben" #: .././db/write.c:58 msgid "" "\n" " The 'write' command takes on different personalities depending on the\n" " type of object being worked with.\n" "\n" " Write has 3 modes:\n" " 'struct mode' - is active anytime you're looking at a filesystem object\n" " which contains individual fields (ex: an inode).\n" " 'data mode' - is active anytime you set a disk address directly or set\n" " the type to 'data'.\n" " 'string mode' - only used for writing symlink blocks.\n" "\n" " Examples:\n" " Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" " 'write fname \"hello\\000\"' - write superblock fname.\n" " (note: in struct mode strings are not null terminated)\n" " 'write fname #6669736800' - write superblock fname with " "hex.\n" " 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" " - write superblock uuid.\n" " Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" " 'write lshift 3' - shift the block 3 bytes to the left\n" " 'write sequence 1 5' - write a cycle of number [1-5] through\n" " the entire block.\n" " String mode: 'write \"This_is_a_filename\" - write null terminated " "string.\n" "\n" " In data mode type 'write' by itself for a list of specific commands.\n" "\n" msgstr "" "\n" " Der »write«-Befehl nimmt abhängig vom Typ des Objekts, mit dem gearbeitet\n" " wird, unterschiedliche Persönlichkeiten an.\n" "\n" " Write hat drei Modi:\n" " »Strukturmodus« - ist jederzeit aktiv, wenn Sie ein\n" " Dateisystemobjekt ansehen, das individuelle\n" " Felder enthält (z.B.: Einen Inode.\n" " »Datenmodus« - ist jederzeit aktiv, wenn Sie eine Plattenadresse\n" " direkt setzen oder den Typ auf »data« setzen.\n" " »Zeichenkettenmodus« - nur benutzt, um symbolische Verweisblöcke zu\n" " schreiben.\n" "\n" " Beispiele:\n" " Strukturmodus: »write core.uid 23« - setzt eine Inode-uid-Feld\n" " auf 23.\n" " »write fname \"hello\\000\"«\n" " - schreibt Superblock fname.\n" " (Anmerkung: Zeichenketten werden in »struct mode« nicht\n" " mit Null beendet)\n" " »write fname #6669736800«\n" " - schreibt Superblock fname\n" " hexadezimal.\n" " »write uuid 00112233-4455-6677-8899-aabbccddeeff«\n" " - schreibt Superblock-uuid.\n" " Datenmodus: »write fill 0xff« - füllt den ganzen Block mit\n" " 0xffs\n" " »write lshift 3« - verschiebt den Block drei\n" " Bytes nach links\n" " »write sequence 1 5« - schreibt einen Zyklus von\n" " Nummern [1-5] durch den\n" " ganzen Block\n" " Zeichenkettenmodus: »write \"This_is_a_filename\"«\n" " - schreibt mit Null beendete\n" " Zeichenkette\n" "\n" " Tippen Sie im Datenmodus »write« ein, um eine Liste spezieller Befehle zu\n" " erhalten.\n" "\n" #: .././db/write.c:95 #, c-format msgid "%s started in read only mode, writing disabled\n" msgstr "%s im Nur-Lese-Modus gestartet, Schreiben ausgeschaltet\n" #: .././db/write.c:107 #, c-format msgid "no handler function for type %s, write unsupported.\n" msgstr "" "keine Funktion zum Behandeln von Typ %s, Schreiben nicht unterstützt.\n" #: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 #: .././db/write.c:258 .././db/write.c:293 .././db/write.c:342 #: .././db/write.c:371 #, c-format msgid "length (%d) too large for data block size (%d)" msgstr "Länge (%d) zu groß für Datenblockgröße (%d)" #: .././db/write.c:559 msgid "usage: write fieldname value\n" msgstr "Aufruf: write Feldname Wert\n" #: .././db/write.c:565 #, c-format msgid "unable to parse '%s'.\n" msgstr "»%s« kann nicht ausgewertet werden.\n" #: .././db/write.c:579 msgid "parsing error\n" msgstr "Auswertungsfehler\n" #: .././db/write.c:598 #, c-format msgid "unable to convert value '%s'.\n" msgstr "Wert »%s« kann nicht konvertiert werden.\n" #: .././db/write.c:621 msgid "usage (in string mode): write \"string...\"\n" msgstr "Aufruf (im Zeichenkettenmodus): write »Zeichenkette ...«\n" #: .././db/write.c:663 msgid "write: invalid subcommand\n" msgstr "write: ungültiger Unterbefehl\n" #: .././db/write.c:668 #, c-format msgid "write %s: invalid number of arguments\n" msgstr "write %s: ungültige Anzahl von Argumenten\n" #: .././db/write.c:692 msgid "usage: write (in data mode)\n" msgstr "Aufruf: write (im Datenmodus)\n" #: .././db/agf.c:36 msgid "set address to agf header" msgstr "Adresse auf agf-Kopfzeilen setzen" #: .././db/agf.c:79 msgid "" "\n" " set allocation group free block list\n" "\n" " Example:\n" "\n" " agf 2 - move location to AGF in 2nd filesystem allocation group\n" "\n" " Located in the second sector of each allocation group, the AGF\n" " contains the root of two different freespace btrees:\n" " The 'cnt' btree keeps track freespace indexed on section size.\n" " The 'bno' btree tracks sections of freespace indexed on block number.\n" msgstr "" "\n" " Liste freier Blöcke der Zuordnungsgruppe setzen\n" "\n" " Beispiel:\n" "\n" " agf 2 - Ort auf AGF in 2.Dateisystemzuordnungsgruppe setzen.\n" "\n" " Im zweiten Abschnitt jeder Zuordnungsgruppe gelegen, enthält das AGF die\n" " Wurzel zweier unterschiedlicher freespace btrees:\n" " Der »cnt«-btree folgt Abschnitten von freespace, indiziert auf\n" " Blocknummer.\n" #: .././estimate/xfs_estimate.c:76 #, c-format msgid "" "Usage: %s [opts] directory [directory ...]\n" "\t-b blocksize (fundamental filesystem blocksize)\n" "\t-i logsize (internal log size)\n" "\t-e logsize (external log size)\n" "\t-v prints more verbose messages\n" "\t-h prints this usage message\n" "\n" "Note:\tblocksize may have 'k' appended to indicate x1024\n" "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" msgstr "" "Aufruf: %s [Optionen] Verzeichnis [Verzeichnis ...]\n" "\t-b Blockgröße (grundlegende Dateisystemblockgröße)\n" "\t-i Protokollgröße (interne Protokollgröße)\n" "\t-e Protokollgröße (externe Protokollgröße)\n" "\t-v gibt detailliertere Nachrichten aus\n" "\t-h gibt diese Aufrufnachricht aus\n" "\n" #: .././estimate/xfs_estimate.c:106 #, c-format msgid "blocksize %llu too small\n" msgstr "Blockgröße %llu zu klein\n" #: .././estimate/xfs_estimate.c:111 #, c-format msgid "blocksize %llu too large\n" msgstr "Blockgröße %llu zu groß\n" #: .././estimate/xfs_estimate.c:118 #, c-format msgid "already have external log noted, can't have both\n" msgstr "externes Protokoll wurde bereits notiert, beide nicht möglich\n" #: .././estimate/xfs_estimate.c:127 #, c-format msgid "already have internal log noted, can't have both\n" msgstr "internes Protokoll wurde bereits notiert, beide nicht möglich\n" #: .././estimate/xfs_estimate.c:157 #, c-format msgid "" "directory bsize blocks megabytes " "logsize\n" msgstr "" "Verzeichnis bsize Blöcke Megabytes " "Protokollgröße\n" #: .././estimate/xfs_estimate.c:171 #, c-format msgid "dirsize=%llu\n" msgstr "dirsize=%llu\n" #: .././estimate/xfs_estimate.c:172 #, fc-format msgid "fullblocks=%llu\n" msgstr "fullblocks=%llu\n" #: .././estimate/xfs_estimate.c:173 #, c-format msgid "isize=%llu\n" msgstr "isize=%llu\n" #: .././estimate/xfs_estimate.c:175 #, c-format msgid "%llu regular files\n" msgstr "%llu reguläre Dateien\n" #: .././estimate/xfs_estimate.c:176 #, c-format msgid "%llu symbolic links\n" msgstr "%llu symbolische Verweise\n" #: .././estimate/xfs_estimate.c:177 #, c-format msgid "%llu directories\n" msgstr "%llu Verzeichnisse\n" #: .././estimate/xfs_estimate.c:178 #, c-format msgid "%llu special files\n" msgstr "%llu Spezialdateien\n" #: .././estimate/xfs_estimate.c:191 #, c-format msgid "%s will take about %.1f megabytes\n" msgstr "%s wird etwa %.lf Megabytes einnehmen\n" #: .././estimate/xfs_estimate.c:198 #, c-format msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" msgstr "%-39s %5llu %8llu %10.1fMB %10llu\n" #: .././estimate/xfs_estimate.c:204 #, c-format msgid "\twith the external log using %llu blocks " msgstr "\tmit dem externen Protokoll belegt %llu Blöcke " #: .././estimate/xfs_estimate.c:206 #, c-format msgid "or about %.1f megabytes\n" msgstr "oder über %.1f Megabytes\n" #: .././fsr/xfs_fsr.c:216 #, c-format msgid "%s: Stats not yet supported for XFS\n" msgstr "%s: Status noch nicht für XFS unterstützt\n" #: .././fsr/xfs_fsr.c:264 .././fsr/xfs_fsr.c:292 #, c-format msgid "%s: could not stat: %s: %s\n" msgstr "%s: kann Status für »%s« nicht abfragen: %s\n" #: .././fsr/xfs_fsr.c:274 #, c-format msgid "%s: cannot read %s\n" msgstr "%s: %s kann nicht gelesen werden\n" #: .././fsr/xfs_fsr.c:306 #, c-format msgid "%s: char special not supported: %s\n" msgstr "%s: Sonderzeichen nicht unterstützt: %s\n" #: .././fsr/xfs_fsr.c:312 #, c-format msgid "%s: cannot defragment: %s: Not XFS\n" msgstr "%s: kann nicht defragmentiert werden: %s: Kein XFS\n" #: .././fsr/xfs_fsr.c:322 #, c-format msgid "%s: not fsys dev, dir, or reg file, ignoring\n" msgstr "%s: nicht fsys dev, dir oder reg-Datei, wird ignoriert\n" #: .././fsr/xfs_fsr.c:337 #, c-format msgid "" "Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m " "mtab]\n" " %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n" "\n" "Options:\n" " -n Do nothing, only interesting with -v. Not\n" " effective with in mtab mode.\n" " -s\t\tPrint statistics only.\n" " -g Print to syslog (default if stdout not a tty).\n" " -t time How long to run in seconds.\n" " -p passes\tNumber of passes before terminating global re-org.\n" " -f leftoff Use this instead of %s.\n" " -m mtab Use something other than /etc/mtab.\n" " -d Debug, print even more.\n" " -v\t\tVerbose, more -v's more verbose.\n" msgstr "" "Aufruf: %s [-d] [-v] [-n] [-s] [-g] [-t Zeit] [-p Durchläufe] [-f leftf] \n" " [-m mtab] %s [-d] [-v] [-n] [-s] [-g] xfsdev | Verz. | Datei ...\n" "\n" "Optionen:\n" " -n Nichts tun, nur interessant mit -v. Im mtab-Modus\n" " nicht effektiv.\n" " -s\t\tNur Statistiken ausgeben.\n" " -g Ausgabe in's Syslog (Vorgabe, wenn stdout kein tty).\n" " -t Zeit Ausführdauer in Sekunden.\n" " -p Durchläufe Anzahl der Durchläufe vor Beenden der globalen\n" " Reorganisation.\n" " -f leftoff Benutzen Sie dies anstelle von %s.\n" " -m mtab Etwas anderes als /etc/mtab benutzen.\n" " -d Fehlersuche, noch mehr ausgeben.\n" " -v\t\tDetailliert, mehr vs - mehr Details.\n" #: .././fsr/xfs_fsr.c:368 #, c-format msgid "could not open mtab file: %s\n" msgstr "mtab-Datei könnte nicht geöffnet werden: %s\n" #: .././fsr/xfs_fsr.c:374 .././fsr/xfs_fsr.c:406 #, c-format msgid "out of memory: %s\n" msgstr "außerhalb des Speichers: %s\n" #: .././fsr/xfs_fsr.c:397 #, c-format msgid "Skipping %s: not mounted rw\n" msgstr "%s wird übersprungen: Nicht rw-eingehängt\n" #: .././fsr/xfs_fsr.c:411 #, c-format msgid "out of memory on realloc: %s\n" msgstr "außerhalb des Speichers bei realloc: %s\n" #: .././fsr/xfs_fsr.c:422 #, c-format msgid "strdup(%s) failed\n" msgstr "strdup(%s) fehlgeschlagen\n" #: .././fsr/xfs_fsr.c:432 #, c-format msgid "no rw xfs file systems in mtab: %s\n" msgstr "keine rw-XFS-Dateisysteme in mtab: %s\n" #: .././fsr/xfs_fsr.c:436 #, c-format msgid "Found %d mounted, writable, XFS filesystems\n" msgstr "%d eingehängte, schreibbare XFS-Dateisysteme gefunden\n" #: .././fsr/xfs_fsr.c:466 #, c-format msgid "%s: open failed\n" msgstr "%s: Öffnen fehlgeschlagen\n" #: .././fsr/xfs_fsr.c:481 #, c-format msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" msgstr "%s kann nicht benutzt werden: Modus=0%o Besitzer=%d nlink=%d\n" #: .././fsr/xfs_fsr.c:501 #, c-format msgid "could not read %s, starting with %s\n" msgstr "%s kann nicht gelesen werden, es wird mit %s gestartet\n" #: .././fsr/xfs_fsr.c:538 #, c-format msgid "START: pass=%d ino=%llu %s %s\n" msgstr "START: Durchlauf=%d ino=%llu %s %s\n" #: .././fsr/xfs_fsr.c:555 #, c-format msgid "Completed all %d passes\n" msgstr "Alle %d Durchläufe wurden komplettiert\n" #: .././fsr/xfs_fsr.c:565 msgid "couldn't fork sub process:" msgstr "Unterprozess kann nicht verzweigt werden:" #: .././fsr/xfs_fsr.c:602 #, c-format msgid "open(%s) failed: %s\n" msgstr "Öffnen (%s) fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:609 #, c-format msgid "write(%s) failed: %s\n" msgstr "Schreiben (%s) fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:616 #, c-format msgid "%s startpass %d, endpass %d, time %d seconds\n" msgstr "%s Durchlaufstart %d, Durchlaufende %d, Zeit %d Sekunden\n" #: .././fsr/xfs_fsr.c:638 #, c-format msgid "%s start inode=%llu\n" msgstr "%s Start-Inode=%llu\n" #: .././fsr/xfs_fsr.c:643 #, c-format msgid "unable to get handle: %s: %s\n" msgstr "es konnte kein »handle« ermittelt werden: %s: %s\n" #: .././fsr/xfs_fsr.c:649 #, c-format msgid "unable to open: %s: %s\n" msgstr "konnte nicht geöffnet werden: %s: %s\n" #: .././fsr/xfs_fsr.c:655 #, c-format msgid "Skipping %s: could not get XFS geometry\n" msgstr "%s wird übersprungen: XFS-Geometrie konnte nicht ermittelt werden\n" #: .././fsr/xfs_fsr.c:687 #, c-format msgid "could not open: inode %llu\n" msgstr "kann nicht geöffnet werden: Inode %llu\n" #: .././fsr/xfs_fsr.c:717 #, c-format msgid "%s: xfs_bulkstat: %s\n" msgstr "%s: xfs_bulkstat: %s\n" #: .././fsr/xfs_fsr.c:743 #, c-format msgid "%s: Directory defragmentation not supported\n" msgstr "%s: Verzeichnis-Defragmentierung nicht unterstützt\n" #: .././fsr/xfs_fsr.c:762 #, c-format msgid "unable to construct sys handle for %s: %s\n" msgstr "sys-handle für %s kann nicht konstruiert werden: %s\n" #: .././fsr/xfs_fsr.c:773 #, c-format msgid "unable to open sys handle for %s: %s\n" msgstr "sys-handle für %s kann nicht geöffnet werden: %s\n" #: .././fsr/xfs_fsr.c:779 #, c-format msgid "unable to get bstat on %s: %s\n" msgstr "bstat auf %s kann nicht ermittelt werden: %s\n" #: .././fsr/xfs_fsr.c:787 #, c-format msgid "unable to open handle %s: %s\n" msgstr "handle %s kann nicht geöffnet werden: %s\n" #: .././fsr/xfs_fsr.c:795 #, c-format msgid "Unable to get geom on fs for: %s\n" msgstr "geom auf fs kann nicht ermittelt werden für: %s\n" #: .././fsr/xfs_fsr.c:844 #, c-format msgid "sync failed: %s: %s\n" msgstr "sync fehlgeschlagen: %s: %s\n" #: .././fsr/xfs_fsr.c:850 #, c-format msgid "%s: zero size, ignoring\n" msgstr "%s: Größe null, wird ignoriert\n" #: .././fsr/xfs_fsr.c:869 #, c-format msgid "locking check failed: %s\n" msgstr "Prüfen der Sperre fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:876 #, c-format msgid "mandatory lock: %s: ignoring\n" msgstr "verbindliche Sperre: %s: wird ignoriert\n" #: .././fsr/xfs_fsr.c:889 #, c-format msgid "unable to get fs stat on %s: %s\n" msgstr "fs-stat auf %s kann nicht ermittelt werden: %s\n" #: .././fsr/xfs_fsr.c:896 #, c-format msgid "insufficient freespace for: %s: size=%lld: ignoring\n" msgstr "unzureichender freier Speicher für: %s: Größe=%lld: wird ignoriert\n" #: .././fsr/xfs_fsr.c:903 #, c-format msgid "failed to get inode attrs: %s\n" msgstr "Ermitteln von Inode-attrs fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:908 #, c-format msgid "%s: immutable/append, ignoring\n" msgstr "%s: unveränderlich/anhängen, wird ignoriert\n" #: .././fsr/xfs_fsr.c:913 #, c-format msgid "%s: marked as don't defrag, ignoring\n" msgstr "%s: als nicht zu defragmentieren markiert, wird ignoriert\n" #: .././fsr/xfs_fsr.c:919 #, c-format msgid "cannot get realtime geometry for: %s\n" msgstr "Echtzeitgeometrie kann nicht ermittelt werden für: %s\n" #: .././fsr/xfs_fsr.c:924 #, c-format msgid "low on realtime free space: %s: ignoring file\n" msgstr "geringer freier Echtzeit-Raum: %s: Datei wird ignoriert\n" #: .././fsr/xfs_fsr.c:931 #, c-format msgid "cannot open: %s: Permission denied\n" msgstr "kann nicht geöffnet werden: %s: Erlaubnis verweigert\n" #: .././fsr/xfs_fsr.c:985 #, c-format msgid "%s already fully defragmented.\n" msgstr "%s ist bereits vollständig defragmentiert.\n" #: .././fsr/xfs_fsr.c:990 #, c-format msgid "%s extents=%d can_save=%d tmp=%s\n" msgstr "%s extents=%d can_save=%d tmp=%s\n" #: .././fsr/xfs_fsr.c:996 #, c-format msgid "could not open tmp file: %s: %s\n" msgstr "tmp-Datei kann nicht geöffnet werden: %s: %s\n" #: .././fsr/xfs_fsr.c:1005 #, c-format msgid "could not set ATTR on tmp: %s:\n" msgstr "ATTR auf tmp kann nicht gesetzt werden: %s:\n" #: .././fsr/xfs_fsr.c:1010 #, c-format msgid "%s set temp attr\n" msgstr "%s setzt temp attr\n" #: .././fsr/xfs_fsr.c:1016 #, c-format msgid "could not set inode attrs on tmp: %s\n" msgstr "Inode-attrs auf tmp können nicht gesetzt werden: %s\n" #: .././fsr/xfs_fsr.c:1024 #, c-format msgid "could not get DirectIO info on tmp: %s\n" msgstr "DirekIO-Information auf tmp kann nicht ermittelt werden: %s\n" #: .././fsr/xfs_fsr.c:1040 #, c-format msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" msgstr "FEHLERSUCHE: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" #: .././fsr/xfs_fsr.c:1047 #, c-format msgid "could not allocate buf: %s\n" msgstr "buf kann nicht zugewiesen werden: %s\n" #: .././fsr/xfs_fsr.c:1058 #, c-format msgid "could not open fragfile: %s : %s\n" msgstr "fragfile kann nicht geöffnet werden: %s : %s\n" #: .././fsr/xfs_fsr.c:1075 #, c-format msgid "could not trunc tmp %s\n" msgstr "tmp %s kann nicht gekürzt werden\n" #: .././fsr/xfs_fsr.c:1090 #, c-format msgid "could not pre-allocate tmp space: %s\n" msgstr "tmp-Raum kann nicht vorab zugewiesen werden: %s\n" #: .././fsr/xfs_fsr.c:1101 msgid "Couldn't rewind on temporary file\n" msgstr "es konnte auf temporäre Datei zurückgesetzt werden\n" #: .././fsr/xfs_fsr.c:1110 #, c-format msgid "Temporary file has %d extents (%d in original)\n" msgstr "Temporäre Datei hat %d extents (%d im Original)\n" #: .././fsr/xfs_fsr.c:1113 #, c-format msgid "No improvement will be made (skipping): %s\n" msgstr "Es wird keine Verbesserung vorgenommen (übersprungen): %s\n" #: .././fsr/xfs_fsr.c:1157 #, c-format msgid "bad read of %d bytes from %s: %s\n" msgstr "fehlerhaftes Lesen von %d Bytes auf %s: %s\n" #: .././fsr/xfs_fsr.c:1161 .././fsr/xfs_fsr.c:1195 #, c-format msgid "bad write of %d bytes to %s: %s\n" msgstr "fehlerhaftes Schreiben von %d Bytes auf %s: %s\n" #: .././fsr/xfs_fsr.c:1178 #, c-format msgid "bad write2 of %d bytes to %s: %s\n" msgstr "fehlerhaftes write2 von %d Bytes auf %s: %s\n" #: .././fsr/xfs_fsr.c:1183 #, c-format msgid "bad copy to %s\n" msgstr "fehlerhafte Kopie auf %s\n" #: .././fsr/xfs_fsr.c:1218 #, c-format msgid "failed to fchown tmpfile %s: %s\n" msgstr "fchown tmpfile fehlgeschlagen: %s: %s\n" #: .././fsr/xfs_fsr.c:1229 #, c-format msgid "%s: file type not supported\n" msgstr "%s: Dateityp nicht unterstützt\n" #: .././fsr/xfs_fsr.c:1233 #, c-format msgid "%s: file modified defrag aborted\n" msgstr "%s: Datei geändert, Defragmentierung abgebrochen\n" #: .././fsr/xfs_fsr.c:1238 #, c-format msgid "%s: file busy\n" msgstr "%s: Datei wird benutzt\n" #: .././fsr/xfs_fsr.c:1240 #, c-format msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" msgstr "XFS_IOC_SWAPEXT fehlgeschlagen: %s: %s\n" #: .././fsr/xfs_fsr.c:1249 #, c-format msgid "extents before:%d after:%d %s %s\n" msgstr "extents vorher: %d nachher: %d %s %s\n" #: .././fsr/xfs_fsr.c:1275 #, c-format msgid "tmp file name too long: %s\n" msgstr "tmp-Dateiname zu lang: %s\n" #: .././fsr/xfs_fsr.c:1324 #, c-format msgid "realloc failed: %s\n" msgstr "realloc fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:1337 #, c-format msgid "malloc failed: %s\n" msgstr "malloc fehlgeschlagen: %s\n" #: .././fsr/xfs_fsr.c:1367 #, c-format msgid "failed reading extents: inode %llu" msgstr "Lesen der Extents fehlgeschlagen: Inode %llu" #: .././fsr/xfs_fsr.c:1417 msgid "failed reading extents" msgstr "Lesen der Extents fehlgeschlagen" #: .././fsr/xfs_fsr.c:1534 .././fsr/xfs_fsr.c:1548 #, c-format msgid "tmpdir already exists: %s\n" msgstr "tmpdir exisitiert bereits: %s\n" #: .././fsr/xfs_fsr.c:1537 #, c-format msgid "could not create tmpdir: %s: %s\n" msgstr "tmpdir könnte nicht erstellt werden: %s: %s\n" #: .././fsr/xfs_fsr.c:1550 #, c-format msgid "cannot create tmpdir: %s: %s\n" msgstr "tmpdir kann nicht erstellt werden: %s: %s\n" #: .././fsr/xfs_fsr.c:1588 .././fsr/xfs_fsr.c:1596 #, c-format msgid "could not remove tmpdir: %s: %s\n" msgstr "tmpdir könnte nicht entfernt werden: %s: %s\n" #: .././growfs/xfs_growfs.c:34 #, c-format msgid "" "Usage: %s [options] mountpoint\n" "\n" "Options:\n" "\t-d grow data/metadata section\n" "\t-l grow log section\n" "\t-r grow realtime section\n" "\t-n don't change anything, just show geometry\n" "\t-I allow inode numbers to exceed %d significant bits\n" "\t-i convert log from external to internal format\n" "\t-t alternate location for mount table (/etc/mtab)\n" "\t-x convert log from internal to external format\n" "\t-D size grow data/metadata section to size blks\n" "\t-L size grow/shrink log section to size blks\n" "\t-R size grow realtime section to size blks\n" "\t-e size set realtime extent size to size blks\n" "\t-m imaxpct set inode max percent to imaxpct\n" "\t-V print version information\n" msgstr "" "Aufruf: %s [Optionen] Einhängepunkt\n" "\n" "Optionen:\n" "\t-d Daten-/Metadaten-Bereich vergrößern\n" "\t-l Protokoll-Bereich vergrößern\n" "\t-r Echtzeit-Bereich vergrößern\n" "\t-n nichts ändern, nur Geometrie anzeigen\n" "\t-I Inode-Nummern erlauben %d signifikante Bits zu übersteigen\n" "\t-i Protokoll vom externen auf das interne Format umwandeln\n" "\t-t alternativer Ort der Einhängepunkt-Tabelle (/etc/mtab)\n" "\t-x Protokoll vom internen auf das externe Format umwandeln\n" "\t-D Größe Daten-/Metadaten-Bereich auf blks-Größe vergrößern\n" "\t-L Größe vergrößern/verkleinern des Protokoll-Bereiches auf blks-Größe\n" "\t-R Größe Echtzeit-Bereich auf blks-Größe vergrößern\n" "\t-e Größe Echtezeit-Umfang auf blks-Größe setzen\n" "\t-m imaxpct Inodes auf maximal imaxcpt Prozent setzen\n" "\t-V Versions-Information anzeigen\n" #: .././growfs/xfs_growfs.c:68 #, c-format msgid "" "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" msgstr "" "Metadaten =%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "Daten =%-22s bsize=%-6u Blöcke=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "Benennung =Version %-14u bsize=%-6u ascii-ci=%d\n" "Protokoll =%-22s bsize=%-6u Blöcke=%u, Version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "Echtzeit =%-22s extsz=%-6u Blöcke=%llu, rtextents=%llu\n" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:448 #: .././growfs/xfs_growfs.c:449 msgid "internal" msgstr "Intern" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:86 #: .././growfs/xfs_growfs.c:448 .././growfs/xfs_growfs.c:449 msgid "external" msgstr "extern" #: .././growfs/xfs_growfs.c:199 #, c-format msgid "%s: %s is not a mounted XFS filesystem\n" msgstr "%s: %s ist kein eingehängtes XFS-Dateisystem\n" #: .././growfs/xfs_growfs.c:216 .././io/open.c:170 #, c-format msgid "%s: specified file [\"%s\"] is not on an XFS filesystem\n" msgstr "%s: angegebene Datei [»%s«] ist kein XFS-Dateisystem\n" #: .././growfs/xfs_growfs.c:233 #, c-format msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" msgstr "" "%s: Geometrie des auf %s eingehängten Dateisystems kann nicht ermittelt\n" "werden: %s\n" #: .././growfs/xfs_growfs.c:268 #, c-format msgid "%s: failed to access data device for %s\n" msgstr "%s: Zugriff auf Datenträger für %s fehlgeschlagen\n" #: .././growfs/xfs_growfs.c:273 #, c-format msgid "%s: failed to access external log for %s\n" msgstr "%s: Zugriff auf externes Protokoll für %s fehlgeschlagen.\n" #: .././growfs/xfs_growfs.c:279 #, c-format msgid "%s: failed to access realtime device for %s\n" msgstr "%s: Zugriff auf Echtzeit-Gerät für %s fehlgeschlagen.\n" #: .././growfs/xfs_growfs.c:315 #, c-format msgid "data size %lld too large, maximum is %lld\n" msgstr "Datengröße %lld zu groß, Maximum ist %lld\n" #: .././growfs/xfs_growfs.c:325 #, c-format msgid "data size %lld too small, old size is %lld\n" msgstr "Datengröße %lld zu klein, alte Größe ist %lld\n" #: .././growfs/xfs_growfs.c:333 #, c-format msgid "data size unchanged, skipping\n" msgstr "Datengröße unverändert, wird übersprungen\n" #: .././growfs/xfs_growfs.c:336 #, c-format msgid "inode max pct unchanged, skipping\n" msgstr "»inode max pct« unverändert, wird übersprungen\n" #: .././growfs/xfs_growfs.c:343 .././growfs/xfs_growfs.c:382 #: .././growfs/xfs_growfs.c:417 #, c-format msgid "%s: growfs operation in progress already\n" msgstr "%s: growfs-Operation wird immer noch ausgeführt.\n" #: .././growfs/xfs_growfs.c:347 #, c-format msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" msgstr "%s: XFS_IOC_FSGROWFSDATA xfsctl fehlgeschlagen: %s\n" #: .././growfs/xfs_growfs.c:363 #, c-format msgid "realtime size %lld too large, maximum is %lld\n" msgstr "Echtzeit-Größe %lld zu groß, Maximum ist %lld\n" #: .././growfs/xfs_growfs.c:369 #, c-format msgid "realtime size %lld too small, old size is %lld\n" msgstr "Echtzeit-Größe %lld zu klein, alte Größe ist %lld\n" #: .././growfs/xfs_growfs.c:375 #, c-format msgid "realtime size unchanged, skipping\n" msgstr "Echtzeit-Größe unverändert, wird übersprungen\n" #: .././growfs/xfs_growfs.c:386 #, c-format msgid "%s: realtime growth not implemented\n" msgstr "%s: Echtzeit-Wachstum nicht implementiert\n" #: .././growfs/xfs_growfs.c:390 #, c-format msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" msgstr "%s: XFS_IOC_FSGROWFSRT xfsctl fehlgeschlagen: %s\n" #: .././growfs/xfs_growfs.c:411 #, c-format msgid "log size unchanged, skipping\n" msgstr "Protokoll-Größe unverändert, wird übersprungen\n" #: .././growfs/xfs_growfs.c:421 #, c-format msgid "%s: log growth not supported yet\n" msgstr "%s: Protokoll-Wachstum nicht implementiert\n" #: .././growfs/xfs_growfs.c:425 #, c-format msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" msgstr "%s: XFS_IOC_FSGROWFSLOG xfsctl fehlgeschlagen: %s\n" #: .././growfs/xfs_growfs.c:433 #, c-format msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" msgstr "%s: XFS_IOC_FSGEOMETRY xfsctl fehlgeschlagen: %s\n" #: .././growfs/xfs_growfs.c:438 #, c-format msgid "data blocks changed from %lld to %lld\n" msgstr "Datenblöcke von %lld auf %lld geändert.\n" #: .././growfs/xfs_growfs.c:441 #, c-format msgid "inode max percent changed from %d to %d\n" msgstr "Maximale Inode-Prozentzahl von %d auf %d geändert\n" #: .././growfs/xfs_growfs.c:444 #, c-format msgid "log blocks changed from %d to %d\n" msgstr "Protokollblöcke von %d auf %d geändert\n" #: .././growfs/xfs_growfs.c:447 #, c-format msgid "log changed from %s to %s\n" msgstr "Protokoll von %s auf %s geändert\n" #: .././growfs/xfs_growfs.c:451 #, c-format msgid "realtime blocks changed from %lld to %lld\n" msgstr "Echtzeit-Blöcke von %lld auf %lld geändert\n" #: .././growfs/xfs_growfs.c:454 #, c-format msgid "realtime extent size changed from %d to %d\n" msgstr "Echtzeit-Umfang von %d auf %d geändert\n" #: .././io/attr.c:59 #, c-format msgid "" "\n" " displays the set of extended inode flags associated with the current file\n" "\n" " Each individual flag is displayed as a single character, in this order:\n" " r -- file data is stored in the realtime section\n" " p -- file has preallocated extents (cannot be changed using chattr)\n" " i -- immutable, file cannot be modified\n" " a -- append-only, file can only be appended to\n" " s -- all updates are synchronous\n" " A -- the access time is not updated for this inode\n" " d -- do not include this file in a dump of the filesystem\n" " t -- child created in this directory has realtime bit set by default\n" " P -- child created in this directory has parents project ID by default\n" " n -- symbolic links cannot be created in this directory\n" " e -- for non-realtime files, observe the inode extent size value\n" " E -- children created in this directory inherit the extent size value\n" " f -- do not include this file when defragmenting the filesystem\n" " S -- enable filestreams allocator for this directory\n" "\n" " Options:\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, but only list attributes on directories\n" " -a -- show all flags which can be set alongside those which are set\n" " -v -- verbose mode; show long names of flags, not single characters\n" "\n" msgstr "" "\n" " zeigt den Satz von erweiterten Inode-Markierungen an, die zu der\n" " aktuellen Datei zugehörig sind.\n" "\n" " Jede einzelne Markierung wird als einzelner Buchstabe in dieser\n" " Reihenfolge angezeigt:\n" " r -- Dateiinhalt ist im Echtzeit-Bereich gespeichert\n" " p -- Datei hat vorher zugeteilten Umfang (kann nicht mit chattr\n" " geändert werden)\n" " i -- unveränderlich, Datei kann nicht verändert werden\n" " a -- nur anhängen, Datei kann nur daran angehängt werden\n" " s -- alle Aktualisierungen sind synchron\n" " A -- die Zugriffszeit für diesen Inode ist nicht aktualisiert\n" " d -- diese Datei nicht in die Ausgabe des Dateisystems einschließen\n" " t -- das in diesem Verzeichnis erzeugte Kind hat standardmäßig ein\n" " gesetztes Echtzeit-Bit.\n" " P -- das in diesem Verzeichnis erzeugte Kind hat standardmäßig die\n" " Projekt-ID der Eltern.\n" " n -- in diesem Verzeichnis können keine symbolischen Verweise erstellt\n" " werden\n" " e -- für Nicht-Echtzeit-Dateien wird die Größe des Inode-Umfangs beachtet\n" " E -- in diesem Verzeichnis erzeugt Kinder erben die Größe des Umfangs\n" " f -- diese Datei nicht bei der Defragmentierung des Dateisystems\n" " einschließen\n" "\n" " Optionen:\n" " -R -- rekursiv absteigend (nützlich, wenn die aktuelle Datei ein\n" " Verzeichnis ist)\n" " -D -- rekursiv absteigend, aber nur die Attribute von Verzeichnissen\n" " auflisten\n" " -a -- alle Merkmale zeigen, die neben denen gesetzt werden können, die\n" " gesetzt sind.\n" " -v -- gesprächiger Modus; zeige lange Namen der Merkmale, keine einzelnen\n" " Zeichen\n" "\n" #: .././io/attr.c:90 #, c-format msgid "" "\n" " modifies the set of extended inode flags associated with the current file\n" "\n" " Examples:\n" " 'chattr +a' - sets the append-only flag\n" " 'chattr -a' - clears the append-only flag\n" "\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, only modifying attributes on directories\n" " +/-r -- set/clear the realtime flag\n" " +/-i -- set/clear the immutable flag\n" " +/-a -- set/clear the append-only flag\n" " +/-s -- set/clear the sync flag\n" " +/-A -- set/clear the no-atime flag\n" " +/-d -- set/clear the no-dump flag\n" " +/-t -- set/clear the realtime inheritance flag\n" " +/-P -- set/clear the project ID inheritance flag\n" " +/-n -- set/clear the no-symbolic-links flag\n" " +/-e -- set/clear the extent-size flag\n" " +/-E -- set/clear the extent-size inheritance flag\n" " +/-f -- set/clear the no-defrag flag\n" " +/-S -- set/clear the filestreams allocator flag\n" " Note1: user must have certain capabilities to modify immutable/append-" "only.\n" " Note2: immutable/append-only files cannot be deleted; removing these files\n" " requires the immutable/append-only flag to be cleared first.\n" " Note3: the realtime flag can only be set if the filesystem has a realtime\n" " section, and the (regular) file must be empty when the flag is set.\n" "\n" msgstr "" "\n" " verändert den Satz von erweiterten Inode-Merkmalen, die zu der\n" " aktuellen Datei zugehörig sind.\n" "\n" " Beispiele:\n" " »chattr +a« - setzt das Nur-anhängen-Merkmal\n" " »chattr -a« - löscht das Nur-anhängen-Merkmal\n" "\n" " -R -- rekursiv absteigend (nützlich, wenn die aktuelle Datei ein\n" " Verzeichnis ist)\n" " -D -- rekursiv absteigend, aber nur die Attribute von Verzeichnissen\n" " auflisten\n" " +/-r -- setzen/löschen des Echtzeit-Merkmals\n" " +/-i -- setzen/löschen des Unveränderlich-Merkmals\n" " +/-a -- setzen/löschen des Nur-anhängen-Merkmals\n" " +/-s -- setzen/löschen des Sync-Merkmals\n" " +/-A -- setzen/löschen des No-atime-Merkmals\n" " +/-d -- setzen/löschen des No-dump-Merkmals\n" " +/-t -- setzen/löschen des Echtzeit-Vererbungs-Merkmals\n" " +/-P -- setzen/löschen des Projekt-ID-Vererbungs-Merkmals\n" " +/-n -- setzen/löschen des Kein-symbolischer-Verweis-Merkmals\n" " +/-e -- setzen/löschen des Erweiterte-Größe-Merkmals\n" " +/-E -- setzen/löschen des Erweiterte-Größe-Vererbungs-Merkmals\n" " +/-f -- setzen/löschen des Nicht-Defragmentierungs-Merkmals\n" " +/-S -- setzen/löschen des Datenstrom-Zuteiler-Merkmals\n" " Anmerkung1: Der Anwender muss gewisse Fähigkeiten haben, um das zu ändern,\n" " das unveränderlich oder zum Nur-Ändern ist.\n" " Anmerkung2: Unveränderliche-/Nur-Ändern-Dateien können nicht gelöscht\n" " werden; diese Dateien zu entfernen erfordert das vorherige\n" " Löschen des Unveränderlich-/Nur-Ändern-Merkmals.\n" " Anmerkung3: Das Echtzeit-Merkmal kann nur gesetzt werden, wenn das\n" " Dateisystem einen Echtzeit-Bereich hat, und die (reguläre)\n" " Datei muss leer sein, wenn das Merkmal gesetzt wird.\n" "\n" #: .././io/attr.c:171 .././io/attr.c:247 .././io/open.c:403 .././io/open.c:475 #: .././io/open.c:599 .././io/open.c:621 .././libxfs/init.c:110 #: .././mkfs/proto.c:284 .././quota/project.c:118 .././quota/project.c:163 #: .././quota/project.c:210 #, c-format msgid "%s: cannot open %s: %s\n" msgstr "%s: %s kann nicht geöffnet werden: %s\n" #: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 #: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 #, c-format msgid "%s: cannot get flags on %s: %s\n" msgstr "%s: Es werden keine Merkmale von %s erlangt: %s\n" #: .././io/attr.c:256 .././io/attr.c:327 #, c-format msgid "%s: cannot set flags on %s: %s\n" msgstr "%s: Markierungen auf %s können nicht gesetzt werden: %s\n" #: .././io/attr.c:291 .././io/attr.c:305 #, c-format msgid "%s: unknown flag\n" msgstr "%s: unbekannte Markierung\n" #: .././io/attr.c:311 #, c-format msgid "%s: bad chattr command, not +/-X\n" msgstr "%s: schlechter chattr-Befehl, nicht +/-X\n" #: .././io/attr.c:336 msgid "chattr" msgstr "chattr" #: .././io/attr.c:338 msgid "[-R|-D] [+/-" msgstr "[-R|-D] [+/-" #: .././io/attr.c:343 msgid "change extended inode flags on the currently open file" msgstr "erweiterte Inode-Markierungen bei der derzeit offenen Datei ändern" #: .././io/attr.c:346 msgid "lsattr" msgstr "lsattr" #: .././io/attr.c:348 msgid "[-R|-D|-a|-v]" msgstr "[-R|-D|-a|-v]" #: .././io/attr.c:353 msgid "list extended inode flags set on the currently open file" msgstr "" "gesetzte erweiterte Inode-Markierungen bei der derzeit offenen Dateianzeigen" #: .././io/fadvise.c:31 #, c-format msgid "" "\n" " advise the page cache about expected I/O patterns on the current file\n" "\n" " Modifies kernel page cache behaviour when operating on the current file.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" " -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" " -r -- expect random page references (POSIX_FADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" " Notes: these interfaces are not supported in Linux kernels before 2.6.\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" "\n" msgstr "" "\n" " benachrichtigt den Zwischenspeicher über voraussichtliche I/O-Muster der\n" " aktuellen Datei\n" "\n" " Verändert das Verhalten des Kernelseiten-Zwischenspeichers während der\n" " Bearbeitung der vorliegenden Datei.\n" " Die Bereichs-Argumente werden von einigen Benachrichtigungs-Befehlen\n" " ([*] unten) benötigt. Ohne Argumente ist die POSIX_FADV_NORMAL-" "Benachrichtigung impliziert.\n" " -d -- diese Seiten werden nicht benötigt (POSIX_FADV_DONTNEED) [*]\n" " -n -- auf die Daten wird einmal zugegriffen (POSIX_FADV_NOREUSE) [*]\n" " -r -- erwartet zufällige Seiten Referenzen (POSIX_FADV_RANDOM)\n" " -s -- erwartet fortlaufende Seiten-Referenzen (POSIX_FADV_SEQUENTIAL)\n" " -w -- möchte diese Seiten (POSIX_FADV_WILLNEED) [*]\n" " Anmerkungen: Diese Schnittstellen werden nicht von Linux-Kerneln vor 2.6.\n" " unterstützt. NORMAL stellt die Standard-Vorauslesen-" "Einstellung für diese Datei ein.\n" " RANDOM stellt die Vorauslesen-Einstellung für diese Datei auf Null.\n" " SEQUENTIAL setzt die doppelte Standard-Vorauslesen-Einstellung für diese\n" " Datei ein.\n" " WILLNEED und NOREUSE sind gleichbedeutend und erzwingen maximales\n" " Vorauslesen.\n" "\n" #: .././io/fadvise.c:93 .././io/madvise.c:87 .././io/mincore.c:48 #: .././io/sendfile.c:126 .././io/prealloc.c:49 .././io/pwrite.c:284 #: .././io/mmap.c:206 .././io/mmap.c:301 .././io/mmap.c:387 .././io/mmap.c:546 #, c-format msgid "non-numeric offset argument -- %s\n" msgstr "nicht-numerisches Versatz-Argument -- %s\n" #: .././io/fadvise.c:100 .././io/madvise.c:94 .././io/mincore.c:54 #: .././io/pread.c:330 .././io/pread.c:338 .././io/sendfile.c:133 #: .././io/prealloc.c:54 .././io/pwrite.c:290 .././io/mmap.c:212 #: .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 #, c-format msgid "non-numeric length argument -- %s\n" msgstr "nicht-numerisches Längen-Argument -- %s\n" #: .././io/fadvise.c:118 msgid "fadvise" msgstr "fadvise" #: .././io/fadvise.c:123 msgid "[-dnrsw] [off len]" msgstr "[-dnrsw] [off len]" #: .././io/fadvise.c:124 msgid "advisory commands for sections of a file" msgstr "Benachrichtigungsbefehl für Bereiche einer Datei" #: .././io/file.c:39 #, c-format msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" msgstr "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" #: .././io/file.c:41 msgid "foreign" msgstr "fremd" #: .././io/file.c:41 msgid "xfs" msgstr "xfs" #: .././io/file.c:42 .././io/open.c:82 msgid "sync" msgstr "synchronisieren" #: .././io/file.c:42 .././io/open.c:82 msgid "non-sync" msgstr "nicht synchronisieren" #: .././io/file.c:43 .././io/open.c:83 msgid "direct" msgstr "direkt" #: .././io/file.c:43 .././io/open.c:83 msgid "non-direct" msgstr "nicht direkt" #: .././io/file.c:44 .././io/open.c:84 msgid "read-only" msgstr "Nur-lesen" #: .././io/file.c:44 .././io/open.c:84 msgid "read-write" msgstr "Nur-schreiben" #: .././io/file.c:45 .././io/open.c:85 msgid ",real-time" msgstr "Echtzeit" #: .././io/file.c:46 .././io/open.c:86 msgid ",append-only" msgstr "Nur-anhängen" #: .././io/file.c:47 .././io/open.c:87 msgid ",non-block" msgstr "Nicht-Block" #: .././io/file.c:81 .././io/sendfile.c:103 .././quota/path.c:112 #, c-format msgid "value %d is out of range (0-%d)\n" msgstr "Wert %d ist außerhalb des Bereichs (0-%d)\n" #: .././io/file.c:92 msgid "file" msgstr "Datei" #: .././io/file.c:93 msgid "f" msgstr "f" #: .././io/file.c:94 .././quota/path.c:126 msgid "[N]" msgstr "[N]" #: .././io/file.c:99 msgid "set the current file" msgstr "derzeitige Datei setzen" #: .././io/file.c:101 .././quota/path.c:133 msgid "print" msgstr "ausgeben" #: .././io/file.c:102 .././quota/path.c:134 msgid "p" msgstr "p" #: .././io/file.c:108 msgid "list current open files and memory mappings" msgstr "gibt derzeit offene Dateien und Speicherauszüge an" #: .././io/fsync.c:54 msgid "fsync" msgstr "fsync" #: .././io/fsync.c:55 .././repair/progress.c:430 .././repair/progress.c:440 #: .././repair/progress.c:456 .././repair/progress.c:474 #: .././repair/progress.c:489 msgid "s" msgstr "s" #: .././io/fsync.c:59 msgid "calls fsync(2) to flush all in-core file state to disk" msgstr "" "ruft fsync(2) auf, um alle Dateistatusse aus dem Kern auf die\n" "Platte zu leeren" #: .././io/fsync.c:61 msgid "fdatasync" msgstr "fdatasync" #: .././io/fsync.c:62 msgid "ds" msgstr "ds" #: .././io/fsync.c:66 msgid "calls fdatasync(2) to flush the files in-core data to disk" msgstr "" "ruft fsync(2) auf, um alle Dateiinhalte aus dem Kern auf die\n" "Platte zu leeren" #: .././io/getrusage.c:112 msgid "getrusage" msgstr "getrusage" #: .././io/getrusage.c:113 msgid "g" msgstr "g" #: .././io/getrusage.c:118 msgid "report process resource usage" msgstr "Bericht, Prozess, Ressource, Aufruf" #: .././io/imap.c:53 #, c-format msgid "ino %10llu count %2d mask %016llx\n" msgstr "ino %10llu Anzahl %2d Maske %016llx\n" #: .././io/imap.c:67 msgid "imap" msgstr "imap" #: .././io/imap.c:71 msgid "[nentries]" msgstr "[nentries]" #: .././io/imap.c:73 msgid "inode map for filesystem of current file" msgstr "Inode-Karte für das Dateisystem der " #: .././io/init.c:35 #, c-format msgid "Usage: %s [-adFfmrRstx] [-p prog] [-c cmd]... file\n" msgstr "Aufruf: %s [-adFfmrRstx] [-p Programm] [-c Befehl]... Datei\n" #: .././io/init.c:98 .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 #: .././io/open.c:281 #, c-format msgid "no files are open, try 'help open'\n" msgstr "es sind keine Dateien geöffnet, versuchen sie »help open«\n" #: .././io/init.c:102 .././io/mmap.c:167 .././io/mmap.c:174 #, c-format msgid "no mapped regions, try 'help mmap'\n" msgstr "keine kartierten Bereiche, versuchen sie »help open«\n" #: .././io/init.c:108 #, c-format msgid "foreign file active, %s command is for XFS filesystems only\n" msgstr "Fremde Datei aktiv, der %s-Befehl ist nur für das XFS-Dateisystem\n" #: .././io/init.c:153 .././io/open.c:303 #, c-format msgid "non-numeric mode -- %s\n" msgstr "nicht-numerischer Modus -- %s\n" #: .././io/inject.c:109 #, c-format msgid "" "\n" " inject errors into the filesystem of the currently open file\n" "\n" " Example:\n" " 'inject readagf' - cause errors on allocation group freespace reads\n" "\n" " Causes the kernel to generate and react to errors within XFS, provided\n" " the XFS kernel code has been built with debugging features enabled.\n" " With no arguments, displays the list of error injection tags.\n" "\n" msgstr "" "\n" " speist Fehler in das Dateisystem der aktuell geöffneten Datei ein\n" "\n" " Beispiel:\n" " »inject readagf« - ruft Fehler hervor beim Lesen des für die Gruppe\n" " reservierten freien Raumes hervor\n" "\n" " Veranlasst den Kernel zu generieren und auf Fehler im XFS zu reagieren,\n" " vorausgesetzt, der Kernel-Kode wurde mit eingeschalteten\n" " Fehlersuche-Merkmalen erzeugt. Ohne Argumente wird eine Liste der\n" " Fehler-Einspeisungs-Kennzeichen angezeigt.\n" "\n" #: .././io/inject.c:135 #, c-format msgid "no such tag -- %s\n" msgstr "kein solches Kennzeichen -- %s\n" #: .././io/inject.c:151 msgid "inject" msgstr "einspeisen" #: .././io/inject.c:156 msgid "[tag ...]" msgstr "[Kennzeichen ...]" #: .././io/inject.c:157 msgid "inject errors into a filesystem" msgstr "Fehler in ein Dateisystem einspeisen" #: .././io/madvise.c:32 #, c-format msgid "" "\n" " advise the page cache about access patterns expected for a mapping\n" "\n" " Modifies page cache behavior when operating on the current mapping.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" " -r -- expect random page references (POSIX_MADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" " Notes:\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED forces the maximum readahead.\n" "\n" msgstr "" "\n" " teilt dem Seiten-Zwischenspeicher die erwarteten Zugriffs-Vorlagen für\n" " eine Kartierung mit\n" "\n" " Ändert das Verhalten des Seiten-Zwischenspeichers beim Operieren auf der\n" " gegenwärtigen Kartierung. Die Bereichs-Argumente werden von einigen\n" " Ankündigungs-Befehlen benötigt([*] unten).\n" " Ohne Argumente ist die POSIX_MADV_NORMAL-Benachrichtigung impliziert.\n" " -d -- diese Seiten werden nicht benötigt (POSIX_MADV_DONTNEED) [*]\n" " -r -- erwartet zufällige Seiten Referenzen (POSIX_MADV_RANDOM)\n" " -s -- erwartet fortlaufende Seiten-Referenzen (POSIX_MADV_SEQUENTIAL)\n" " -w -- möchte diese Seiten (POSIX_MADV_WILLNEED) [*]\n" " NORMAL stellt die Standard-Vorauslesen-Einstellung für diese Datei ein.\n" " RANDOM stellt die Vorauslesen-Einstellung für diese Datei auf Null.\n" " SEQUENTIAL setzt die doppelte Standard-Vorauslesen-Einstellung für diese\n" " Datei ein.\n" " WILLNEED und NOREUSE sind gleichbedeutend und erzwingen maximales\n" " Vorauslesen.\n" "\n" #: .././io/madvise.c:116 msgid "madvise" msgstr "madvise" #: .././io/madvise.c:117 msgid "ma" msgstr "ma" #: .././io/madvise.c:122 msgid "[-drsw] [off len]" msgstr "[-drsw] [off len]" #: .././io/madvise.c:123 msgid "give advice about use of memory" msgstr "einen Rat über den Gebrauch des Speichers geben" #: .././io/mincore.c:87 .././io/mincore.c:97 #, c-format msgid "0x%lx %lu pages (%llu : %lu)\n" msgstr "0x%lx %lu Seiten (%llu : %lu)\n" #: .././io/mincore.c:111 msgid "mincore" msgstr "mincore" #: .././io/mincore.c:112 msgid "mi" msgstr "mi" #: .././io/mincore.c:117 msgid "[off len]" msgstr "[off len]" #: .././io/mincore.c:118 msgid "find mapping pages that are memory resident" msgstr "Kartierungsseiten finden, die speicherresident sind" #: .././io/pread.c:32 #, c-format msgid "" "\n" " reads a range of bytes in a specified block size from the given offset\n" "\n" " Example:\n" " 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" "\n" " Reads a segment of the currently open file, optionally dumping it to the\n" " standard output stream (with -v option) for subsequent inspection.\n" " The reads are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different pattern is requested.\n" " -B -- read backwards through the range from offset (backwards N bytes)\n" " -F -- read forwards through the range of bytes from offset (default)\n" " -v -- be verbose, dump out buffers (used when reading forwards)\n" " -R -- read at random offsets in the range of bytes\n" " -Z N -- zeed the random number generator (used when reading randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" " When in \"random\" mode, the number of read operations will equal the\n" " number required to do a complete forward/backward scan of the range.\n" " Note that the offset within the range is chosen at random each time\n" " (an offset may be read more than once when operating in this mode).\n" "\n" msgstr "" "\n" " liest einen Bereich von Bytes in einer angegeben Block-Größe vom gegebenen\n" " Versatz\n" "\n" " Beispiel:\n" " »pread -v 512 20« - Auszug von gelesenen 20 Bytes aus 512 Bytes in die\n" " Datei\n" "\n" " Liest einen Ausschnitt der derzeit offenen Datei, leert sie optional in " "den\n" " Standard-Ausgabe-Datenstrom (mit »-v-Option«) für die nachfolgende\n" " Überprüfung. Das Lesen wird, vom Versatz beginnend, in fortlaufenden\n" " Blöcken mit durch die »-b«-Option einstellbarer Blockgröße ausgeführt\n" " (Standard-Blockgröße ist 4096 Bytes), außer wenn ein anderes Muster\n" " angefordert ist.\n" " -B -- liest vom Versatz rückwärts durch den Bereich (Rückwärts N Bytes)\n" " -F -- liest vom Versatz vorwärts durch den Bereich (Standard)\n" " -v -- detaillierte Ausgabe, Puffer leeren (beim Vorwärtslesen benutzt)\n" " -R -- von zufälligem Versatz im Bereich der Bytes lesen\n" " -Z N -- »zeedet« den Zufallszahlengenerator (benutzt beim zufälligen Lesen)\n" " (Heh, Zorry, die -s-/-S-Argumente sind in Benutzung durch pwrite)\n" " Im »Zufalls«-Modus entspricht die Anzahl der Leseoperationen der benötigten\n" " Anzahl, um einen kompletten Vor-/Rückwärtsscan des Bereiches zu machen.\n" " Merken Sie sich, dass der Versatz innerhalb des Bereiches jedesmal " "zufällig\n" " gewählt wird (ein Versatz könnte mehr als einmal beim Ausführen dieses\n" " Modus gelesen werden).\n" "\n" #: .././io/pread.c:286 .././io/pwrite.c:217 #, c-format msgid "non-numeric bsize -- %s\n" msgstr "nicht-numerische bsize -- %s\n" #: .././io/pread.c:315 .././io/pwrite.c:251 .././io/pwrite.c:270 #: .././io/mmap.c:530 #, c-format msgid "non-numeric seed -- %s\n" msgstr "Nicht-numerische Füllzeichen -- %s\n" #: .././io/pread.c:375 #, c-format msgid "read %lld/%lld bytes at offset %lld\n" msgstr "%lld/%lld Bytes lesen beim Versatz %lld lesen\n" #: .././io/pread.c:377 .././io/sendfile.c:163 .././io/pwrite.c:336 #, c-format msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" msgstr "%s, %d ops; %s (%s/Sek und %.4f ops/Sek)\n" #: .././io/pread.c:390 msgid "pread" msgstr "pread" #: .././io/pread.c:391 msgid "r" msgstr "r" #: .././io/pread.c:396 msgid "[-b bs] [-v] off len" msgstr "[-b bs] [-v] off len" #: .././io/pread.c:397 msgid "reads a number of bytes at a specified offset" msgstr "liest eine Anzahl von Bytes beim angegebenen Versatz" #: .././io/resblks.c:39 #, c-format msgid "non-numeric argument -- %s\n" msgstr "nicht-numerisches Argument -- %s\n" #: .././io/resblks.c:51 #, c-format msgid "reserved blocks = %llu\n" msgstr "reservierte Blöcke = %llu\n" #: .././io/resblks.c:53 #, c-format msgid "available reserved blocks = %llu\n" msgstr "verfügbare reservierte Blöcke = %llu\n" #: .././io/resblks.c:61 msgid "resblks" msgstr "resblks" #: .././io/resblks.c:66 msgid "[blocks]" msgstr "[Blöcke]" #: .././io/resblks.c:68 msgid "get and/or set count of reserved filesystem blocks" msgstr "Anzahl derreservierten Dateisystem-Blöcke angeben und/oder setzen" #: .././io/sendfile.c:32 #, c-format msgid "" "\n" " transfer a range of bytes from the given offset between files\n" "\n" " Example:\n" " 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Copies data between one file descriptor and another. Because this copying\n" " is done within the kernel, sendfile does not need to transfer data to and\n" " from user space.\n" " -f -- specifies an input file from which to source data to write\n" " -i -- specifies an input file name from which to source data to write.\n" " An offset and length in the source file can be optionally specified.\n" "\n" msgstr "" "\n" " einen Bereich von Bytes von gegebenen Versatz zwischen Dateien übertragen\n" "\n" " Beispiel:\n" " »send -f 2 512 20« - überträge 20 von 512 Bytes in die offene Datei\n" "\n" " Kopiert Daten zwischen einem Datei-Deskriptor und einem anderen. Weil\n" " dieses Kopieren innerhalb des Kernels erledigt wird, müssen keine Daten " "der\n" " Sendedatei zum und vom Benutzerraum übertragen werden.\n" " -f -- gibt eine Eingabedatei an, aus der die Quelldaten zu schreiben sind.\n" " -i -- gibt einen Eingabedateinamen an, von dem die Quelldaten zu schreiben\n" " sind.\n" " Optional kann ein Versatz und eine Länge in der Quelldatei angegeben\n" " werden.\n" "\n" #: .././io/sendfile.c:161 #, c-format msgid "sent %lld/%lld bytes from offset %lld\n" msgstr "sende %lld/%lld Bytes vom Versatz %lld\n" #: .././io/sendfile.c:179 msgid "sendfile" msgstr "sendfile" #: .././io/sendfile.c:180 msgid "send" msgstr "senden" #: .././io/sendfile.c:186 msgid "-i infile | -f N [off len]" msgstr "-i infile | -f N [off len]" #: .././io/sendfile.c:188 msgid "Transfer data directly between file descriptors" msgstr "Daten direkt zwischen Datei-Deskriptoren übertragen" #: .././io/shutdown.c:54 msgid "shutdown" msgstr "herunterfahren" #: .././io/shutdown.c:59 msgid "[-f]" msgstr "[-f]" #: .././io/shutdown.c:61 msgid "shuts down the filesystem where the current file resides" msgstr "fährt das Dateisystem herunter auf dem die aktuelle Datei liegt" #: .././io/truncate.c:38 #, c-format msgid "non-numeric truncate argument -- %s\n" msgstr "nicht-numerisches Kürzungs-Argument -- %s\n" #: .././io/truncate.c:52 msgid "truncate" msgstr "kürzen" #: .././io/truncate.c:53 msgid "t" msgstr "t" #: .././io/truncate.c:58 .././quota/state.c:520 msgid "off" msgstr "aus" #: .././io/truncate.c:60 msgid "truncates the current file at the given offset" msgstr "kürzt die aktuelle Datei am gegebenen Versatz" #: .././io/freeze.c:37 #, c-format msgid "%s: cannot freeze filesystem at %s: %s\n" msgstr "%s: Dateisystem kann nicht bei %s gesperrt werden: %s\n" #: .././io/freeze.c:54 #, c-format msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" msgstr "%s: das auf %s einhängte Dateisystem kann nicht entsperrt werden: %s\n" #: .././io/freeze.c:65 msgid "freeze" msgstr "sperren" #: .././io/freeze.c:70 msgid "freeze filesystem of current file" msgstr "Dateisystem der aktuellen Datei sperren" #: .././io/freeze.c:72 msgid "thaw" msgstr "auftauen" #: .././io/freeze.c:77 msgid "unfreeze filesystem of current file" msgstr "Dateisystem der aktuellen Datei entsperren" #: .././io/prealloc.c:165 msgid "allocsp" msgstr "allocsp" #: .././io/prealloc.c:170 .././io/prealloc.c:178 .././io/prealloc.c:186 #: .././io/prealloc.c:194 msgid "off len" msgstr "off len" #: .././io/prealloc.c:171 msgid "allocates zeroed space for part of a file" msgstr "stellt genullten Speicher für einen Teil der Datei bereit" #: .././io/prealloc.c:173 msgid "freesp" msgstr "freesp" #: .././io/prealloc.c:179 msgid "frees space associated with part of a file" msgstr "leert Speicher, der mit einem Teil einer Datei verbunden ist" #: .././io/prealloc.c:181 msgid "resvsp" msgstr "resvsp" #: .././io/prealloc.c:188 msgid "reserves space associated with part of a file" msgstr "reserviert Speicher, der mit einem Teil einer Datei verbunden ist" #: .././io/prealloc.c:190 msgid "unresvsp" msgstr "unresvsp" #: .././io/prealloc.c:197 msgid "frees reserved space associated with part of a file" msgstr "" "gibt reservierten Speicher frei, der mit einem Teil einer Datei verbunden ist" #: .././io/prealloc.c:205 msgid "falloc" msgstr "falloc" #: .././io/prealloc.c:210 msgid "[-k] off len" msgstr "[-k] [off len]" #: .././io/prealloc.c:212 msgid "allocates space associated with part of a file via fallocate" msgstr "" "weist Speicher zu, der mit einem Teil der Datei über fallocate verbunden ist" #: .././io/pwrite.c:31 #, c-format msgid "" "\n" " writes a range of bytes (in block size increments) from the given offset\n" "\n" " Example:\n" " 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Writes into a segment of the currently open file, using either a buffer\n" " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" " The writes are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different write pattern is requested.\n" " -S -- use an alternate seed number for filling the write buffer\n" " -i -- input file, source of data to write (used when writing forward)\n" " -d -- open the input file for direct IO\n" " -s -- skip a number of bytes at the start of the input file\n" " -w -- call fdatasync(2) at the end (included in timing results)\n" " -W -- call fsync(2) at the end (included in timing results)\n" " -B -- write backwards through the range from offset (backwards N bytes)\n" " -F -- write forwards through the range of bytes from offset (default)\n" " -R -- write at random offsets in the specified range of bytes\n" " -Z N -- zeed the random number generator (used when writing randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" "\n" msgstr "" "\n" " schreibt einen Bereich von Bytes (Erhöhungen in Blockgröße) vom gegebenen\n" " Versatz\n" "\n" " Beispiel:\n" " »pwite 512 20« - schreibt 20 Bytes aus 512 Bytes in die Datei\n" "\n" " Schreibt unter Benutzung eines Puffers, der mit einem Mustersatz oder mit\n" " aus einer Eingabedatei gelesenen Daten gefüllt wurde, in einen Ausschnitt\n" " der derzeit offenen Datei. Das Lesen wird, vom Versatz beginnend, in " "fortlaufenden\n" " Blöcken mit durch die »-b«-Option einstellbarer Blockgröße ausgeführt\n" " (Standard-Blockgröße ist 4096 Bytes), außer wenn ein anderes Muster\n" " angefordert ist.\n" " -S -- alternative Füllnummer benutzen um den Schreibpuffer zu füllen\n" " -i -- Eingabedatei, Datenquelle zum Schreiben (benutzt, wenn vorwärts\n" " geschrieben wird)\n" " -d -- Eingabedatei für direktes IO öffnen\n" " -s -- eine Anzahl von Bytes am Anfang der Eingabedatei überspringen\n" " -w -- am Ende fdatasync(2) aufrufen (einschließlich zeitlicher " "Resultate)\n" " -W -- am Ende fsync(2) aufrufen (einschließlich zeitlicher Resultate)\n" " -B -- liest vom Versatz rückwärts durch den Bereich (Rückwärts N Bytes)\n" " -F -- liest vom Versatz vorwärts durch den Bereich (Standard)\n" " -R -- von zufälligem Versatz im Bereich der Bytes lesen\n" " -Z N -- »zeedet« den Zufallszahlengenerator (benutzt beim zufälligen Lesen)\n" " (Heh, Zorry, die -s-/-S-Argumente sind in Benutzung durch pwrite)\n" "\n" #: .././io/pwrite.c:244 #, c-format msgid "non-numeric skip -- %s\n" msgstr "nicht-numerische überspringen -- %s\n" #: .././io/pwrite.c:334 #, c-format msgid "wrote %lld/%lld bytes at offset %lld\n" msgstr "schrieb %lld/%lld Bytes ab Versatz %lld\n" #: .././io/pwrite.c:352 msgid "pwrite" msgstr "pwrite" #: .././io/pwrite.c:353 msgid "w" msgstr "w" #: .././io/pwrite.c:359 msgid "[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] off len" msgstr "[-i infile [-d] [-s überspringen]] [-b bs] [-S seed] [-wW] off len" #: .././io/pwrite.c:361 msgid "writes a number of bytes at a specified offset" msgstr "schreibt ein Anzahl von Bytes ab dem angegebenen Versatz" #: .././io/bmap.c:30 #, c-format msgid "" "\n" " prints the block mapping for an XFS file's data or attribute forks\n" " Example:\n" " 'bmap -vp' - tabular format verbose map, including unwritten extents\n" "\n" " bmap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " Note: the bmap for non-regular files can be obtained provided the file\n" " was opened appropriately (in particular, must be opened read-only).\n" "\n" msgstr "" "\n" " gibt die Block-Kartierung für die Daten- oder Attribus-Verzweigungen einer\n" " XFS-Datei aus\n" " Beispiel:\n" " »bmap -vp« - aussagekräftige Karte im Tabellenformat, einschließlich\n" " ungeschriebenem Umfang\n" "\n" " »bmap« schreibt die Karte der Plattenblöcke, die von der derzeitigen Datei\n" " belegt werden.\n" " Die Karte listet jeden Bereich, der von der Datei belegt wird, sowie \n" " Regionen in der Datei, die keine zugehörigen Blöcke (Löcher) haben auf.\n" " Standardmäßig nimmt jede Zeile der Liste die folgende Form an:\n" " Bereich: [Startversatz..Endversatz]: Startblock..Endblock\n" " Löcher sind durch den Ersatz von Startblock..Endblock durch »Loch«\n" " markiert.\n" " Alle Datei-Offsets und Plattenblöcke sind Einheiten aus 512-Byte-Blöcken.\n" " -a -- gibt die Attributs-Verzweigungs-Karte statt der\n" " Daten-Verzweigung aus.\n" " -d -- unterdrückt ein DMAPI-Lese-Ereignis, Offline-Teile werden als Löcher\n" " betrachtet.\n" " -l -- zeigt außerdem die Länge von jedem Bereich in 512-Byte Blöcken.\n" " Anmerkung: Das »bmap« für irreguläre Dateien kann bereitgestellt werden,\n" " statt der Datei die passend geöffnet wurde (im Einzelnen darf sie\n" " Nur-Lesend geöffnet werden)\n" "\n" #: .././io/bmap.c:120 #, c-format msgid "%s: can't get geometry [\"%s\"]: %s\n" msgstr "%s: Geometrie [»%s«] kann nicht ermittelt werden: %s\n" #: .././io/bmap.c:128 #, c-format msgid "%s: cannot read attrs on \"%s\": %s\n" msgstr "%s: attrs auf »%s« können nicht gelesen werden: %s\n" #: .././io/bmap.c:146 #, c-format msgid "%s: malloc of %d bytes failed.\n" msgstr "%s: Speicherallokation von %d Bytes fehlgeschlagen.\n" #: .././io/bmap.c:194 #, c-format msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" msgstr "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" #: .././io/bmap.c:225 #, c-format msgid "%s: cannot realloc %d bytes\n" msgstr "%s: %d Bytes können nicht realloziert werden.\n" #: .././io/bmap.c:234 #, c-format msgid "%s: no extents\n" msgstr "%s: keine Bereiche\n" #: .././io/bmap.c:248 .././io/bmap.c:376 #, c-format msgid "hole" msgstr "Loch" #: .././io/bmap.c:257 #, c-format msgid " %lld blocks\n" msgstr "%lld Blöcke\n" #: .././io/bmap.c:336 msgid "EXT" msgstr "EXT" #: .././io/bmap.c:337 msgid "FILE-OFFSET" msgstr "DATEI-VERSATZ" #: .././io/bmap.c:338 msgid "RT-BLOCK-RANGE" msgstr "RT-BLOCK-AUSWAHL" #: .././io/bmap.c:338 msgid "BLOCK-RANGE" msgstr "BLOCK-AUSWAHL" #: .././io/bmap.c:339 msgid "AG" msgstr "AG" #: .././io/bmap.c:340 msgid "AG-OFFSET" msgstr "AG-VERSATZ" #: .././io/bmap.c:341 msgid "TOTAL" msgstr "GESAMT" #: .././io/bmap.c:342 msgid " FLAGS" msgstr "MARKIERUNGEN" #: .././io/bmap.c:410 #, c-format msgid " FLAG Values:\n" msgstr "MARKIERUNGS-Werte:\n" #: .././io/bmap.c:411 #, c-format msgid " %*.*o Unwritten preallocated extent\n" msgstr " %*.*o Ungeschriebener vorher zugeteiler Bereich\n" #: .././io/bmap.c:413 #, c-format msgid " %*.*o Doesn't begin on stripe unit\n" msgstr " %*.*o Beginnt nicht auf der Stripe-Einheit\n" #: .././io/bmap.c:415 #, c-format msgid " %*.*o Doesn't end on stripe unit\n" msgstr " %*.*o Endet nicht auf der Stripe-Einheit\n" #: .././io/bmap.c:417 #, c-format msgid " %*.*o Doesn't begin on stripe width\n" msgstr " %*.*o Beginnt nicht auf der Stripe-Breite\n" #: .././io/bmap.c:419 #, c-format msgid " %*.*o Doesn't end on stripe width\n" msgstr " %*.*o Endet nicht auf der Stripe-Breite\n" #: .././io/bmap.c:430 msgid "bmap" msgstr "bmap" #: .././io/bmap.c:435 msgid "[-adlpv] [-n nx]" msgstr "[-adlpv] [-n nx]" #: .././io/bmap.c:436 msgid "print block mapping for an XFS file" msgstr "Blockkarte für eine XFS-Datei ausgeben" #: .././io/mmap.c:76 #, c-format msgid "offset (%lld) is before start of mapping (%lld)\n" msgstr "Versatz (%lld) liegt vor dem Start der Kartierung (%lld)\n" #: .././io/mmap.c:82 #, c-format msgid "offset (%lld) is beyond end of mapping (%lld)\n" msgstr "Versatz (%lld) liegt hinter dem Ende der Kartierung (%lld)\n" #: .././io/mmap.c:87 #, c-format msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" msgstr "Bereich (%lld:%lld) liegt außerhalb der Kartierung (%lld:%ld)\n" #: .././io/mmap.c:93 #, c-format msgid "offset address (%p) is not page aligned\n" msgstr "Versatz-Adresse (%p) ist nicht an der Seite ausgerichtet\n" #: .././io/mmap.c:133 #, c-format msgid "" "\n" " maps a range within the current file into memory\n" "\n" " Example:\n" " 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" "\n" " Memory maps a range of a file for subsequent use by other xfs_io commands.\n" " With no arguments, mmap shows the current mappings. The current mapping\n" " can be set by using the single argument form (mapping number or address).\n" " If two arguments are specified (a range), a new mapping is created and the\n" " following options are available:\n" " -r -- map with PROT_READ protection\n" " -w -- map with PROT_WRITE protection\n" " -x -- map with PROT_EXEC protection\n" " If no protection mode is specified, all are used by default.\n" "\n" msgstr "" "\n" " bildet einen Bereich innerhalb der aktuellen Datei im Speicher ab.\n" "\n" " Beispiel:\n" " »mmap -rw 0 1m« - bildet ein Megabyte vom Anfang der aktuellen Datei ab\n" "\n" " Speicher eines Dateibereiches für eine nachfolgende Benutzung durch andere\n" " xfs-io-Befehle abbilden.\n" " Ohne Argumente zeigt mmap die derzeitige Kartierung. Die derzeitige\n" " Kartierung kann durch Benutzung einer einzelnen Argument-Form\n" " (Kartierungsnummer oder Adresse) gesetzt werden.\n" " Wenn zwei Argumente angegeben wurden (ein Bereich) wird eine neue\n" " Kartierung erstellt und die folgenden Optionen sind verfügbar:\n" " -r -- Karte mit PROT_READ-Schutz\n" " -w -- Karte mit PROT_WRITE-Schutz\n" " -x -- Karte mit PROT_EXEC-Schutz\n" " Wenn kein Schutz-Modus angegeben wurde, werden standardmäßig alle benutzt.\n" "\n" #: .././io/mmap.c:254 #, c-format msgid "" "\n" " flushes a range of bytes in the current memory mapping\n" "\n" " Writes all modified copies of pages over the specified range (or entire\n" " mapping if no range specified) to their backing storage locations. Also,\n" " optionally invalidates so that subsequent references to the pages will be\n" " obtained from their backing storage locations (instead of cached copies).\n" " -a -- perform asynchronous writes (MS_ASYNC)\n" " -i -- invalidate mapped pages (MS_INVALIDATE)\n" " -s -- perform synchronous writes (MS_SYNC)\n" "\n" msgstr "" "\n" " leert einen Bereich von Bytes in der aktuellen Speicher-Kartierung\n" "\n" " Schreibt alle veränderten Seitenkopien über den angegebenen Bereich (oder \n" " die vollständige Kartierung, wenn kein Bereich angegeben wurde) auf ihre\n" " zusätzlichen Speicherorte. Außerdem werden optional alle außer Kraft\n" " gesetzt, so dass nachfolgende Verweise von den zusätzlichen Speicherorten\n" " (anstelle der Kopien im Zwischenspeicher) erhalten werden.\n" " -a -- asynchrones Schreiben ausführen (MS_ASYNC)\n" " -i -- kartierte Seiten ungültig erklären (MS_INVALIDATE)\n" " -s -- synchrones Schreiben ausführen (MS_SYNC)\n" "\n" #: .././io/mmap.c:330 #, c-format msgid "" "\n" " reads a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" "\n" " Accesses a range of the current memory mapping, optionally dumping it to\n" " the standard output stream (with -v option) for subsequent inspection.\n" " -f -- verbose mode, dump bytes with offsets relative to start of file.\n" " -r -- reverse order; start accessing from the end of range, moving " "backward\n" " -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" " The accesses are performed sequentially from the start offset by default.\n" " Notes:\n" " References to whole pages following the end of the backing file results\n" " in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" " on various filesystem conditions, including quota exceeded errors, and\n" " for physical device errors (such as unreadable disk blocks). No attempt\n" " has been made to catch signals at this stage...\n" "\n" msgstr "" "\n" " liest einen Bereich von Bytes in die aktuelle Speicherkartierung\n" "\n" " Beispiel:\n" " »mread -v 512 20« - Auszug von gelesenen 20 Bytes von 512 Bytes in die\n" " Kartierung\n" "\n" " Greift auf einen Bereich der aktuellen Speicherkartierung zu oder gibt\n" " sie optional zum Standard-Ausgabe-Strom aus (mit der »-v«-Option) für die\n" " nachfolgende Überprüfung.\n" " -f -- detaillierte Ausgabe - gibt Bytes mit relativem Versatz zum Anfang\n" " der Datei aus.\n" " -r -- umgekehrte Reihenfolge; Zugriff vom Ende des Bereiches beginnen und\n" " rückwärts bewegen.\n" " -v -- detaillierte Ausgabe - gibt Bytes mit relativem Versatz zum Anfang\n" " der Kartierung aus.\n" " Standardmäßig werden die Zugriffe der Reihe nach vom Versatz des Anfangs\n" " durchgeführt.\n" " Anmerkungen:\n" " Bezieht sich auf die ganzen Seiten, die dem Ende der\n" " Zusatzdatei-Ergebnisse bei der Zusendung des SIGBUS-Signals folgen.\n" " SIGBUS-Signale können außerdem unter unterschiedlichen\n" " Dateisystem-Bedingungen gesandt werden, einschließlich\n" " Quota-Überschreitungs-Fehlern und physischen Gerätefehlern (wie\n" " unlesbaren Platten-Blocks). Es wurde kein Versuch unternommen auf dieser\n" " Ebene Signale abzufangen...\n" "\n" #: .././io/mmap.c:494 #, c-format msgid "" "\n" " dirties a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" "\n" " Stores a byte into memory for a range within a mapping.\n" " The default stored value is 'X', repeated to fill the range specified.\n" " -S -- use an alternate seed character\n" " -r -- reverse order; start storing from the end of range, moving backward\n" " The stores are performed sequentially from the start offset by default.\n" "\n" msgstr "" "\n" " verunreinigt einen Bereich von Bytes in die aktuelle Speicherkartierung\n" "\n" " Beispiel:\n" " »mwrite 512 20« - schreibt 20 Bytes von 512 Bytes a in die aktuelle\n" " Kartierung\n" "\n" " Speichert ein Byte in den Speicher für einen Bereich innerhalb einer \n" " Kartierung. Der Standard-Speicherwert ist »X«, das wiederholt wird um \n" " den angegebenen Bereich zu füllen.\n" " -S -- verwende ein anderes Füllzeichen\n" " -r -- umgekehrte Reihenfolge; Speichern vom Ende des Bereiches beginnen\n" " und rückwärts bewegen.\n" " Standardmäßig wird der Reihe nach vom Versatz des Anfangs gespeichert.\n" "\n" #: .././io/mmap.c:580 msgid "mmap" msgstr "mmap" #: .././io/mmap.c:581 msgid "mm" msgstr "mm" #: .././io/mmap.c:586 msgid "[N] | [-rwx] [off len]" msgstr "[N] | [-rwx] [off len]" #: .././io/mmap.c:588 msgid "mmap a range in the current file, show mappings" msgstr "mmap eines Bereiches der aktuellen Datei, Kartierungen anzeigen" #: .././io/mmap.c:591 msgid "mread" msgstr "mread" #: .././io/mmap.c:592 msgid "mr" msgstr "mr" #: .././io/mmap.c:597 msgid "[-r] [off len]" msgstr "[-r] [off len]" #: .././io/mmap.c:599 msgid "reads data from a region in the current memory mapping" msgstr "liest Daten aus einer Region der derzeitigen Speicherkartierung" #: .././io/mmap.c:602 msgid "msync" msgstr "msync" #: .././io/mmap.c:603 msgid "ms" msgstr "ms" #: .././io/mmap.c:608 msgid "[-ais] [off len]" msgstr "[-ais] [off len]" #: .././io/mmap.c:609 msgid "flush a region in the current memory mapping" msgstr "leere eine Region der derzeitigen Speicherkartierung" #: .././io/mmap.c:612 msgid "munmap" msgstr "munmap" #: .././io/mmap.c:613 msgid "mu" msgstr "mu" #: .././io/mmap.c:618 msgid "unmaps the current memory mapping" msgstr "die aktuelle Speicherkartierung entladen" #: .././io/mmap.c:620 msgid "mwrite" msgstr "mwrite" #: .././io/mmap.c:621 msgid "mw" msgstr "mw" #: .././io/mmap.c:626 msgid "[-r] [-S seed] [off len]" msgstr "[-r] [-S seed] [off len]" #: .././io/mmap.c:628 msgid "writes data into a region in the current memory mapping" msgstr "schreibt Daten in eine Region der derzeitigen Speicherkartierung" #: .././io/open.c:53 msgid "socket" msgstr "Socket" #: .././io/open.c:55 msgid "directory" msgstr "Verzeichnis" #: .././io/open.c:57 msgid "char device" msgstr "zeichenorientiertes Gerät" #: .././io/open.c:59 msgid "block device" msgstr "blockorientiertes Gerät" #: .././io/open.c:61 msgid "regular file" msgstr "reguläre Datei" #: .././io/open.c:63 msgid "symbolic link" msgstr "symbolischer Verweis" #: .././io/open.c:65 msgid "fifo" msgstr "fifo" #: .././io/open.c:80 .././io/open.c:725 #, c-format msgid "fd.path = \"%s\"\n" msgstr "fd.path = \"%s\"\n" #: .././io/open.c:81 #, c-format msgid "fd.flags = %s,%s,%s%s%s%s\n" msgstr "fd.flags = %s,%s,%s%s%s%s\n" #: .././io/open.c:91 #, c-format msgid "stat.ino = %lld\n" msgstr "stat.ino = %lld\n" #: .././io/open.c:92 #, c-format msgid "stat.type = %s\n" msgstr "stat.type = %s\n" #: .././io/open.c:93 #, c-format msgid "stat.size = %lld\n" msgstr "stat.size = %lld\n" #: .././io/open.c:94 #, c-format msgid "stat.blocks = %lld\n" msgstr "stat.blocks = %lld\n" #: .././io/open.c:96 #, c-format msgid "stat.atime = %s" msgstr "stat.atime = %s" #: .././io/open.c:97 #, c-format msgid "stat.mtime = %s" msgstr "stat.mtime = %s" #: .././io/open.c:98 #, c-format msgid "stat.ctime = %s" msgstr "stat.ctime = %s" #: .././io/open.c:107 #, c-format msgid "fsxattr.xflags = 0x%x " msgstr "fsxattr.xflags = 0x%x " #: .././io/open.c:109 #, c-format msgid "fsxattr.projid = %u\n" msgstr "fsxattr.projid = %u\n" #: .././io/open.c:110 #, c-format msgid "fsxattr.extsize = %u\n" msgstr "fsxattr.extsize = %u\n" #: .././io/open.c:111 #, c-format msgid "fsxattr.nextents = %u\n" msgstr "fsxattr.nextents = %u\n" #: .././io/open.c:112 #, c-format msgid "fsxattr.naextents = %u\n" msgstr "fsxattr.naextents = %u\n" #: .././io/open.c:117 #, c-format msgid "dioattr.mem = 0x%x\n" msgstr "dioattr.mem = 0x%x\n" #: .././io/open.c:118 #, c-format msgid "dioattr.miniosz = %u\n" msgstr "dioattr.miniosz = %u\n" #: .././io/open.c:119 #, c-format msgid "dioattr.maxiosz = %u\n" msgstr "dioattr.maxiosz = %u\n" #: .././io/open.c:243 #, c-format msgid "" "\n" " opens a new file in the requested mode\n" "\n" " Example:\n" " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" "\n" " Opens a file for subsequent use by all of the other xfs_io commands.\n" " With no arguments, open uses the stat command to show the current file.\n" " -F -- foreign filesystem file, disallow XFS-specific commands\n" " -a -- open with the O_APPEND flag (append-only mode)\n" " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" " -f -- open with O_CREAT (create the file if it doesn't exist)\n" " -m -- permissions to use in case a new file is created (default 0600)\n" " -n -- open with O_NONBLOCK\n" " -r -- open with O_RDONLY, the default is O_RDWR\n" " -s -- open with O_SYNC\n" " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" " -R -- mark the file as a realtime XFS file immediately after opening it\n" " Note1: usually read/write direct IO requests must be blocksize aligned;\n" " some kernels, however, allow sectorsize alignment for direct IO.\n" " Note2: the bmap for non-regular files can be obtained provided the file\n" " was opened correctly (in particular, must be opened read-only).\n" "\n" msgstr "" "\n" " öffnet eine Datei in der angeforderten Weise\n" "\n" " Beispiel:\n" " »open -cd /tmp/data« - erstellt/öffnet Datei zum Lesen/Schreiben für\n" " direkte IO\n" "\n" " Öffnet eine Datei zum anschließenden Gebrauch durch alle anderen\n" " XFS-Befehle\n" " Ohne Argumente benutzt »Öffnen« den »stat«-Befehl um die aktuelle Datei\n" " anzuzeigen.\n" " -F -- Datei eines fremden Dateisystems, erlaube keine XFS-spezifischen\n" " Befehle\n" " -a -- öffne mit der O_APPEND-Markierung (Nur-anhängen-Modus)\n" " -d -- öffne mit O_DIRECT (nicht gepufferte IO, vermerkt\n" " Ausrichtungsbeschränkungen)\n" " -f -- öffne mit O_CREAT (erstellt die Datei, wenn es sie nicht gibt)\n" " -m -- Rechte, die bei der Erstellung neuer Dateien gesetzt werden\n" " (Vorgabe 0600)\n" " -n -- öffne mit O_NONBLOCK\n" " -r -- öffne mit O_RDONLY, Vorgabe ist O_RDWR\n" " -s -- öffne mit O_SYNC\n" " -t -- öffne mit O_TRUNC (Datei auf die Länge Null kürzen, wenn es sie gibt\n" " -R -- Datei direkt nach dem Öffnen als Echtzeit-XFS-Datei markieren.\n" " Anmerkung1: Direkte Lese-/Schreib-IO-Abfragen müssen üblicherweise an der\n" " Blockgröße ausgerichtet werden. Einige Kernel erlauben jedoch\n" " Ausrichtung an der Sektorgröße für direktes IO.\n" " Anmerkung2: Das »bmap« für irreguläre Dateien kann bereitgestellt werden,\n" " statt der Datei die passend geöffnet wurde (im Einzelnen darf\n" " sie Nur-Lesend geöffnet werden)\n" "\n" #: .././io/open.c:380 #, c-format msgid "" "\n" " displays the project identifier associated with the current path\n" "\n" " Options:\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, but only list projects on directories\n" "\n" msgstr "" "\n" " zeigt die Projektkennung, die mit dem derzeitigen Pfad verbunden wird\n" "\n" " Optionen:\n" " -R -- rekursiv absteigend (nützlich, wenn die aktuelle Datei ein\n" " Verzeichnis ist)\n" " -D -- rekursiv absteigend, aber nur die Attribute von Verzeichnissen\n" " auflisten\n" "\n" #: .././io/open.c:446 #, c-format msgid "projid = %u\n" msgstr "projid = %u\n" #: .././io/open.c:454 #, c-format msgid "" "\n" " modifies the project identifier associated with the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying projects on directories\n" "\n" msgstr "" "\n" " zeigt die Projektkennung, die mit dem derzeitigen Pfad verbunden wird\n" "\n" " -R -- rekursiv absteigend (nützlich, wenn die aktuelle Datei ein\n" " Verzeichnis ist)\n" " -D -- rekursiv absteigend, aber nur die Attribute von Verzeichnissen\n" " auflisten\n" "\n" #: .././io/open.c:513 #, c-format msgid "invalid project ID -- %s\n" msgstr "Falsche Projekt-ID -- %s\n" #: .././io/open.c:529 #, c-format msgid "" "\n" " report or modify preferred extent size (in bytes) for the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying extsize on directories\n" "\n" msgstr "" "\n" " zeigt oder ändert die vorgesehene Größe des Extents (in Bytes) des\n" " aktuellen Verzeichnisses\n" "\n" " -R -- rekursiv absteigend (nützlich, wenn der aktuelle Pfad ein\n" " Verzeichnis ist)\n" " -D -- rekursiv absteigend, nur die »extsize« von Verzeichnissen ändern\n" "\n" #: .././io/open.c:572 #, c-format msgid "invalid target file type - file %s\n" msgstr "ungültiger Ziel-Dateityp - Datei %s\n" #: .././io/open.c:658 #, c-format msgid "non-numeric extsize argument -- %s\n" msgstr "nicht-numerisches »extsize«-Argument -- %s\n" #: .././io/open.c:705 #, c-format msgid "invalid setfl argument -- '%c'\n" msgstr "ungültiges »setfl«-Argument -- »%c«\n" #: .././io/open.c:729 #, c-format msgid "statfs.f_bsize = %lld\n" msgstr "statfs.f_bsize = %lld\n" #: .././io/open.c:730 #, c-format msgid "statfs.f_blocks = %lld\n" msgstr "statfs.f_blocks = %lld\n" #: .././io/open.c:732 #, c-format msgid "statfs.f_frsize = %lld\n" msgstr "statfs.f_frsize = %lld\n" #: .././io/open.c:734 #, c-format msgid "statfs.f_bavail = %lld\n" msgstr "statfs.f_bavail = %lld\n" #: .././io/open.c:736 #, c-format msgid "statfs.f_files = %lld\n" msgstr "statfs.f_files = %lld\n" #: .././io/open.c:737 #, c-format msgid "statfs.f_ffree = %lld\n" msgstr "statfs.f_ffree = %lld\n" #: .././io/open.c:744 #, c-format msgid "geom.bsize = %u\n" msgstr "geom.bsize = %u\n" #: .././io/open.c:745 #, c-format msgid "geom.agcount = %u\n" msgstr "geom.agcount = %u\n" #: .././io/open.c:746 #, c-format msgid "geom.agblocks = %u\n" msgstr "geom.agblocks = %u\n" #: .././io/open.c:747 #, c-format msgid "geom.datablocks = %llu\n" msgstr "geom.datablocks = %llu\n" #: .././io/open.c:749 #, c-format msgid "geom.rtblocks = %llu\n" msgstr "geom.rtblocks = %llu\n" #: .././io/open.c:751 #, c-format msgid "geom.rtextents = %llu\n" msgstr "geom.rtextents = %llu\n" #: .././io/open.c:753 #, c-format msgid "geom.rtextsize = %u\n" msgstr "geom.rtextsize = %u\n" #: .././io/open.c:754 #, c-format msgid "geom.sunit = %u\n" msgstr "geom.sunit = %u\n" #: .././io/open.c:755 #, c-format msgid "geom.swidth = %u\n" msgstr "geom.swidth = %u\n" #: .././io/open.c:760 #, c-format msgid "counts.freedata = %llu\n" msgstr "counts.freedata = %llu\n" #: .././io/open.c:762 #, c-format msgid "counts.freertx = %llu\n" msgstr "counts.freertx = %llu\n" #: .././io/open.c:764 #, c-format msgid "counts.freeino = %llu\n" msgstr "counts.freeino = %llu\n" #: .././io/open.c:766 #, c-format msgid "counts.allocino = %llu\n" msgstr "counts.allocino = %llu\n" #: .././io/open.c:775 msgid "open" msgstr "öffnen" #: .././io/open.c:776 msgid "o" msgstr "o" #: .././io/open.c:781 msgid "[-acdrstx] [path]" msgstr "[-acdrstx] [Pfad]" #: .././io/open.c:782 msgid "open the file specified by path" msgstr "öffne die Datei, die durch den Pfad gegeben ist" #: .././io/open.c:785 msgid "stat" msgstr "stat" #: .././io/open.c:790 msgid "[-v]" msgstr "[-v]" #: .././io/open.c:791 msgid "statistics on the currently open file" msgstr "Statistiken über die derzeit geöffnete Datei" #: .././io/open.c:793 msgid "close" msgstr "schließen" #: .././io/open.c:794 msgid "c" msgstr "c" #: .././io/open.c:799 msgid "close the current open file" msgstr "die derzeit offene Datei schließen" #: .././io/open.c:801 msgid "setfl" msgstr "setfl" #: .././io/open.c:803 msgid "[-adx]" msgstr "[-adx]" #: .././io/open.c:806 msgid "set/clear append/direct flags on the open file" msgstr "setzen-/löschen- anhängen-/direkt-Markierungen auf die offene Datei" #: .././io/open.c:808 msgid "statfs" msgstr "statfs" #: .././io/open.c:812 msgid "statistics on the filesystem of the currently open file" msgstr "Statistiken über das Dateisystem der derzeit offenen Datei" #: .././io/open.c:814 msgid "chproj" msgstr "chproj" #: .././io/open.c:816 msgid "[-D | -R] projid" msgstr "[-D | -R] projid" #: .././io/open.c:821 msgid "change project identifier on the currently open file" msgstr "ändert Projekt-Kennzeichnung der derzeit offenen Datei" #: .././io/open.c:824 msgid "lsproj" msgstr "lsproj" #: .././io/open.c:826 msgid "[-D | -R]" msgstr "[-D | -R]" #: .././io/open.c:831 msgid "list project identifier set on the currently open file" msgstr "" "zeigt die für die derzeit offene Datei gesetzten Projekt-Kennzeichnungen" #: .././io/open.c:834 msgid "extsize" msgstr "extsize" #: .././io/open.c:836 msgid "[-D | -R] [extsize]" msgstr "[-D | -R] [extsize]" #: .././io/open.c:841 msgid "get/set preferred extent size (in bytes) for the open file" msgstr "gib/setze bevorzugte Extent-Größe (in Bytes) für die offene Datei" #: .././io/parent.c:49 #, c-format msgid "%s%s" msgstr "%s%s" #: .././io/parent.c:54 #, c-format msgid "inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n" msgstr "Inode-Pfad für Inode: %llu ist falsch - Pfad »%s« gibt es nicht\n" #: .././io/parent.c:58 #, c-format msgid "path \"%s\" does not stat for inode: %llu; err = %s\n" msgstr "Pfad »%s« enthält keinen Status für Inode: %llu; err = %s\n" #: .././io/parent.c:67 #, c-format msgid "path \"%s\" found\n" msgstr "Pfad »%s« nicht gefunden\n" #: .././io/parent.c:73 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong inode#\n" msgstr "Inode-Pfad für Inode: %llu ist falsch - falscher Inode#\n" #: .././io/parent.c:77 .././io/parent.c:107 #, c-format msgid "ino mismatch for path \"%s\" %llu vs %llu\n" msgstr "ino für Pfad »%s« stimmt nicht überein %llu gegen %llu\n" #: .././io/parent.c:85 #, c-format msgid "inode number match: %llu\n" msgstr "Inode-Nummer stimmt überein: %llu\n" #: .././io/parent.c:95 #, c-format msgid "parent path \"%s\" does not stat: %s\n" msgstr "Elternpfad »%s« enthält keinen Status: %s\n" #: .././io/parent.c:103 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong parent inode#\n" msgstr "Inode-Pfad für Inode: %llu ist falsch - falscher Eltern-Inode#\n" #: .././io/parent.c:116 #, c-format msgid "parent ino match for %llu\n" msgstr "Eltern-»ino« stimmt überein für %llu\n" #: .././io/parent.c:137 #, c-format msgid "parentpaths failed for ino %llu: %s\n" msgstr "»parentpaths« fehlgeschlagen für »ino« %llu: %s\n" #: .././io/parent.c:148 #, c-format msgid "inode-path for inode: %llu is missing\n" msgstr "Inode-Pfad für Inode: %llu fehlt\n" #: .././io/parent.c:171 #, c-format msgid "can't stat mount point \"%s\": %s\n" msgstr "Status für Einhängepunkt »%s« kann nicht abgefragt werden: %s\n" #: .././io/parent.c:192 #, c-format msgid "failed to get bulkstat information for inode %llu\n" msgstr "Bulkstat-Information für Inode %llu zu bekommen ist fehlgeschlagen\n" #: .././io/parent.c:198 #, c-format msgid "failed to get valid bulkstat information for inode %llu\n" msgstr "" "gültige Bulkstat-Information für Inode %llu zu bekommen ist\n" "fehlgeschlagen\n" #: .././io/parent.c:210 #, c-format msgid "checking inode %llu\n" msgstr "Inode %llu wird geprüft\n" #: .././io/parent.c:224 #, c-format msgid "syssgi bulkstat failed: %s\n" msgstr "syssgi bulkstat fehlgeschlagen:%s\n" #: .././io/parent.c:246 #, c-format msgid "unable to open \"%s\" for jdm: %s\n" msgstr "außerstande »%s« für jdm zu öffnen: %s\n" #: .././io/parent.c:256 #, c-format msgid "unable to allocate buffers: %s\n" msgstr "außerstande Puffer zu allozieren: %s\n" #: .././io/parent.c:265 #, c-format msgid "num errors: %d\n" msgstr "»num«-Fehler: %d\n" #: .././io/parent.c:267 #, c-format msgid "succeeded checking %llu inodes\n" msgstr "Prüfung von %llu Inodes erfolgreich\n" #: .././io/parent.c:277 #, c-format msgid "p_ino = %llu\n" msgstr "p_ino = %llu\n" #: .././io/parent.c:278 #, c-format msgid "p_gen = %u\n" msgstr "p_gen = %u\n" #: .././io/parent.c:279 #, c-format msgid "p_reclen = %u\n" msgstr "p_reclen = %u\n" #: .././io/parent.c:281 #, c-format msgid "p_name = \"%s%s\"\n" msgstr "p_name = »%s%s«\n" #: .././io/parent.c:283 #, c-format msgid "p_name = \"%s\"\n" msgstr "p_name = »%s«\n" #: .././io/parent.c:305 #, c-format msgid "%s: failed path_to_fshandle \"%s\": %s\n" msgstr "%s: path_to_fshandle »%s« fehlgeschlagen: %s\n" #: .././io/parent.c:312 #, c-format msgid "%s: path_to_handle failed for \"%s\"\n" msgstr "%s: path_to_handle fehlgeschlagen für»%s«\n" #: .././io/parent.c:319 #, c-format msgid "%s: unable to allocate parent buffer: %s\n" msgstr "%s: außerstande Eltern-Puffer zu allozieren: %s\n" #: .././io/parent.c:340 #, c-format msgid "%s: %s call failed for \"%s\": %s\n" msgstr "%s: %s-Aufruf fehlgeschlagen für »%s«: %s\n" #: .././io/parent.c:349 #, c-format msgid "%s: inode-path is missing\n" msgstr "%s: Inode-Pfad fehlt\n" #: .././io/parent.c:380 #, c-format msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" msgstr "Datei-Argument »%s« ist nicht in einem eingehängten XFS-Dateisystem\n" #: .././io/parent.c:420 #, c-format msgid "" "\n" " list the current file's parents and their filenames\n" "\n" " -c -- check the current file's file system for parent consistency\n" " -p -- list the current file's parents and their full paths\n" " -v -- verbose mode\n" "\n" msgstr "" "\n" " liste die Eltern der derzeitigen Datei und ihre Dateinamen auf\n" "\n" " -c -- prüfe das Dateisystem der derzeitigen Datei auf Vollständigkeit der\n" " Eltern\n" " -p -- liste die Eltern der derzeitigen Datei und ihre vollständigen\n" " Dateinamen auf\n" " -v -- detaillierte Ausgabe\n" "\n" #: .././io/parent.c:432 msgid "parent" msgstr "Eltern" #: .././io/parent.c:436 msgid "[-cpv]" msgstr "[-cpv]" #: .././io/parent.c:438 msgid "print or check parent inodes" msgstr "Eltern-Inodes ausgeben oder prüfen" #: .././libdisk/lvm.c:60 #, c-format msgid "Warning - LVM device, but no lvdisplay(8) found\n" msgstr "Warnung: LVM-Gerät, aber es wurde kein lvdisplay(8) gefunden\n" #: .././libdisk/lvm.c:70 .././libdisk/dm.c:73 #, c-format msgid "Could not open pipe\n" msgstr "Weiterleitung kann nicht geöffnet werden\n" #: .././libdisk/lvm.c:85 .././libdisk/dm.c:88 #, c-format msgid "Failed to execute %s\n" msgstr "Ausführen von %s fehlgeschlagen\n" #: .././libdisk/lvm.c:89 #, c-format msgid "Failed forking lvdisplay process\n" msgstr "Erstellen des »lvdisplay«-Unterprozesses fehlgeschlagen\n" #: .././libdisk/drivers.c:35 #, c-format msgid "Cannot stat %s: %s\n" msgstr "Kann Status für »%s« nicht abfragen:%s\n" #: .././libdisk/md.c:61 #, c-format msgid "Error getting MD array device from %s\n" msgstr "Fehler beim Ermitteln des MD-Array-Geräts von %s\n" #: .././libdisk/md.c:68 #, c-format msgid "Couldn't malloc device string\n" msgstr "malloc von Gerätzeichenkette konnte nicht durchgeführt werden\n" #: .././libdisk/md.c:84 #, c-format msgid "Error getting MD array info from %s\n" msgstr "Fehler beim Ermitteln der MD-Array-Informationen von %s\n" #: .././libdisk/dm.c:57 #, c-format msgid "Warning - device mapper device, but no dmsetup(8) found\n" msgstr "" "Warnung: »device mapper«-Gerät, aber es wurde kein dmsetup(8) gefunden\n" #: .././libdisk/dm.c:92 #, c-format msgid "Failed forking dmsetup process\n" msgstr "Erstellen des »dmsetup«-Unterprozesses fehlgeschlagen\n" #: .././libxcmd/command.c:85 #, c-format msgid "bad argument count %d to %s, expected at least %d arguments\n" msgstr "falsche Argument-Anzahl %d für %s, mindestens %d Argumente erwartet\n" #: .././libxcmd/command.c:89 #, c-format msgid "bad argument count %d to %s, expected %d arguments\n" msgstr "falsche Argument-Anzahl %d für %s, %d Argumente erwartet\n" #: .././libxcmd/command.c:93 #, c-format msgid "bad argument count %d to %s, expected between %d and %d arguments\n" msgstr "" "falsche Argument-Anzahl %d für %s, zwischen %d und %d Argumente erwartet\n" #: .././libxcmd/command.c:155 #, c-format msgid "cannot strdup command '%s': %s\n" msgstr "strdup-Befehl »%s« konnte nicht ausgeführt werden: %s\n" #: .././libxcmd/command.c:171 .././libxcmd/command.c:189 #, c-format msgid "command \"%s\" not found\n" msgstr "Befehl »%s« nicht gefunden\n" #: .././libxcmd/help.c:86 msgid "help" msgstr "Hilfe" #: .././libxcmd/help.c:87 msgid "?" msgstr "?" #: .././libxcmd/quit.c:36 msgid "quit" msgstr "beenden" #: .././libxcmd/quit.c:37 msgid "q" msgstr "q" #: .././libxcmd/quit.c:42 msgid "exit the program" msgstr "das Programm beenden" #: .././libxcmd/paths.c:77 #, c-format msgid "%s: warning - out of memory\n" msgstr "%s: Warnung - außerhalb des Speichers\n" #: .././libxcmd/paths.c:85 #, c-format msgid "%s: warning - cannot find %s: %s\n" msgstr "%s: Warnung - %s kann nicht gefunden werden: %s\n" #: .././libxcmd/paths.c:251 #, c-format msgid "%s: getmntinfo() failed: %s\n" msgstr "%s: getmntinfo() fehlgeschlagen: %s\n" #: .././libxcmd/paths.c:331 #, c-format msgid "%s: cannot find mount point for path `%s': %s\n" msgstr "%s: Einhängepunkt für Pfad »%s« kann nicht gefunden werden: %s\n" #: .././libxcmd/paths.c:367 #, c-format msgid "%s: cannot initialise path table: %s\n" msgstr "%s: Pfad-Tabelle kann nicht initialisiert werden: %s\n" #: .././libxcmd/paths.c:382 #, c-format msgid "%s: cannot setup path for mount %s: %s\n" msgstr "%s: Pfad zum Einhängen von %s kann nicht eingerichtet werden: %s\n" #: .././libxcmd/paths.c:395 #, c-format msgid "%s: no mount table yet, so no projects\n" msgstr "%s: noch keine Einhänge-Tabelle, deshalb keine Projekte\n" #: .././libxcmd/paths.c:402 #, c-format msgid "%s: cannot setup path for project %s: %s\n" msgstr "%s: der Pfad für Projekt %s kann nicht eingerichtet werden: %s\n" #: .././libxcmd/paths.c:433 #, c-format msgid "%s: cannot setup path for project dir %s: %s\n" msgstr "" "%s: der Pfad für Projektverzeichnis %s kann nicht eingerichtet werden: %s\n" #: .././libxfs/darwin.c:41 #, c-format msgid "%s: error opening the device special file \"%s\": %s\n" msgstr "%s: Fehler beim Öffnen der gerätspezifischen Datei »%s«: %s\n" #: .././libxfs/darwin.c:48 #, c-format msgid "%s: can't tell if \"%s\" is writable: %s\n" msgstr "%s: ob Datei %s schreibbar ist, kann nicht gesagt werden: %s\n" #: .././libxfs/darwin.c:76 .././libxfs/freebsd.c:116 .././libxfs/irix.c:58 #: .././libxfs/linux.c:138 #, c-format msgid "%s: cannot stat the device file \"%s\": %s\n" msgstr "%s: kann Status für Gerätedatei »%s« nicht abfragen: %s\n" #: .././libxfs/darwin.c:86 #, c-format msgid "%s: can't determine device size: %s\n" msgstr "%s: Gerätgröße kann nicht bestimmt werden: %s\n" #: .././libxfs/darwin.c:139 .././libxfs/freebsd.c:198 .././libxfs/irix.c:106 #: .././libxfs/linux.c:216 #, c-format msgid "%s: can't determine memory size\n" msgstr "%s: Speichergröße kann nicht bestimmt werden\n" #: .././libxfs/freebsd.c:49 #, c-format msgid "%s: %s possibly contains a mounted filesystem\n" msgstr "%s: %s enthält möglicherweise ein eingehängtes Dateisystem\n" #: .././libxfs/freebsd.c:60 .././libxfs/linux.c:67 #, c-format msgid "%s: %s contains a mounted filesystem\n" msgstr "%s: %s enthält ein eingehängtes Dateisystem\n" #: .././libxfs/freebsd.c:75 .././libxfs/linux.c:85 #, c-format msgid "%s: %s contains a possibly writable, mounted filesystem\n" msgstr "" "%s: %s enthält ein möglicherweise beschreibbares eingehängtes Dateisystem\n" #: .././libxfs/freebsd.c:89 .././libxfs/linux.c:99 #, c-format msgid "%s: %s contains a mounted and writable filesystem\n" msgstr "%s: %s enthält ein eingehängtes und beschreibbares Dateisystem\n" #: .././libxfs/freebsd.c:129 #, c-format msgid "%s: Not a device or file: \"%s\"n" msgstr "%s: Kein Gerät oder Datei: »%s«n" #: .././libxfs/freebsd.c:136 #, c-format msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" msgstr "%s: DIOCGMEDIASIZE fehlgeschlagen in »%s«: %s\n" #: .././libxfs/freebsd.c:143 #, c-format msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" msgstr "%s: DIOCGSECTORSIZE fehlgeschlagen in »%s«: %s\n" #: .././libxfs/rdwr.c:40 #, c-format msgid "%s: %s can't memalign %d bytes: %s\n" msgstr "%s: %s konnte nicht memalign %d Bytes: %s\n" #: .././libxfs/rdwr.c:50 #, c-format msgid "%s: %s seek to offset %llu failed: %s\n" msgstr "%s: %s auf Versatz %llu zu positionieren fehlgeschlagen: %s\n" #: .././libxfs/rdwr.c:60 #, c-format msgid "%s: %s write failed: %s\n" msgstr "%s: %s schreiben fehlgeschlagen: %s\n" #: .././libxfs/rdwr.c:64 #, c-format msgid "%s: %s not progressing?\n" msgstr "%s: %s nicht durchführen?\n" #: .././libxfs/rdwr.c:319 #, c-format msgid "%s: %s can't memalign %u bytes: %s\n" msgstr "%s: %s konnte nicht memalign %u Bytes: %s\n" #: .././libxfs/rdwr.c:459 #, c-format msgid "%s: read failed: %s\n" msgstr "%s: lesen fehlgeschlagen: %s\n" #: .././libxfs/rdwr.c:502 #, c-format msgid "%s: pwrite64 failed: %s\n" msgstr "%s: pwrite64 fehlgeschlagen: %s\n" #: .././libxfs/rdwr.c:509 #, c-format msgid "%s: error - wrote only %d of %d bytes\n" msgstr "%s: Fehler - nur %d von %d Bytes wurden geschrieben\n" #: .././libxfs/trans.c:33 #, c-format msgid "%s: xact calloc failed (%d bytes): %s\n" msgstr "%s: xact calloc fehlgeschlagen (%d Bytes): %s\n" #: .././libxfs/trans.c:597 #, c-format msgid "%s: warning - itobp failed (%d)\n" msgstr "%s: Warnung - itobp fehlgeschlagen (%d)\n" #: .././libxfs/trans.c:605 #, c-format msgid "%s: warning - iflush_int failed (%d)\n" msgstr "%s: Warnung - iflush_int fehlgeschlagen (%d)\n" #: .././libxfs/trans.c:684 .././libxfs/trans.c:790 #, c-format msgid "%s: unrecognised log item type\n" msgstr "%s: nicht erkannter Protokoll-Element-Typ\n" #: .././libxfs/util.c:697 #, c-format msgid "%s: cannot reserve space: %s\n" msgstr "%s: Speicher konnte nicht reserviert werden: %s\n" #: .././libxfs/kmem.c:15 #, c-format msgid "%s: zone init failed (%s, %d bytes): %s\n" msgstr "%s: Zoneninitialisierung fehlgeschlagen (%s, %d Bytes): %s\n" #: .././libxfs/kmem.c:32 #, c-format msgid "%s: zone alloc failed (%s, %d bytes): %s\n" msgstr "%s: zuweisen von Zone fehlgeschlagen(%s, %d Bytes): %s\n" #: .././libxfs/kmem.c:56 #, c-format msgid "%s: malloc failed (%d bytes): %s\n" msgstr "%s: malloc fehlgeschlagen (%d Bytes): %s\n" #: .././libxfs/kmem.c:77 #, c-format msgid "%s: realloc failed (%d bytes): %s\n" msgstr "%s: realloc fehlgeschlagen (%d Bytes): %s\n" #: .././libxfs/linux.c:114 #, c-format msgid "%s: %s - cannot set blocksize on block device %s: %s\n" msgstr "" "%s: %s - Blockgröße auf blockorientiertem Gerät %s kann nicht gesetzt\n" "werden: %s\n" #: .././libxfs/linux.c:161 #, c-format msgid "%s: can't determine device size\n" msgstr "%s: Größe des Gerätes kann nicht bestimmt werden\n" #: .././libxfs/linux.c:169 #, c-format msgid "%s: warning - cannot get sector size from block device %s: %s\n" msgstr "" "%s: Warnung - Sektorgröße des blockorientierten Gerätes %s kann nicht\n" "erlangt werden: %s\n" #: .././libxfs/init.c:80 .././libxfs/init.c:179 #, c-format msgid "%s: %s: device %lld is not open\n" msgstr "%s: %s: Gerät %lld ist nicht geöffnet\n" #: .././libxfs/init.c:116 #, c-format msgid "%s: cannot stat %s: %s\n" msgstr "%s: kann Status für »%s« nicht abfragen: %s\n" #: .././libxfs/init.c:141 #, c-format msgid "%s: device %lld is already open\n" msgstr "%s: Gerät %lld ist bereits geöffnet\n" #: .././libxfs/init.c:154 #, c-format msgid "%s: %s: too many open devices\n" msgstr "%s: %s: zu viele offene Geräte\n" #: .././libxfs/init.c:197 #, c-format msgid "%s: can't find a character device matching %s\n" msgstr "%s: zeichenorientiertes Gerät, das auf %s passt wird nicht gefunden\n" #: .././libxfs/init.c:203 #, c-format msgid "%s: can't find a block device matching %s\n" msgstr "%s: blockorientiertes Gerät, das auf %s passt wird nicht gefunden\n" #: .././libxfs/init.c:318 #, c-format msgid "%s: can't get size for data subvolume\n" msgstr "%s: Größe des Daten des Unterdatenträgers kann nicht erlangt werden\n" #: .././libxfs/init.c:323 #, c-format msgid "%s: can't get size for log subvolume\n" msgstr "" "%s: Größe des Protokolls für Unterdatenträger kann nicht erlangt werden\n" #: .././libxfs/init.c:328 #, c-format msgid "%s: can't get size for realtime subvolume\n" msgstr "%s: Größe des Echtzeit-Unterdatenträgers kann nicht erlangt werden\n" #: .././libxfs/init.c:424 #, c-format msgid "%s: cannot read realtime bitmap inode (%d)\n" msgstr "%s: Echtzeit-Bitmap-Inode (%d) kann nicht gelesen werden\n" #: .././libxfs/init.c:434 #, c-format msgid "%s: cannot read realtime summary inode (%d)\n" msgstr "%s: Echtzeit-Zusammenfassungs-Inode (%d) kann nicht gelesen werden\n" #: .././libxfs/init.c:458 #, c-format msgid "%s: filesystem has a realtime subvolume\n" msgstr "%s: Dateisystem hat einen Echtzeit-Unterdatenträger\n" #: .././libxfs/init.c:480 #, c-format msgid "%s: realtime init - %llu != %llu\n" msgstr "%s: Echtzeitinitialisierung - %llu != %llu\n" #: .././libxfs/init.c:488 #, c-format msgid "%s: realtime size check failed\n" msgstr "%s: Prüfen der Echtzeit-Größe fehlgeschlagen\n" #: .././libxfs/init.c:590 #, c-format msgid "%s: size check failed\n" msgstr "%s: Prüfen der Größe fehlgeschlagen\n" #: .././libxfs/init.c:599 #, c-format msgid "%s: WARNING - filesystem uses v1 dirs,limited functionality provided.\n" msgstr "" "%s: WARNUNG - Dateisystem benutzt v1 dirs, begrenzte Funktionalität\n" "bereitgestellt.\n" #: .././libxfs/init.c:619 #, c-format msgid "%s: data size check failed\n" msgstr "%s: Prüfen der Datengröße fehlgeschlagen\n" #: .././libxfs/init.c:632 #, c-format msgid "%s: log size checks failed\n" msgstr "%s: Prüfen der Protokollgröße fehlgeschlagen\n" #: .././libxfs/init.c:643 #, c-format msgid "%s: realtime device init failed\n" msgstr "%s: Initialisieren von Echtzeitgerät fehlgeschlagen\n" #: .././libxfs/init.c:651 #, c-format msgid "%s: failed to alloc %ld bytes: %s\n" msgstr "%s: Zuweisen von %ld Bytes fehlgeschlagen: %s\n" #: .././libxfs/init.c:665 #, c-format msgid "%s: cannot read root inode (%d)\n" msgstr "%s: Wurzel-Inode (%d) kann nicht gelesen werden\n" #: .././libxfs/init.c:685 #, c-format msgid "%s: cannot init perag data (%d)\n" msgstr "%s: perag-Daten (%d) konnten nicht initialisiert werden\n" #: .././libxlog/util.c:37 #, c-format msgid "" "* ERROR: mismatched uuid in log\n" "* SB : %s\n" "* log: %s\n" msgstr "" "* FEHLER: uuid stimmt im Protokoll nicht überein\n" "* SB : %s\n" "* Protokoll : %s\n" #: .././libxlog/util.c:50 #, c-format msgid "" "\n" "LOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n" msgstr "" "\n" "LOG REC AT LSN Zyklus %d Block %d (0x%x, 0x%x)\n" #: .././libxlog/util.c:58 #, c-format msgid "* ERROR: bad magic number in log header: 0x%x\n" msgstr "* FEHLER: falsche Magische Zahl in Protokoll-Kopf: 0x%x\n" #: .././libxlog/util.c:67 #, c-format msgid "* ERROR: log format incompatible (log=%d, ours=%d)\n" msgstr "* FEHLER: Protokollformat inkompatibel (Protokoll=%d, ours=%d)\n" #: .././libxlog/util.c:77 .././libxlog/util.c:89 msgid "Bad log" msgstr "Falsches Protokoll" #: .././logprint/log_copy.c:44 .././logprint/log_dump.c:43 #, c-format msgid "%s: read error (%lld): %s\n" msgstr "%s: Lesefehler (%lld): %s\n" #: .././logprint/log_copy.c:49 .././logprint/log_dump.c:48 #, c-format msgid "%s: physical end of log at %lld\n" msgstr "%s: physisches Ende des Protokolls bei %lld\n" #: .././logprint/log_copy.c:53 #, c-format msgid "%s: short read? (%lld)\n" msgstr "%s: kurzes Lesen? (%lld)\n" #: .././logprint/log_copy.c:60 #, c-format msgid "%s: write error (%lld): %s\n" msgstr "%s: Schreibfehler (%lld): %s\n" #: .././logprint/log_copy.c:65 #, c-format msgid "%s: short write? (%lld)\n" msgstr "%s: kurzes Schreiben? (%lld)\n" #: .././logprint/log_dump.c:56 #, c-format msgid "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n" msgstr "%6lld HEADER Zyklus %d Ende %d:%06d Länge %6d ops %d\n" #: .././logprint/log_dump.c:67 #, c-format msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" msgstr "[%05lld - %05lld] Zyklus 0x%08x Neuer Zyklus 0x%08x\n" #: .././logprint/log_misc.c:131 #, c-format msgid "Oper (%d): tid: %x len: %d clientid: %s " msgstr "Oper (%d): tid: %x len: %d clientid: %s " #: .././logprint/log_misc.c:136 #, c-format msgid "flags: " msgstr "Markierungen: " #: .././logprint/log_misc.c:230 #, c-format msgid " Not enough data to decode further\n" msgstr " Nicht genug Daten, um weiter zu entschlüsseln\n" #: .././logprint/log_misc.c:234 #, c-format msgid " type: %s tid: %x num_items: %d\n" msgstr " Typ: %s tid: %x num_items: %d\n" #: .././logprint/log_misc.c:276 #, c-format msgid "" "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" msgstr "" "#regs: %d Start-blkno: %lld (0x%llx) Länge: %d bmap Größe: %d " "Markierungen: 0x%x\n" #: .././logprint/log_misc.c:282 #, c-format msgid "#regs: %d Not printing rest of data\n" msgstr "#regs: %d Rest der Daten wird nicht ausgegeben\n" #: .././logprint/log_misc.c:299 #, c-format msgid "SUPER BLOCK Buffer: " msgstr "SUPER-BLOCK-Puffer: " #: .././logprint/log_misc.c:301 .././logprint/log_misc.c:363 #: .././logprint/log_misc.c:389 #, c-format msgid "Out of space\n" msgstr "Außerhalb des Raums\n" #: .././logprint/log_misc.c:309 #, c-format msgid "icount: %lld ifree: %lld " msgstr "icount: %lld ifree: %lld " #: .././logprint/log_misc.c:313 #, c-format msgid "fdblks: %lld frext: %lld\n" msgstr "fdblks: %lld frext: %lld\n" #: .././logprint/log_misc.c:319 #, c-format msgid "AGI Buffer: XAGI " msgstr "AGI Buffer: XAGI " #: .././logprint/log_misc.c:322 #, c-format msgid "out of space\n" msgstr "Außerhalb des Raums\n" #: .././logprint/log_misc.c:325 #, c-format msgid "ver: %d " msgstr "ver: %d " #: .././logprint/log_misc.c:327 #, c-format msgid "seq#: %d len: %d cnt: %d root: %d\n" msgstr "seq#: %d Länge: %d cnt: %d Wurzel: %d\n" #: .././logprint/log_misc.c:332 #, c-format msgid "level: %d free#: 0x%x newino: 0x%x\n" msgstr "Stufe: %d free#: 0x%x newino: 0x%x\n" #: .././logprint/log_misc.c:342 #, c-format msgid "AGI unlinked data skipped " msgstr "AGI-Verweis gelöst, Daten übersprungen" #: .././logprint/log_misc.c:343 #, c-format msgid "(CONTINUE set, no space)\n" msgstr "(FORTFAHREN gesetzt, kein Raum)\n" #: .././logprint/log_misc.c:349 #, c-format msgid "bucket[%d - %d]: " msgstr "bucket[%d - %d]: " #: .././logprint/log_misc.c:361 #, c-format msgid "AGF Buffer: XAGF " msgstr "AGF Puffer: XAGF " #: .././logprint/log_misc.c:366 #, c-format msgid "ver: %d seq#: %d len: %d \n" msgstr "ver: %d seq#: %d Länge: %d \n" #: .././logprint/log_misc.c:370 #, c-format msgid "root BNO: %d CNT: %d\n" msgstr "Wurzel BNO: %d CNT: %d\n" #: .././logprint/log_misc.c:373 #, c-format msgid "level BNO: %d CNT: %d\n" msgstr "Stufe BNO: %d CNT: %d\n" #: .././logprint/log_misc.c:376 #, c-format msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" msgstr "1.: %d letzter: %d cnt: %d freeblks: %d längster: %d\n" #: .././logprint/log_misc.c:386 #, c-format msgid "DQUOT Buffer: DQ " msgstr "DQUOT Puffer: DQ " #: .././logprint/log_misc.c:393 #, c-format msgid "ver: %d flags: 0x%x id: %d \n" msgstr "ver: %d Markierungen: 0x%x id: %d \n" #: .././logprint/log_misc.c:396 #, c-format msgid "blk limits hard: %llu soft: %llu\n" msgstr "blk harte Limits: %llu weiche: %llu\n" #: .././logprint/log_misc.c:399 #, c-format msgid "blk count: %llu warns: %d timer: %d\n" msgstr "blk Anzahl: %llu Warnungen: %d Zeitnehmer: %d\n" #: .././logprint/log_misc.c:403 #, c-format msgid "ino limits hard: %llu soft: %llu\n" msgstr "ino harte Limits: %llu weiche: %llu\n" #: .././logprint/log_misc.c:406 #, c-format msgid "ino count: %llu warns: %d timer: %d\n" msgstr "ino-Anzahl: %llu Warnungen: %d Zeitnehmer: %d\n" #: .././logprint/log_misc.c:412 #, c-format msgid "BUF DATA\n" msgstr "BUF DATEN\n" #: .././logprint/log_misc.c:454 #, c-format msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "EFD: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_misc.c:461 #, c-format msgid "EFD: Not enough data to decode further\n" msgstr "EFD: Nicht genug Daten, um weiter zu entschlüsseln\n" #: .././logprint/log_misc.c:481 .././logprint/log_misc.c:490 #, c-format msgid "%s: xlog_print_trans_efi: malloc failed\n" msgstr "%s: xlog_print_trans_efi: malloc fehlgeschlagen\n" #: .././logprint/log_misc.c:498 #, c-format msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "EFI: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_misc.c:525 #, c-format msgid "QOFF: #regs: %d flags: 0x%x\n" msgstr "QOFF: #regs: %d Markierungen: 0x%x\n" #: .././logprint/log_misc.c:528 #, c-format msgid "QOFF: Not enough data to decode further\n" msgstr "QOFF: Nicht genug Daten, um weiter zu entschlüsseln\n" #: .././logprint/log_misc.c:537 #, c-format msgid "INODE CORE\n" msgstr "INODE CORE\n" #: .././logprint/log_misc.c:538 #, c-format msgid "magic 0x%hx mode 0%ho version %d format %d\n" msgstr "magischer 0x%hx Modus 0%ho Version %d Format %d\n" #: .././logprint/log_misc.c:541 #, c-format msgid "nlink %hd uid %d gid %d\n" msgstr "nlink %hd uid %d gid %d\n" #: .././logprint/log_misc.c:543 #, c-format msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" msgstr "atime 0x%x mtime 0x%x ctime 0x%x\n" #: .././logprint/log_misc.c:545 #, c-format msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" msgstr "Größe 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" #: .././logprint/log_misc.c:548 #, c-format msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" msgstr "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" #: .././logprint/log_misc.c:551 #, c-format msgid "flags 0x%x gen 0x%x\n" msgstr "Markierungen 0x%x gen 0x%x\n" #: .././logprint/log_misc.c:567 #, c-format msgid "SHORTFORM DIRECTORY size %d\n" msgstr "KURZFORM VERZEICHNIS-Größe %d\n" #: .././logprint/log_misc.c:573 #, c-format msgid "SHORTFORM DIRECTORY size %d count %d\n" msgstr "KURZFORM VERZEICHNIS-Größe %d Anzahl %d\n" #: .././logprint/log_misc.c:576 #, c-format msgid ".. ino 0x%llx\n" msgstr ".. ino 0x%llx\n" #: .././logprint/log_misc.c:584 #, c-format msgid "%s ino 0x%llx namelen %d\n" msgstr "%s ino 0x%llx namelen %d\n" #: .././logprint/log_misc.c:616 #, c-format msgid "INODE: " msgstr "INODE: " #: .././logprint/log_misc.c:617 #, c-format msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" msgstr "#regs: %d ino: 0x%llx Markierungen: 0x%x dsize: %d\n" #: .././logprint/log_misc.c:620 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr " blkno: %lld Länge: %d boff: %d\n" #: .././logprint/log_misc.c:625 #, c-format msgid "INODE: #regs: %d Not printing rest of data\n" msgstr "INODE: #regs: %d Rest der Daten nicht ausgeben\n" #: .././logprint/log_misc.c:658 #, c-format msgid "EXTENTS inode data\n" msgstr "EXTENTS Inode Daten\n" #: .././logprint/log_misc.c:669 #, c-format msgid "BTREE inode data\n" msgstr "BTREE Inode Daten\n" #: .././logprint/log_misc.c:680 #, c-format msgid "LOCAL inode data\n" msgstr "LOCAL Inode Daten\n" #: .././logprint/log_misc.c:694 #, c-format msgid "EXTENTS inode attr\n" msgstr "EXTENTS Inode attr\n" #: .././logprint/log_misc.c:705 #, c-format msgid "BTREE inode attr\n" msgstr "BTREE Inode attr\n" #: .././logprint/log_misc.c:716 #, c-format msgid "LOCAL inode attr\n" msgstr "LOCAL Inode attr\n" #: .././logprint/log_misc.c:728 #, c-format msgid "DEV inode: no extra region\n" msgstr "DEV Inode: Keine Extraregion\n" #: .././logprint/log_misc.c:733 #, c-format msgid "UUID inode: no extra region\n" msgstr "UUID Inode: Keine Extraregion\n" #: .././logprint/log_misc.c:741 msgid "xlog_print_trans_inode: illegal inode type" msgstr "xlog_print_trans_inode: Illegaler Inode-Typ" #: .././logprint/log_misc.c:769 #, c-format msgid "#regs: %d id: 0x%x" msgstr "#regs: %d id: 0x%x" #: .././logprint/log_misc.c:770 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr " blkno: %lld Länge: %d boff: %d\n" #: .././logprint/log_misc.c:774 #, c-format msgid "DQUOT: #regs: %d Not printing rest of data\n" msgstr "DQUOT: #regs: %d Rest der Daten nicht ausgeben\n" #: .././logprint/log_misc.c:793 #, c-format msgid "DQUOT: magic 0x%hx flags 0%ho\n" msgstr "DQUOT: Magische 0x%hx Markierungen 0%ho\n" #: .././logprint/log_misc.c:821 #, c-format msgid "%s: lseek64 to %lld failed: %s\n" msgstr "%s: lseek64 auf %lld fehlgeschlagen: %s\n" #: .././logprint/log_misc.c:864 #, c-format msgid "%s: xlog_print_record: malloc failed\n" msgstr "%s: xlog_print_record: malloc fehlgeschlagen\n" #: .././logprint/log_misc.c:873 #, c-format msgid "%s: xlog_print_record: read error\n" msgstr "%s: xlog_print_record: Lesefehler\n" #: .././logprint/log_misc.c:960 #, c-format msgid "Left over region from split log item\n" msgstr "Übrige Region des geteilten Protkollelements\n" #: .././logprint/log_misc.c:1004 #, c-format msgid "Unmount filesystem\n" msgstr "Dateisystem aushängen\n" #: .././logprint/log_misc.c:1009 #, c-format msgid "%s: unknown log operation type (%x)\n" msgstr "%s: unbekannter Protokolloperationstyp (%x)\n" #: .././logprint/log_misc.c:1044 #, c-format msgid "Header 0x%x wanted 0x%x\n" msgstr "Kopfzeile 0x%x gesucht 0x%x\n" #: .././logprint/log_misc.c:1058 #, c-format msgid "cycle: %d\tversion: %d\t" msgstr "Zyklus: %d\tVersion: %d\t" #: .././logprint/log_misc.c:1064 #, c-format msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" msgstr "Länge des Protokolldatensatzes: %d\tprev Versatz: %d\t\tnum ops: %d\n" #: .././logprint/log_misc.c:1070 .././logprint/log_misc.c:1112 #, c-format msgid "cycle num overwrites: " msgstr "Zyklus Nummer Überschreibungen: " #: .././logprint/log_misc.c:1079 #, c-format msgid "uuid: %s format: " msgstr "uuid: %s Format: " #: .././logprint/log_misc.c:1082 #, c-format msgid "unknown\n" msgstr "unbekannt\n" #: .././logprint/log_misc.c:1085 #, c-format msgid "little endian linux\n" msgstr "kleines Endian-Linux\n" #: .././logprint/log_misc.c:1088 #, c-format msgid "big endian linux\n" msgstr "großes Endian-Linux\n" #: .././logprint/log_misc.c:1091 #, c-format msgid "big endian irix\n" msgstr "großes Endian-Irix\n" #: .././logprint/log_misc.c:1097 #, c-format msgid "h_size: %d\n" msgstr "h_size: %d\n" #: .././logprint/log_misc.c:1109 #, c-format msgid "extended-header: cycle: %d\n" msgstr "extended-header: Zyklus: %d\n" #: .././logprint/log_misc.c:1125 #, c-format msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" msgstr "* FEHLER: Daten nach genullten Blöcken gefunden Block=%-21lld *\n" #: .././logprint/log_misc.c:1136 #, c-format msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" msgstr "* FEHLER: Kopfzeile Zyklus=%-11d Block=%-21lld *\n" #: .././logprint/log_misc.c:1147 #, c-format msgid "* ERROR: data block=%-21lld *\n" msgstr "* FEHLER: Datenblock=%-21lld *\n" #: .././logprint/log_misc.c:1158 #, c-format msgid "" "* ERROR: for header block=%lld\n" "* not enough hdrs for data length, required num = %d, hdr num = %d\n" msgstr "" "* ERROR: Für Kopfzeilenblock=%lld\n" "* nicht genügend hdrs für Datenlänge, benötigt num = %d, hdr num = %d\n" #: .././logprint/log_misc.c:1164 msgid "Not enough headers for data length." msgstr "Nicht genügend Kopfzeilen für Datenlänge." #: .././logprint/log_misc.c:1174 #, c-format msgid "%s: xlog_print: malloc failed for ext hdrs\n" msgstr "%s: xlog_print: malloc fehlgeschlagen für ext hdrs\n" #: .././logprint/log_misc.c:1220 .././logprint/log_misc.c:1295 #: .././logprint/log_misc.c:1361 .././logprint/log_misc.c:1398 #, c-format msgid "%s: physical end of log\n" msgstr "%s: Physisches Ende des Protokolls\n" #: .././logprint/log_misc.c:1226 .././logprint/log_misc.c:1300 #: .././logprint/log_misc.c:1413 #, c-format msgid "BLKNO: %lld\n" msgstr "BLKNO: %lld\n" #: .././logprint/log_misc.c:1283 #, c-format msgid "%s: problem finding oldest LR\n" msgstr "%s: Problem, das älteste LR zu finden\n" #: .././logprint/log_misc.c:1309 #, c-format msgid "%s: after %d zeroed blocks\n" msgstr "%s: Nach %d genullten Blöcken\n" #: .././logprint/log_misc.c:1373 msgid "illegal value" msgstr "unerlaubter Wert" #: .././logprint/log_misc.c:1379 #, c-format msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" msgstr "%s: %d geleerte Blöcke übersprungen in Bereich: %lld - %lld\n" #: .././logprint/log_misc.c:1384 #, c-format msgid "%s: totally cleared log\n" msgstr "%s: Gesamtes geleertes Protokoll\n" #: .././logprint/log_misc.c:1389 #, c-format msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" msgstr "%s: %d genullte Blöcke übersprungen in Bereich: %lld - %lld\n" #: .././logprint/log_misc.c:1394 #, c-format msgid "%s: totally zeroed log\n" msgstr "%s: Gesamtes genulltes Protokoll\n" #: .././logprint/log_misc.c:1410 msgid "xlog_find_head: bad read" msgstr "xlog_find_head: Falsch gelesen" #: .././logprint/log_misc.c:1466 #, c-format msgid "%s: logical end of log\n" msgstr "%s: Logisches Ende des Protokolls\n" #: .././logprint/log_misc.c:1558 #, c-format msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" msgstr "" "%s: Falsche Größe des efi-Formats: %u; erwartet %u oder %u; nextents = %u\n" #: .././logprint/log_print_all.c:98 #, c-format msgid "" "BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" msgstr "" "BUF: #regs:%d Start blkno:0x%llx Länge:%d bmap-Größe:%d " "Markierungen:0x%x\n" #: .././logprint/log_print_all.c:108 #, c-format msgid "\tSUPER Block Buffer:\n" msgstr "\tSUPER Block-Puffer:\n" #: .././logprint/log_print_all.c:111 #, c-format msgid "\t\ticount:%Ld ifree:%Ld " msgstr "\t\ticount:%Ld ifree:%Ld " #: .././logprint/log_print_all.c:114 #, c-format msgid "fdblks:%Ld frext:%Ld\n" msgstr "fdblks:%Ld frext:%Ld\n" #: .././logprint/log_print_all.c:117 #, c-format msgid "\t\tsunit:%u swidth:%u\n" msgstr "\t\tsunit:%u swidth:%u\n" #: .././logprint/log_print_all.c:122 #, c-format msgid "\tAGI Buffer: (XAGI)\n" msgstr "\tAGI-Puffer: (XAGI)\n" #: .././logprint/log_print_all.c:125 #, c-format msgid "\t\tver:%d " msgstr "\t\tver:%d " #: .././logprint/log_print_all.c:127 #, c-format msgid "seq#:%d len:%d cnt:%d root:%d\n" msgstr "seq#:%d Länge:%d cnt:%d Wurzel:%d\n" #: .././logprint/log_print_all.c:132 #, c-format msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" msgstr "\t\tStufe:%d free#:0x%x newino:0x%x\n" #: .././logprint/log_print_all.c:138 #, c-format msgid "\tAGF Buffer: (XAGF)\n" msgstr "\tAGF-Puffer: (XAGF)\n" #: .././logprint/log_print_all.c:141 #, c-format msgid "\t\tver:%d seq#:%d len:%d \n" msgstr "\t\tver:%d seq#:%d Länge:%d \n" #: .././logprint/log_print_all.c:145 #, c-format msgid "\t\troot BNO:%d CNT:%d\n" msgstr "\t\tWurzel-BNO:%d CNT:%d\n" #: .././logprint/log_print_all.c:148 #, c-format msgid "\t\tlevel BNO:%d CNT:%d\n" msgstr "\t\tStufe BNO:%d CNT:%d\n" #: .././logprint/log_print_all.c:151 #, c-format msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" msgstr "\t\t1.:%d letzter:%d cnt:%d freeblks:%d längster:%d\n" #: .././logprint/log_print_all.c:160 #, c-format msgid "\tDQUOT Buffer:\n" msgstr "\tDQUOT-Puffer:\n" #: .././logprint/log_print_all.c:163 #, c-format msgid "\t\tUIDs 0x%lx-0x%lx\n" msgstr "\t\tUIDs 0x%lx-0x%lx\n" #: .././logprint/log_print_all.c:168 #, c-format msgid "\tBUF DATA\n" msgstr "\tBUF-DATEN\n" #: .././logprint/log_print_all.c:190 #, c-format msgid "\tQUOTAOFF: #regs:%d type:%s\n" msgstr "\tQUOTAOFF: #regs:%d Typ:%s\n" #: .././logprint/log_print_all.c:205 #, c-format msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" msgstr "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" #: .././logprint/log_print_all.c:209 #, c-format msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" msgstr "\t\tmagische 0x%x\tVersion 0x%x\tID 0x%x (%d)\t\n" #: .././logprint/log_print_all.c:214 #, c-format msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" msgstr "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" #: .././logprint/log_print_all.c:220 #, c-format msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" msgstr "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" #: .././logprint/log_print_all.c:225 #, c-format msgid "\t\tbtimer 0x%x itimer 0x%x \n" msgstr "\t\tbtimer 0x%x itimer 0x%x \n" #: .././logprint/log_print_all.c:234 #, c-format msgid "\tCORE inode:\n" msgstr "\tCORE-Inode:\n" #: .././logprint/log_print_all.c:237 #, c-format msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" msgstr "\t\tmagische:%c%c Modus:0x%x ver:%d Format:%d onlink:%d\n" #: .././logprint/log_print_all.c:241 #, c-format msgid "\t\tuid:%d gid:%d nlink:%d projid:%d\n" msgstr "\t\tuid:%d gid:%d nlink:%d projid:%d\n" #: .././logprint/log_print_all.c:243 #, c-format msgid "\t\tatime:%d mtime:%d ctime:%d\n" msgstr "\t\tatime:%d mtime:%d ctime:%d\n" #: .././logprint/log_print_all.c:245 #, c-format msgid "\t\tflushiter:%d\n" msgstr "\t\tflushiter:%d\n" #: .././logprint/log_print_all.c:246 #, c-format msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" msgstr "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" #: .././logprint/log_print_all.c:250 #, c-format msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" msgstr "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" #: .././logprint/log_print_all.c:270 #, c-format msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" msgstr "\tINODE: #regs:%d ino:0x%llx Markierungen:0x%x dsize:%d\n" #: .././logprint/log_print_all.c:285 #, c-format msgid "\t\tDATA FORK EXTENTS inode data:\n" msgstr "\t\tDATA FORK EXTENTS Inode-Daten:\n" #: .././logprint/log_print_all.c:292 #, c-format msgid "\t\tDATA FORK BTREE inode data:\n" msgstr "\t\tDATA FORK BTREE Inode-Daten:\n" #: .././logprint/log_print_all.c:299 #, c-format msgid "\t\tDATA FORK LOCAL inode data:\n" msgstr "\t\tDATA FORK LOCAL Inode-Daten:\n" #: .././logprint/log_print_all.c:306 #, c-format msgid "\t\tDEV inode: no extra region\n" msgstr "\t\tDEV-Inode: Keine Extraregion\n" #: .././logprint/log_print_all.c:310 #, c-format msgid "\t\tUUID inode: no extra region\n" msgstr "\t\tUUID-Inode: Keine Extraregion\n" #: .././logprint/log_print_all.c:325 #, c-format msgid "\t\tATTR FORK EXTENTS inode data:\n" msgstr "\t\tATTR FORK EXTENTS Inode-Daten:\n" #: .././logprint/log_print_all.c:333 #, c-format msgid "\t\tATTR FORK BTREE inode data:\n" msgstr "\t\tATTR FORK BTREE Inode-Daten:\n" #: .././logprint/log_print_all.c:341 #, c-format msgid "\t\tATTR FORK LOCAL inode data:\n" msgstr "\t\tATTR FORK LOCAL Inode-Daten:\n" #: .././logprint/log_print_all.c:366 #, c-format msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_print_all.c:390 #, c-format msgid "%s: xlog_recover_print_efi: malloc failed\n" msgstr "%s: xlog_recover_print_efi: malloc fehlgeschlagen\n" #: .././logprint/log_print_all.c:398 #, c-format msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" msgstr "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" #: .././logprint/log_print_all.c:438 #, c-format msgid "xlog_recover_print_logitem: illegal type\n" msgstr "xlog_recover_print_logitem: Illegaler Typ\n" #: .././logprint/log_print_all.c:469 #, c-format msgid "%s: illegal type" msgstr "%s: Illegaler Typ" #: .././logprint/log_print_all.c:477 #, c-format msgid ": cnt:%d total:%d " msgstr ": cnt:%d gesamt:%d " #: .././logprint/log_print_all.c:479 #, c-format msgid "a:0x%lx len:%d " msgstr "a:0x%lx Länge:%d " #: .././logprint/log_print_trans.c:25 #, c-format msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" msgstr "TRANS: tid:0x%x Typ:%s #items:%d trans:0x%x q:0x%lx\n" #: .././logprint/log_print_trans.c:51 #, c-format msgid "%s: failed to find head and tail, error: %d\n" msgstr "%s: Kopf und Ende zu finden fehlgeschlagen, Fehler: %d\n" #: .././logprint/log_print_trans.c:56 #, c-format msgid " log tail: %lld head: %lld state: %s\n" msgstr " Protokollende: %lld Kopf: %lld Status: %s\n" #: .././logprint/log_print_trans.c:62 #, c-format msgid " override tail: %d\n" msgstr " Ende überschreiben: %d\n" #: .././logprint/log_print_trans.c:72 #, c-format msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" msgstr "%s: In xfs_do_recovery_pass fehlgeschlagen, Fehler: %d\n" #: .././logprint/logprint.c:42 #, c-format msgid "" "Usage: %s [options...] \n" "\n" "Options:\n" " -c\t try to continue if error found in log\n" " -C copy the log from the filesystem to filename\n" " -d\t dump the log in log-record format\n" " -f\t specified device is actually a file\n" " -l filename of external log\n" " -n\t don't try and interpret log data\n" " -o\t print buffer data in hex\n" " -s block # to start printing\n" " -v print \"overwrite\" data\n" " -t\t print out transactional view\n" "\t-b in transactional view, extract buffer info\n" "\t-i in transactional view, extract inode info\n" "\t-q in transactional view, extract quota info\n" " -D print only data; no decoding\n" " -V print version information\n" msgstr "" "Aufruf: %s [Optionen ...] \n" "\n" "Optionen:\n" " -c\t versuchen fortzufahren, wenn Fehler im Protokoll\n" " entdeckt wurde\n" " -C das Protokoll vom Dateisystem nach Dateiname kopieren\n" " -d\t Auszug des Protokolls im log-record-Format\n" " -f\t angegebenes Gerät ist derzeit eine Datei\n" " -l Dateiname des externen Protokolls\n" " -n\t Protokolldaten nicht ausprobieren und interpretieren\n" " -o\t Pufferdaten hexadezimal ausgeben\n" " -s Block #, um Ausgabe zu starten\n" " -v »overwrite«-Daten ausgeben\n" " -t\t Transaktionsansicht ausgeben\n" "\t-b in Transaktionsansicht, Pufferinformationen extrahieren\n" "\t-i in Transaktionsansicht, Inodeinformationen extrahieren\n" "\t-q in Transaktionsansicht, Quotainformationen extrahieren\n" " -D Daten nur ausgeben, nicht entschlüsseln\n" " -V Versionsinformationen ausgeben\n" #: .././logprint/logprint.c:75 #, c-format msgid " Can't open device %s: %s\n" msgstr " Gerät %s kann nicht geöffnet werden: %s\n" #: .././logprint/logprint.c:81 #, c-format msgid " read of XFS superblock failed\n" msgstr " Lesen des XFS-Superblocks fehlgeschlagen!\n" #: .././logprint/logprint.c:97 #, c-format msgid "" " external log device not specified\n" "\n" msgstr "" " externes Protokollgerät nicht angegeben\n" "\n" #: .././logprint/logprint.c:112 #, c-format msgid "Can't open file %s: %s\n" msgstr "Datei %s kann nicht geöffnet werden: %s\n" #: .././logprint/logprint.c:212 #, c-format msgid "xfs_logprint:\n" msgstr "xfs_logprint:\n" #: .././logprint/logprint.c:220 #, c-format msgid " data device: 0x%llx\n" msgstr " Datengerät: 0x%llx\n" #: .././logprint/logprint.c:223 #, c-format msgid " log file: \"%s\" " msgstr " Protokolldatei: »%s« " #: .././logprint/logprint.c:225 #, c-format msgid " log device: 0x%llx " msgstr " Protokollgerät: 0x%llx " #: .././logprint/logprint.c:228 #, c-format msgid "" "daddr: %lld length: %lld\n" "\n" msgstr "" "daddr: %lld Länge: %lld\n" "\n" #: .././mkfs/proto.c:60 #, c-format msgid "%s: failed to open %s: %s\n" msgstr "%s: Öffnen von %s fehlgeschlagen: %s\n" #: .././mkfs/proto.c:66 .././mkfs/proto.c:291 #, c-format msgid "%s: read failed on %s: %s\n" msgstr "%s: Lesen auf %s fehlgeschlagen: %s\n" #: .././mkfs/proto.c:71 #, c-format msgid "%s: proto file %s premature EOF\n" msgstr "%s: proto-Datei %s vorzeitiges EOF\n" #: .././mkfs/proto.c:108 msgid "cannot reserve space" msgstr "Speicher kann nicht reserviert werden" #: .././mkfs/proto.c:161 #, c-format msgid "%s: premature EOF in prototype file\n" msgstr "%s: verfrühtes EOF in Prototyp-Datei\n" #: .././mkfs/proto.c:180 msgid "error reserving space for a file" msgstr "Fehler beim Reservieren von Speicher für eine Datei" #: .././mkfs/proto.c:249 msgid "error allocating space for a file" msgstr "Fehler beim Allokieren von Speicher für eine Datei" #: .././mkfs/proto.c:253 #, c-format msgid "%s: cannot allocate space for file\n" msgstr "%s: Speicher für Datei kann nicht alloziert werden\n" #: .././mkfs/proto.c:316 msgid "directory createname error" msgstr "Verzeichnis-Namenserstellungs-Fehler" #: .././mkfs/proto.c:330 msgid "directory create error" msgstr "Verzeichnis-Erstellungsfehler" #: .././mkfs/proto.c:396 .././mkfs/proto.c:408 .././mkfs/proto.c:419 #: .././mkfs/proto.c:426 #, c-format msgid "%s: bad format string %s\n" msgstr "%s: schlechte Format-Zeichenkette %s\n" #: .././mkfs/proto.c:447 .././mkfs/proto.c:486 .././mkfs/proto.c:501 #: .././mkfs/proto.c:513 .././mkfs/proto.c:525 .././mkfs/proto.c:536 msgid "Inode allocation failed" msgstr "Inode-Allokation fehlgeschlagen" #: .././mkfs/proto.c:464 msgid "Inode pre-allocation failed" msgstr "Inode-Vorallokation fehlgeschlagen" #: .././mkfs/proto.c:474 msgid "Pre-allocated file creation failed" msgstr "Erzeugung der vorher zugeteiler Datei fehlgeschlagen" #: .././mkfs/proto.c:556 msgid "Directory creation failed" msgstr "Erstellung des Verzeichnisses fehlgeschlagen" #: .././mkfs/proto.c:580 msgid "Error encountered creating file from prototype file" msgstr "Fehler beim Erstellen einer Datei aus der Prototyp-Datei gefunden" #: .././mkfs/proto.c:630 msgid "Realtime bitmap inode allocation failed" msgstr "Zuweisung des Echtzeit-Bitmap-Inodes fehlgeschlagen" #: .././mkfs/proto.c:648 msgid "Realtime summary inode allocation failed" msgstr "Allokation des Echtzeit-Zusammenfassungs-Inodes fehlgeschlagen" #: .././mkfs/proto.c:675 msgid "Allocation of the realtime bitmap failed" msgstr "Zuweisung des Echtzeit-Bitmaps fehlgeschlagen" #: .././mkfs/proto.c:688 msgid "Completion of the realtime bitmap failed" msgstr "Vervollständigung des Echtzeit-Bitmaps fehlgeschlagen" #: .././mkfs/proto.c:712 msgid "Allocation of the realtime summary failed" msgstr "Allokation der Echtzeit-Zusammenfassung fehlgeschlagen" #: .././mkfs/proto.c:724 msgid "Completion of the realtime summary failed" msgstr "Vervollständigung der Echtzeit-Zusammenfassung fehlgeschlagen" #: .././mkfs/proto.c:741 msgid "Error initializing the realtime space" msgstr "Fehler beim Initialisieren des Echtzeit-Raumes" #: .././mkfs/proto.c:746 msgid "Error completing the realtime space" msgstr "Fehler beim vervollständigen des Echtzeit-Raumes" #: .././mkfs/xfs_mkfs.c:202 #, c-format msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" msgstr "" "su-/sw-Daten müssen in Verbindung mit sunit-/swidth-Daten benutzt werden\n" #: .././mkfs/xfs_mkfs.c:209 #, c-format msgid "both data sunit and data swidth options must be specified\n" msgstr "sunit- und swidth-Optionen müssen beide angegeben werden\n" #: .././mkfs/xfs_mkfs.c:218 #, c-format msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" msgstr "" "sunit-/swidth-Daten müssen in Verbindung mit su-/sw-Daten benutzt werden\n" #: .././mkfs/xfs_mkfs.c:225 #, c-format msgid "both data su and data sw options must be specified\n" msgstr "su- und sw-Optionen müssen beide angegeben werden\n" #: .././mkfs/xfs_mkfs.c:232 #, c-format msgid "data su must be a multiple of the sector size (%d)\n" msgstr "su-Daten müssen ein Vielfaches der Sektorgröße (%d) sein\n" #: .././mkfs/xfs_mkfs.c:243 #, c-format msgid "" "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" msgstr "" "Datenstreifenbreite (%d) muss ein Vielfaches der Datenstreifeneinheit (%d)\n" "sein\n" #: .././mkfs/xfs_mkfs.c:253 #, c-format msgid "log su should not be used in conjunction with log sunit\n" msgstr "" "su-Protokoll kann nicht in Verbindung mit sunit-Protokoll benutzt werden\n" #: .././mkfs/xfs_mkfs.c:262 #, c-format msgid "log sunit should not be used in conjunction with log su\n" msgstr "" "sunit-Protokoll kann nicht in Verbindung mit su-Protokoll benutzt werden\n" #: .././mkfs/xfs_mkfs.c:279 #, c-format msgid "%s: %s appears to contain an existing filesystem (%s).\n" msgstr "%s: %s scheint ein existierendes Dateisystem zu enthalten (%s).\n" #: .././mkfs/xfs_mkfs.c:285 #, c-format msgid "%s: %s appears to contain a partition table (%s).\n" msgstr "%s: %s scheint eine Partitionstabelle (%s) zu enthalten.\n" #: .././mkfs/xfs_mkfs.c:319 #, c-format msgid "log size %lld is not a multiple of the log stripe unit %d\n" msgstr "Protokollgröße %lld ist kein Vielfaches der Datenstreifeneinheit %d)\n" #: .././mkfs/xfs_mkfs.c:347 #, c-format msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" msgstr "" "Aufgrund der Streifenausrichtung ist die interne Protokollgröße (%lld) zu " "groß\n" #: .././mkfs/xfs_mkfs.c:349 #, c-format msgid "Must fit within an allocation group.\n" msgstr "Muss in eine Allokationsgruppe passen.\n" #: .././mkfs/xfs_mkfs.c:360 #, c-format msgid "log size %lld blocks too small, minimum size is %d blocks\n" msgstr "Protokollgröße %lld Blöcke zu klein, Mindestgröße ist %d Blöcke\n" #: .././mkfs/xfs_mkfs.c:366 #, c-format msgid "log size %lld blocks too large, maximum size is %lld blocks\n" msgstr "Protokollgröße %lld Blöcke zu groß, maximale Größe ist %lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:372 #, c-format msgid "log size %lld bytes too large, maximum size is %lld bytes\n" msgstr "Protokollgröße %lld Bytes zu groß, maximale Größe ist %lld Bytes\n" #: .././mkfs/xfs_mkfs.c:477 #, c-format msgid "agsize (%lldb) too small, need at least %lld blocks\n" msgstr "agsize (%lldb) zu klein, es werden mindestens %lld Blöcke benötigt\n" #: .././mkfs/xfs_mkfs.c:485 #, c-format msgid "agsize (%lldb) too big, maximum is %lld blocks\n" msgstr "agsize (%lldb) zu groß, maximal %lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:493 #, c-format msgid "agsize (%lldb) too big, data area is %lld blocks\n" msgstr "agsize (%lldb) zu groß, Datenbereich hat %lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:500 #, c-format msgid "too many allocation groups for size = %lld\n" msgstr "zu viele Allokations-Gruppen für Größe = %lld\n" #: .././mkfs/xfs_mkfs.c:502 #, c-format msgid "need at most %lld allocation groups\n" msgstr "es werden höchstens %lld Allokations-Gruppen benötigt\n" #: .././mkfs/xfs_mkfs.c:510 #, c-format msgid "too few allocation groups for size = %lld\n" msgstr "zu wenige Allokations-Gruppen für Größe = %lld\n" #: .././mkfs/xfs_mkfs.c:512 #, c-format msgid "need at least %lld allocation groups\n" msgstr "es werden mindestens %lld Allokations-Gruppen benötigt\n" #: .././mkfs/xfs_mkfs.c:525 #, c-format msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" msgstr "letzte AG-Größe %lld Blöcke zu klein, Mindestgröße ist %lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:536 #, c-format msgid "%lld allocation groups is too many, maximum is %lld\n" msgstr "%lld Allokations-Gruppen sind zu viel, Maximum ist %lld\n" #: .././mkfs/xfs_mkfs.c:560 #, c-format msgid "error reading existing superblock -- failed to memalign buffer\n" msgstr "" "Fehler beim Lesen des bestehenden Superblocks -- memalign des Puffers\n" "fehlgeschlagen\n" #: .././mkfs/xfs_mkfs.c:566 #, c-format msgid "existing superblock read failed: %s\n" msgstr "Lesen des bestehenden Superblocks fehlgeschlagen: %s\n" #: .././mkfs/xfs_mkfs.c:850 #, c-format msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" msgstr "" "%s: Geben Sie sunit-Daten in 512-Byte-Blöcken an, kein Einheit-Suffix\n" #: .././mkfs/xfs_mkfs.c:866 #, c-format msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" msgstr "" "%s: Geben Sie swidth-Daten in 512-Byte-Blöcken an, kein Einheit-Suffix\n" #: .././mkfs/xfs_mkfs.c:893 #, c-format msgid "%s: Specify data sw as multiple of su, no unit suffix\n" msgstr "%s: Geben Sie sw-Daten als Vielfaches von su an, kein Einheit-Suffix\n" #: .././mkfs/xfs_mkfs.c:1112 #, c-format msgid "Specify log sunit in 512-byte blocks, no size suffix\n" msgstr "Geben Sie sunit-Daten in 512-Byte-Blöcken an, kein Größe-Suffix\n" #: .././mkfs/xfs_mkfs.c:1369 #, c-format msgid "extra arguments\n" msgstr "Extra-Argumente\n" #: .././mkfs/xfs_mkfs.c:1375 #, c-format msgid "cannot specify both %s and -d name=%s\n" msgstr "es kann nicht beides angegeben werden %s und -d Name=%s\n" #: .././mkfs/xfs_mkfs.c:1392 #, c-format msgid "illegal block size %d\n" msgstr "unerlaubte Blockgröße %d\n" #: .././mkfs/xfs_mkfs.c:1411 #, c-format msgid "illegal sector size %d\n" msgstr "unerlaubte Sektorgröße %d\n" #: .././mkfs/xfs_mkfs.c:1416 #, c-format msgid "illegal log sector size %d\n" msgstr "unerlaubte Protokoll-Bereichs-Größe %d\n" #: .././mkfs/xfs_mkfs.c:1426 #, c-format msgid "illegal directory block size %d\n" msgstr "unerlaubte Verzeichnis-Block-Größe %d\n" #: .././mkfs/xfs_mkfs.c:1440 #, c-format msgid "both -d agcount= and agsize= specified, use one or the other\n" msgstr "" "beide -d agcount= und agsize= angegeben, benutzen Sie das eine oder\n" "das andere\n" #: .././mkfs/xfs_mkfs.c:1446 #, c-format msgid "if -d file then -d name and -d size are required\n" msgstr "wenn -d Datei, dann sind -d Name und -d Größe erforderlich\n" #: .././mkfs/xfs_mkfs.c:1455 #, c-format msgid "illegal data length %lld, not a multiple of %d\n" msgstr "unerlaubte Datenlänge %lld, kein Vielfaches von %d\n" #: .././mkfs/xfs_mkfs.c:1461 #, c-format msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" msgstr "" "Warnung: Datenlänge %lld ist kein Vielfaches von %d, wurde auf %lld gekürzt\n" #: .././mkfs/xfs_mkfs.c:1475 #, c-format msgid "if -l file then -l name and -l size are required\n" msgstr "wenn -l Datei, dann sind -l Name und -l Größe erforderlich\n" #: .././mkfs/xfs_mkfs.c:1484 #, c-format msgid "illegal log length %lld, not a multiple of %d\n" msgstr "unerlaubte Protokolllänge %lld, kein Vielfaches von %d\n" #: .././mkfs/xfs_mkfs.c:1491 #, c-format msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" msgstr "" "Warnung: Protokolllänge %lld ist kein Vielfaches von %d, wurde auf\n" "%lld gekürzt\n" #: .././mkfs/xfs_mkfs.c:1497 #, c-format msgid "if -r file then -r name and -r size are required\n" msgstr "wenn -r Datei, dann sind -r Name und -r Größe erforderlich\n" #: .././mkfs/xfs_mkfs.c:1506 #, c-format msgid "illegal rt length %lld, not a multiple of %d\n" msgstr "unerlaubte rt-Länge %lld, kein Vielfaches von %d\n" #: .././mkfs/xfs_mkfs.c:1513 #, c-format msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" msgstr "" "Warnung: rt-Länge %lld ist kein Vielfaches von %d, wurde auf %lld gekürzt\n" #: .././mkfs/xfs_mkfs.c:1526 #, c-format msgid "illegal rt extent size %lld, not a multiple of %d\n" msgstr "unerlaubte rt-Erweiterungs-Länge %lld, kein Vielfaches von %d\n" #: .././mkfs/xfs_mkfs.c:1532 #, c-format msgid "rt extent size %s too large, maximum %d\n" msgstr "rt-Erweiterungs-Länge %s zu groß, Maximum %d\n" #: .././mkfs/xfs_mkfs.c:1538 #, c-format msgid "rt extent size %s too small, minimum %d\n" msgstr "rt-Erweiterungs-Länge %s zu klein, Minimum %d\n" #: .././mkfs/xfs_mkfs.c:1582 #, c-format msgid "illegal inode size %d\n" msgstr "unerlaubte Inode-Größe %d\n" #: .././mkfs/xfs_mkfs.c:1587 #, c-format msgid "allowable inode size with %d byte blocks is %d\n" msgstr "zulässige Inode-Größe mit %d Byte-Blocks ist %d\n" #: .././mkfs/xfs_mkfs.c:1591 #, c-format msgid "allowable inode size with %d byte blocks is between %d and %d\n" msgstr "zulässige Inode-Größe mit %d Byte-Blocks liegt zwischen %d und %d\n" #: .././mkfs/xfs_mkfs.c:1599 #, c-format msgid "log stripe unit specified, using v2 logs\n" msgstr "logische Stripe-Einheit angegeben, v2-Protokolle werden benutzt\n" #: .././mkfs/xfs_mkfs.c:1617 #, c-format msgid "no device name given in argument list\n" msgstr "in der Argumenten-Liste ist kein Gerätename angegeben\n" #: .././mkfs/xfs_mkfs.c:1642 #, c-format msgid "%s: Use the -f option to force overwrite.\n" msgstr "%s: Benutzen Sie die -f-Option um das Überschreiben zu erzwingen.\n" #: .././mkfs/xfs_mkfs.c:1653 msgid "internal log" msgstr "Internes Protokoll" #: .././mkfs/xfs_mkfs.c:1655 msgid "volume log" msgstr "Datenträger-Protokoll" #: .././mkfs/xfs_mkfs.c:1657 #, c-format msgid "no log subvolume or internal log\n" msgstr "kein Unter-Datenträger-Protokoll oder internes Protokoll\n" #: .././mkfs/xfs_mkfs.c:1664 msgid "volume rt" msgstr "Datenträger rt" #: .././mkfs/xfs_mkfs.c:1669 #, c-format msgid "" "size %s specified for data subvolume is too large, maximum is %lld blocks\n" msgstr "" "für den Unter-Datenträger angegebene Größe %s ist zu groß, Maximum ist %lld\n" "Blöcke\n" #: .././mkfs/xfs_mkfs.c:1676 #, c-format msgid "can't get size of data subvolume\n" msgstr "Datenträgergröße kann nicht ermittelt werden\n" #: .././mkfs/xfs_mkfs.c:1681 #, c-format msgid "size %lld of data subvolume is too small, minimum %d blocks\n" msgstr "" "für den Unter-Datenträger angegebene Größe %lld ist zu klein, Minimum\n" "ist %d Blöcke\n" #: .././mkfs/xfs_mkfs.c:1688 #, c-format msgid "can't have both external and internal logs\n" msgstr "man kann nicht beides, externe und interne Protokolle, haben\n" #: .././mkfs/xfs_mkfs.c:1692 #, c-format msgid "data and log sector sizes must be equal for internal logs\n" msgstr "" "Daten- und Protokollbereichs-Größe müssen für interne Protokolle gleich " "sein\n" #: .././mkfs/xfs_mkfs.c:1698 #, c-format msgid "" "Warning: the data subvolume sector size %u is less than the sector size \n" "reported by the device (%u).\n" msgstr "" "Warnung: Die Datenträger-Sektorengröße %u ist kleiner als die Sektorengröße\n" "die vom Gerät (%u) vermeldet wurde.\n" #: .././mkfs/xfs_mkfs.c:1704 #, c-format msgid "" "Warning: the log subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" "Warnung: Die Datenträger-Protokoll-Sektorengröße %u ist kleiner als die\n" "Sektorengröße die vom Gerät (%u) vermeldet wurde.\n" #: .././mkfs/xfs_mkfs.c:1710 #, c-format msgid "" "Warning: the realtime subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" "Warnung: Die Datenträger-Echtzeit-Sektorengröße %u ist kleiner als die\n" "Sektorengröße die vom Gerät (%u) vermeldet wurde.\n" #: .././mkfs/xfs_mkfs.c:1724 #, c-format msgid "" "size %s specified for log subvolume is too large, maximum is %lld blocks\n" msgstr "" "für den Protokoll-Unter-Datenträger angegebene Größe %s ist zu groß, " "Maximum\n" "ist %lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:1731 #, c-format msgid "size specified for non-existent log subvolume\n" msgstr "Größe für nicht existierenden Protokoll-Unter-Datenträger angegeben\n" #: .././mkfs/xfs_mkfs.c:1734 #, c-format msgid "size %lld too large for internal log\n" msgstr "Größe %lld zu groß für internes Protokoll\n" #: .././mkfs/xfs_mkfs.c:1761 #, c-format msgid "" "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" msgstr "" "für den rt-Unter-Datenträger angegebene Größe %s ist zu groß, Maximum ist\n" "%lld Blöcke\n" #: .././mkfs/xfs_mkfs.c:1769 #, c-format msgid "size specified for non-existent rt subvolume\n" msgstr "Größe für nicht existierenden rt-Unter-Datenträger angegeben\n" #: .././mkfs/xfs_mkfs.c:1786 #, c-format msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" msgstr "agsize (%lld) kein Vielfaches der »fs blk«-Größe (%d)\n" #: .././mkfs/xfs_mkfs.c:1803 #, c-format msgid "" "%s: Specified data stripe unit %d is not the same as the volume stripe unit %" "d\n" msgstr "" "%s: Angegebene Daten-Stripe-Einheit %d ist nicht die gleiche wie die\n" "Datenträger-Stripe-Einheit %d\n" #: .././mkfs/xfs_mkfs.c:1810 #, c-format msgid "" "%s: Specified data stripe width %d is not the same as the volume stripe " "width %d\n" msgstr "" "%s: Angegebene Daten-Stripe-Breite %d ist nicht die gleiche wie die\n" "Datenträger-Stripe-Breite %d\n" #: .././mkfs/xfs_mkfs.c:1858 #, c-format msgid "agsize rounded to %lld, swidth = %d\n" msgstr "agsize gerundet auf %lld, swidth = %d\n" #: .././mkfs/xfs_mkfs.c:1865 #, c-format msgid "" "Allocation group size (%lld) is not a multiple of the stripe unit (%d)\n" msgstr "" "Zuordnungsgruppengröße (%lld) ist kein Vielfaches der Stripe-Einheit (%d)\n" #: .././mkfs/xfs_mkfs.c:1887 #, c-format msgid "" "Warning: AG size is a multiple of stripe width. This can cause performance\n" "problems by aligning all AGs on the same disk. To avoid this, run mkfs " "with\n" "an AG size that is one stripe unit smaller, for example %llu.\n" msgstr "" "Warnung: AG-Größe ist ein Vielfaches der Stripe-Breite. Dies kann zu\n" "Performance-Problem führen bei Ausrichtung aller AGs auf die gleiche\n" "Platte. Um dies zu vermeiden, führen Sie mkfs mit einer AG-Größe aus, die\n" "ein Stripe kleiner ist, zum Beispiel %llu.\n" #: .././mkfs/xfs_mkfs.c:1912 #, c-format msgid "" "%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%" "d)\n" msgstr "" "%s: Stripe-Einheit (%d) oder Stripe-Breite (%d) ist kein Vielfaches der\n" "Blockgröße (%d)\n" #: .././mkfs/xfs_mkfs.c:1944 #, c-format msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" msgstr "" "Protokoll-Stripe-Einheit (%d) muss ein Vielfaches der Blockgröße (%d) sein\n" #: .././mkfs/xfs_mkfs.c:1957 #, c-format msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" msgstr "Protokoll-Stripe-Einheit (%d Bytes) ist zu groß (Maximum ist 256KiB)\n" #: .././mkfs/xfs_mkfs.c:1960 #, c-format msgid "log stripe unit adjusted to 32KiB\n" msgstr "Protokoll-Stripe-Einheit angepasst auf 32KiB\n" #: .././mkfs/xfs_mkfs.c:1985 #, c-format msgid "internal log size %lld too large, must fit in allocation group\n" msgstr "" "interne Protokollgröße %lld zu groß, muss in die Allokationsgruppe\n" "passen\n" #: .././mkfs/xfs_mkfs.c:1992 #, c-format msgid "log ag number %d too large, must be less than %lld\n" msgstr "Protokoll-»ag«-Nummer %d zu groß, muss kleiner als %lld sein\n" #: .././mkfs/xfs_mkfs.c:2022 #, c-format msgid "" "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" msgstr "" "Metadaten =%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u\n" "Daten =%-22s bsize=%-6u Blöcke=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "Benennung =Version %-14u bsize=%-6u ascii-ci=%d\n" "Protokoll =%-22s bsize=%-6d Blöcke=%lld, Version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "Echtzeit =%-22s extsz=%-6d Blöcke=%lld, rtextents=%lld\n" #: .././mkfs/xfs_mkfs.c:2138 #, c-format msgid "%s: Growing the data section failed\n" msgstr "%s: Wachsen des Datenbereiches fehlgeschlagen\n" #: .././mkfs/xfs_mkfs.c:2168 #, c-format msgid "%s: filesystem failed to initialize\n" msgstr "%s: Initialisierung des Dateisystems fehlgeschlagen\n" #: .././mkfs/xfs_mkfs.c:2379 #, c-format msgid "%s: root inode created in AG %u, not AG 0\n" msgstr "%s: Wurzel-Inode in AG %u erstellt, nicht AG 0\n" #: .././mkfs/xfs_mkfs.c:2446 #, c-format msgid "Cannot specify both -%c %s and -%c %s\n" msgstr "Beides kann nicht angegeben werden -%c %s und -%c %s\n" #: .././mkfs/xfs_mkfs.c:2457 #, c-format msgid "Illegal value %s for -%s option\n" msgstr "Unerlaubter Wert %s für -%s-Option\n" #: .././mkfs/xfs_mkfs.c:2474 #, c-format msgid "-%c %s option requires a value\n" msgstr "»-%c %s«-Option benötigt einen Wert\n" #: .././mkfs/xfs_mkfs.c:2487 .././repair/xfs_repair.c:170 #, c-format msgid "option respecified\n" msgstr "Option wieder angegeben\n" #: .././mkfs/xfs_mkfs.c:2496 .././repair/xfs_repair.c:177 #, c-format msgid "unknown option -%c %s\n" msgstr "unbekannte Option -%c %s\n" #: .././mkfs/xfs_mkfs.c:2535 #, c-format msgid "blocksize not available yet.\n" msgstr "Blockgröße noch nicht verfügbar.\n" #: .././mkfs/xfs_mkfs.c:2561 #, c-format msgid "" "Usage: %s\n" "/* blocksize */\t\t[-b log=n|size=num]\n" "/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" "\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" "\t\t\t sectlog=n|sectsize=num\n" "/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2]\n" "/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" "\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" "\t\t\t lazy-count=0|1]\n" "/* label */\t\t[-L label (maximum 12 characters)]\n" "/* naming */\t\t[-n log=n|size=num,version=2|ci]\n" "/* prototype file */\t[-p fname]\n" "/* quiet */\t\t[-q]\n" "/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" "/* sectorsize */\t[-s log=n|size=num]\n" "/* version */\t\t[-V]\n" "\t\t\tdevicename\n" " is required unless -d name=xxx is given.\n" " is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n" " xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" " is xxx (512 byte blocks).\n" msgstr "" "Aufruf: %s\n" "/* Blockgröße */\t\t[-b log=n|size=num]\n" "/* Unter-Datenträger */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" "\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" "\t\t\t sectlog=n|sectsize=num\n" "/* Inode-Größe */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2]\n" "/* Protokoll-Datenträger */\t[-l agnum=n,internal,size=num,\n" "\t\t\t logdev=xxx,version=n\n" "\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" "\t\t\t lazy-count=0|1]\n" "/* Aufschrift */\t\t[-L label (maximal 12 Zeichen)]\n" "/* Benennung */\t\t[-n log=n|size=num,version=2|ci]\n" "/* Prototyp-Datei */\t[-p fname]\n" "/* ohne Ausgabe */\t\t[-q]\n" "/* Echtzeit-Unter-Datenträger */\t[-r extsize=num,size=num,rtdev=xxx]\n" "/* Sektorengröße */\t[-s log=n|size=num]\n" "/* Version */\t\t[-V]\n" "\t\t\tdevicename\n" " wird benötigt, außer wenn -d name=xxx angegeben ist.\n" " is xxx (Bytes), xxxs (Sektoren), xxxb (fs Blöcke), xxxk (xxx KiB),\n" " xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" " ist xxx (512 Byte-Blöcke).\n" #: .././quota/init.c:48 #, c-format msgid "Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n" msgstr "Aufruf: %s [-p Programm] [-c Befehl]... [-d Projekt]... [Pfad]\n" #: .././quota/path.c:39 #, c-format msgid "%sFilesystem Pathname\n" msgstr "%sDateisystem Pfadname\n" #: .././quota/path.c:40 msgid " " msgstr " " #: .././quota/path.c:43 #, c-format msgid "%c%03d%c " msgstr "%c%03d%c " #: .././quota/path.c:45 #, c-format msgid "%-19s %s" msgstr "%-19s %s" #: .././quota/path.c:48 #, c-format msgid " (project %u" msgstr " (Projekt %u" #: .././quota/path.c:50 #, c-format msgid ", %s" msgstr ", %s" #: .././quota/path.c:103 #, c-format msgid "No paths are available\n" msgstr "Es sind keine Pfade verfügbar\n" #: .././quota/path.c:124 msgid "path" msgstr "Pfad" #: .././quota/path.c:125 msgid "paths" msgstr "Pfade" #: .././quota/path.c:131 msgid "set current path, or show the list of paths" msgstr "aktuellen Pfad setzen oder Pfadliste anzeigen" #: .././quota/path.c:139 msgid "list known mount points and projects" msgstr "bekannte Einhängepunkte und Projekte auflisten" #: .././quota/edit.c:36 #, c-format msgid "" "\n" " modify quota limits for the specified user\n" "\n" " Example:\n" " 'limit bsoft=100m bhard=110m tanya\n" "\n" " Changes the soft and/or hard block limits, inode limits and/or realtime\n" " block limits that are currently being used for the specified user, group,\n" " or project. The filesystem identified by the current path is modified.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota limits\n" " -p -- modify project quota limits\n" " -u -- modify user quota limits\n" " The block limit values can be specified with a units suffix - accepted\n" " units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" "\n" " Quota-Beschränkungen für den angegebenen Anwender ändern\n" "\n" " Beispiel:\n" " 'limit bsoft=100m bhard=110m tanya\n" "\n" "Ändert die Soft-/Hard-Block-Quotas, Inode-Quotas und/oder\n" "Echtzeit-Block-Quotas, die derzeit für den angegebenen Anwender, die\n" "Gruppe oder das Projekt benutzt werden. Das durch den Pfad erkannte\n" "Dateisystem wird geändert.\n" " -d -- setzt die Standardwerte, die benutzt werden, wenn eine Datei neu\n" " erstellt wurde\n" " -g -- ändert Gruppen-Quota-Beschränkungen\n" " -p -- ändert Projekt-Quota-Beschränkungen\n" " -u -- ändert Anwender-Quota-Beschränkungen\n" " Die -block-Quota-Werte können mit einem einheitlichen Suffix\n" " angegeben werden - akzeptierte Einheiten sind: k (Kilobyte),\n" " m (Megabyte), g (Gigabyte) und t (Terabyte). Gruppe, Anwender, Projekt\n" " kann entweder durch Name oder Nummer angegeben werden.\n" "\n" #: .././quota/edit.c:59 #, c-format msgid "" "\n" " modify quota enforcement timeout for the current filesystem\n" "\n" " Example:\n" " 'timer -i 3days'\n" " (soft inode limit timer is changed to 3 days)\n" "\n" " Changes the timeout value associated with the block limits, inode limits\n" " and/or realtime block limits for all users, groups, or projects on the\n" " current filesystem.\n" " As soon as a user consumes the amount of space or number of inodes set as\n" " the soft limit, a timer is started. If the timer expires and the user is\n" " still over the soft limit, the soft limit is enforced as the hard limit.\n" " The default timeout is 7 days.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota timer\n" " -p -- modify project quota timer\n" " -u -- modify user quota timer\n" " -b -- modify the blocks-used timer\n" " -i -- modify the inodes-used timer\n" " -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" " The timeout value is specified as a number of seconds, by default.\n" " However, a suffix may be used to alternatively specify minutes (m),\n" " hours (h), days (d), or weeks (w) - either the full word or the first\n" " letter of the word can be used.\n" "\n" msgstr "" "\n" " Zeitüberschreitung des Erzwingens von Quota-Größen für das derzeitige\n" " Dateisystem ändern\n" "\n" " Beispiel:\n" " 'timer -i 3days'\n" " (weiche Inode-Zeitbeschränkung wird auf drei Tage geändert)\n" "\n" " Ändert den Wert der Zeitbeschränkung, der sich auf Block-, Inode und/oder\n" " Echtzeit-Blockbeschränkungen für alle Nutzer, Gruppen oder Projekte auf " "dem\n" " derzeitigen Dateisystem bezieht.\n" " Sobald ein Anwender einen Anteil am Speicher oder den Inodes belegt, der\n" " als weiche Beschränkung gesetzt ist, wird ein Zeitnehmer gestartet. Wenn\n" " der Zeitnehmer abläuft und der Anwender ist immer noch über der weichen\n" " Beschränkung, wird die weiche Beschränkung als harte Beschränkung\n" " erzwungen.\n" " Die Standard-Zeitbeschränkung beträgt sieben Tage.\n" " -d -- setzt die Standardwerte, wird benutzt, wenn zum ersten Mal eine " "Datei\n" " erstellt wird\n" " -g -- ändert Gruppen-Quota-Zeitnehmer\n" " -p -- ändert Projekt-Quota-Zeitnehmer\n" " -u -- ändert Anwender-Quota-Zeitnehmer\n" " -b -- ändert den für Blöcke benutzten Zeitnehmer\n" " -i -- ändert den für Inodes benutzten Zeitnehmer\n" " -r -- ändert den für Blöcke benutzten Zeitnehmer für den (optionalen)\n" " Echtzeit-Unterdatenträger\n" " Der Zeitüberschreitungswert ist standardmäßig als eine Anzahl von Sekunden\n" " angegeben. Allerdings kann eine Erweiterung angegeben werden um alternativ\n" " Minuten (m), Stunden (h), Tage (d) oder Wochen (w) anzugeben -sowohl das\n" " ganze Wort als auch der erste Buchstabe können benutzt werden.\n" "\n" #: .././quota/edit.c:91 #, c-format msgid "" "\n" " modify the number of quota warnings sent to the specified user\n" "\n" " Example:\n" " 'warn 2 jimmy'\n" " (tell the quota system that two warnings have been sent to user jimmy)\n" "\n" " Changes the warning count associated with the block limits, inode limits\n" " and/or realtime block limits for the specified user, group, or project.\n" " When a user has been warned the maximum number of times allowed, the soft\n" " limit is enforced as the hard limit. It is intended as an alternative to\n" " the timeout system, where the system administrator updates a count of the\n" " number of warnings issued to people, and they are penalised if the " "warnings\n" " are ignored.\n" " -d -- set maximum warning count, which triggers soft limit enforcement\n" " -g -- set group quota warning count\n" " -p -- set project quota warning count\n" " -u -- set user quota warning count\n" " -b -- set the blocks-used warning count\n" " -i -- set the inodes-used warning count\n" " -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" "\n" " Anzahl der Quota-Warnungen ändern, die zum angegebenen Anwender\n" " gesandt werden\n" "\n" " Beispiel:\n" " 'warn 2 Hans'\n" " (teilt dem Quota-System mit, dass zwei Warnungen an den Anwender Hans\n" " gesandt wurden)\n" " Ändert die Anzahl der Warnungen, die sich auf Block-, Inode und/oder\n" " Echtzeit-Blockbeschränkungen für den angegebenen Nutzer, die Gruppe oder\n" " das Projekt auf dem derzeitigen Dateisystem beziehen.\n" " Wenn ein Anwender die maximale Anzahl von Warnungen erhalten hat, wird die\n" " weiche Beschränkung zu einer harten Beschränkung. Es ist als Alternative\n" " zum Zeitbeschränkungs-System gedacht, bei dem der Systemadministrator die\n" " Anzahl der Warnungen aktualisiert, den Leuten ausgegeben werden und sie\n" " werden bestraft, wenn die Warnungen ignoriert werden.\n" " -d -- maximale Anzahl der Warnungen setzen, die weiche Beschränkungen\n" " auslösen.\n" " -g -- Anzahl der Warnungen für Gruppen-Quotas setzen\n" " -p -- Anzahl der Warnungen für Projekt-Quotas setzen\n" " -u -- Anzahl der Warnungen für Anwender-Quotas setzen\n" " -b -- Anzahl der Warnungen, die von Böcken benutzt werden, setzen\n" " -i -- Anzahl der Warnungen, die von Inodes benutzt werden, setzen\n" " -r -- Anzahl der Warnungen, die von Böcken benutzt werden, für einen\n" " (optionalen) Echtzeit-Unter-Datenträger setzen\n" " Nutzer/Gruppe/Projekt können entweder durch Name oder durch Nummer\n" " angegeben werden\n" "\n" #: .././quota/edit.c:145 #, c-format msgid "%s: cannot set limits: %s\n" msgstr "%s: Beschränkungen können nicht gesetzt werden: %s\n" #: .././quota/edit.c:166 .././quota/edit.c:563 #, c-format msgid "%s: invalid user name: %s\n" msgstr "%s: ungültiger Anwendername: %s\n" #: .././quota/edit.c:189 .././quota/edit.c:580 #, c-format msgid "%s: invalid group name: %s\n" msgstr "%s: ungültiger Gruppenname: %s\n" #: .././quota/edit.c:212 .././quota/edit.c:597 #, c-format msgid "%s: invalid project name: %s\n" msgstr "%s: ungültiger Projektname: %s\n" #: .././quota/edit.c:237 #, c-format msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" msgstr "%s: Warnung: »%s« in Quota-Blöcken ist 0 (unbegrenzt).\n" #: .././quota/edit.c:326 #, c-format msgid "%s: unrecognised argument %s\n" msgstr "%s: nicht erkanntes Argument %s\n" #: .././quota/edit.c:333 #, c-format msgid "%s: cannot find any valid arguments\n" msgstr "%s: es wurden keine gültigen Argumente gefunden\n" #: .././quota/edit.c:441 #, c-format msgid "%s: fopen on %s failed: %s\n" msgstr "%s: fopen von %s fehlgeschlagen: %s\n" #: .././quota/edit.c:473 #, c-format msgid "%s: cannot set timer: %s\n" msgstr "%s: Zeitnehmer kann nicht eingestellt werden: %s\n" #: .././quota/edit.c:547 #, c-format msgid "%s: cannot set warnings: %s\n" msgstr "%s: Warnungen können nicht gesetzt werden: %s\n" #: .././quota/edit.c:678 msgid "limit" msgstr "Beschränkung" #: .././quota/edit.c:683 msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" msgstr "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" #: .././quota/edit.c:684 msgid "modify quota limits" msgstr "Quota-Beschränkungen ändern" #: .././quota/edit.c:687 msgid "restore" msgstr "wieder herstellen" #: .././quota/edit.c:691 .././quota/report.c:33 .././quota/report.c:647 msgid "[-gpu] [-f file]" msgstr "[-gpu] [-f Datei]" #: .././quota/edit.c:692 msgid "restore quota limits from a backup file" msgstr "Quota-Beschränkungen aus einer Sicherungsdatei wiederherstellen" #: .././quota/edit.c:694 msgid "timer" msgstr "Zeitnehmer" #: .././quota/edit.c:698 .././quota/edit.c:706 msgid "[-bir] [-gpu] value -d|id|name" msgstr "[-bir] [-gpu] Ert -d|id|name" #: .././quota/edit.c:699 msgid "get/set quota enforcement timeouts" msgstr "ausgeben/setzen von Zeitbeschränkungen zum Erzwingen von Quotas" #: .././quota/edit.c:702 msgid "warn" msgstr "warnen" #: .././quota/edit.c:707 msgid "get/set enforcement warning counter" msgstr "ausgeben/setzen des Warnungs-Zählers zum Erzwingen" #: .././quota/free.c:29 #, c-format msgid "" "\n" " reports the number of free disk blocks and inodes\n" "\n" " This command reports the number of total, used, and available disk blocks.\n" " It can optionally report the same set of numbers for inodes and realtime\n" " disk blocks, and will report on all known XFS filesystem mount points and\n" " project quota paths by default (see 'print' command for a list).\n" " -b -- report the block count values\n" " -i -- report the inode count values\n" " -r -- report the realtime block count values\n" " -h -- report in a human-readable format\n" " -N -- suppress the header from the output\n" "\n" msgstr "" "\n" " meldet die Anzahl freier Blöcke und Inodes\n" "\n" " Dieser Befehl meldet die Anzahl von allen, den benutzten und den\n" " verfügbaren Plattenblöcken. Er kann wahlweise den gleichen Satz von\n" " Inode-Nummern und Echtzeit-Plattenblöcken melden sowie alle bekannten\n" " XFS-Dateisystem-Einhängepunkte und Standard-Projekt-Quota-Pfade\n" " (»print«-Befehl gibt eine Liste aus).\n" " -b -- Werte für die Block-Anzahl melden\n" " -i -- Werte für die Inode-Anzahl melden\n" " -r -- Werte für die Echtzeit-Block-Anzahl melden\n" " -h -- in einem lesbaren Format ausgeben\n" " -N -- in der Ausgabe die Kopfdaten unterdrücken\n" "\n" #: .././quota/free.c:146 #, c-format msgid "%s: project quota flag not set on %s\n" msgstr "%s: Projekt-Quota-Markierung ist nicht auf %s gesetzt\n" #: .././quota/free.c:155 #, c-format msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" msgstr "%s: Projekt-ID %u (%s) entspricht nicht ID %u (%s)\n" #: .././quota/free.c:220 #, c-format msgid "Filesystem " msgstr "Dateisystem" #: .././quota/free.c:220 #, c-format msgid "Filesystem " msgstr "Dateisystem" #: .././quota/free.c:223 #, c-format msgid " Size Used Avail Use%%" msgstr " Größe Benutzt Verfügbar Benutzung%%" #: .././quota/free.c:224 #, c-format msgid " 1K-blocks Used Available Use%%" msgstr " 1K-Blöcke Benutzt Verfügbar Benutzung%%" #: .././quota/free.c:227 #, c-format msgid " Inodes Used Free Use%%" msgstr " Inodes Benutzt Frei Use%%" #: .././quota/free.c:228 #, c-format msgid " Inodes IUsed IFree IUse%%" msgstr " Inodes IUsed IFree IUse%%" #: .././quota/free.c:229 #, c-format msgid " Pathname\n" msgstr " Pfadname\n" #: .././quota/free.c:360 msgid "df" msgstr "df" #: .././quota/free.c:361 .././repair/dir2.c:949 .././repair/dir2.c:1480 msgid "free" msgstr "frei" #: .././quota/free.c:365 msgid "[-bir] [-hn] [-f file]" msgstr "[-bir] [-hn] [-f Datei]" #: .././quota/free.c:366 msgid "show free and used counts for blocks and inodes" msgstr "Anzahl freier und benutzter Blöcke und Inodes anzeigen" #: .././quota/project.c:45 #, c-format msgid "" "\n" " list projects or setup a project tree for tree quota management\n" "\n" " Example:\n" " 'project -c logfiles'\n" " (match project 'logfiles' to a directory, and setup the directory tree)\n" "\n" " Without arguments, report all projects found in the /etc/projects file.\n" " The project quota mechanism in XFS can be used to implement a form of\n" " directory tree quota, where a specified directory and all of the files\n" " and subdirectories below it (i.e. a tree) can be restricted to using a\n" " subset of the available space in the filesystem.\n" "\n" " A managed tree must be setup initially using the -c option with a project.\n" " The specified project name or identifier is matched to one or more trees\n" " defined in /etc/projects, and these trees are then recursively descended\n" " to mark the affected inodes as being part of that tree - which sets inode\n" " flags and the project identifier on every file.\n" " Once this has been done, new files created in the tree will automatically\n" " be accounted to the tree based on their project identifier. An attempt to\n" " create a hard link to a file in the tree will only succeed if the project\n" " identifier matches the project identifier for the tree. The xfs_io " "utility\n" " can be used to set the project ID for an arbitrary file, but this can only\n" " be done by a privileged user.\n" "\n" " A previously setup tree can be cleared from project quota control through\n" " use of the -C option, which will recursively descend the tree, clearing\n" " the affected inodes from project quota control.\n" "\n" " The -c option can be used to check whether a tree is setup, it reports\n" " nothing if the tree is correct, otherwise it reports the paths of inodes\n" " which do not have the project ID of the rest of the tree, or if the inode\n" " flag is not set.\n" "\n" " The -p option can be used to manually specify project path without\n" " need to create /etc/projects file. This option can be used multiple times\n" " to specify multiple paths. When using this option only one projid/name can\n" " be specified at command line. Note that /etc/projects is also used if " "exists.\n" "\n" " The -d option allows to descend at most levels of " "directories\n" " below the command line arguments. -d 0 means only apply the actions\n" " to the top level of the projects. -d -1 means no recursion limit " "(default).\n" "\n" " The /etc/projid and /etc/projects file formats are simple, and described\n" " on the xfs_quota man page.\n" "\n" msgstr "" "\n" " Projekte auflisten oder einen Projektbaum für eine\n" " Baum-Quota-Verwaltung einrichten\n" "\n" " Beispiel:\n" " 'project -c Protokolldateien'\n" " (ordnet das Projekt »Protokolldateien« einem Verzeichnis zu und richtet\n" " den Verzeichnis-Baum ein)\n" "\n" " Ohne Argumente werden alle Projekte ausgegeben, die in der Datei\n" " /etc/projects gefunden werden.\n" " Der Projekt-Quota-Mechanismus von XFS kann benutzt werden um eine\n" " Form von Verzeichnis-Baum-Quotas umzusetzen, bei der ein angegebenes\n" " Verzeichnis und alle Dateien und Unterverzeichnisse unterhalb (z.B. ein \n" " Baum) darauf beschränkt werden können, eine Teilmenge des verfügbaren\n" " Speichers des Dateisystems zu benutzen\n" "\n" " Ein verwalteter Baum muss zuerst unter Benutzung der Option -c mit\n" " einem Projekt eingerichtet werden. Der angebegenen Projektname oder\n" " Bezeichner passt zu einem oder mehreren in /etc/projects definierten\n" " Bäumen und in diese Bäume wird rekursiv abgestiegen um die betroffenen\n" " Inodes durch Setzen von Inode-Kennzeichnungen und dem\n" " Projekt-Bezeichner für jede Datei als Teil des Baumes zu markieren\n" " Wenn dies erledigt ist, werden neu im Baum erstellte Dateien\n" " automatisch auf dem Baum ausgewiesen, der auf ihrem Projekt-Bezeichner\n" " basiert. Ein Versuch einen harten Verweis zu einer Datei im Baum zu\n" " erstellen hat nur Erfolg, wenn der Projekt-Bezeichner mit dem\n" " Projekt-Bezeichner im Baum übereinstimmt. Das »xfs-io«-Programm kann\n" " benutzt werden um eine Projekt-ID für eine beliebige Datei zu setzen,\n" " aber dies kann nur durch einen berechtigen Anwender getan werden.\n" "\n" " Ein vorheriger Einrichtungs-Baum kann mit der Option -C aus der\n" " Projekt-Quota-Kontrolle entfernt werden, die rekursiv den Baum\n" " hinabsteigt und die betroffenen Inodes von der\n" " Projekt-Quota-Kontrolle befreit.\n" "\n" " Die »-c«-Option kann benutzt werden um prüfen, ob ein Baum eingerichtet\n" " ist. Sie gibt nichts aus, wenn der Baum korrekt ist. Andernfalls gibt\n" " sie den Pfad der Inodes an, die nicht die Projekt-ID des restlichen\n" " Baumes hat oder ob die Inode-Kennzeichnung nicht gesetzt ist.\n" "\n" "Die -Option -p kann benutzt werden, um manuell den Projektpfad\n" "anzugeben, ohne dass es nötig ist, die Datei /etc/projects zu erstellen.\n" "Diese Option kann mehrmals benutzt werden, um mehrere Pfade zu erstellen.\n" "Wenn diese Option benutzt wird kann nur eine projid/Name auf der\n" "Befehlszeile angegeben werden. Beachten Sie, dass außerden /etc/projects\n" "benutzt wird, wenn es existiert.\n" "\n" "Die -Option -d erlaub es, die meisten >Tiefe>-Stufen der\n" "Verzeichnisse unterhalb der Befehlszeilenargumente hinabzusteigen.\n" "-d 0 bedeutet, dass nur die Aktionen der obersten Stufe des Projekts\n" "abgefragt werden. d -1 bedeutet keine Rekursionsbeschränkung (Vorgabe).\n" "\n" " Die Formate der Dateien /etc/projid und /etc/projects sind einfach. Sie\n" " werden auf der »xfs_quota«-Handbuchseite beschrieben.\n" "\n" #: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 #, c-format msgid "%s: cannot stat file %s\n" msgstr "%s: kann Status für »%s« nicht abfragen\n" #: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 #, c-format msgid "%s: skipping special file %s\n" msgstr "%s: Spezialdatei %s wird übersprungen\n" #: .././quota/project.c:126 #, c-format msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" msgstr "%s - Projekt-Bezeichner ist nicht gesetzt (Inode=%u, Baum=%u)\n" #: .././quota/project.c:130 #, c-format msgid "%s - project inheritance flag is not set\n" msgstr "%s - Projekt-Vererbungs-Markierung ist nicht gesetzt\n" #: .././quota/project.c:178 #, c-format msgid "%s: cannot clear project on %s: %s\n" msgstr "%s: Projekt auf %s kann nicht bereinigt werden: %s\n" #: .././quota/project.c:225 #, c-format msgid "%s: cannot set project on %s: %s\n" msgstr "%s: Projekt auf %s kann nicht gesetzt werden: %s\n" #: .././quota/project.c:240 #, c-format msgid "Checking project %s (path %s)...\n" msgstr "Projekt %s wird geprüft (Pfad %s)...\n" #: .././quota/project.c:244 #, c-format msgid "Setting up project %s (path %s)...\n" msgstr "Projekt-Pfad %s wird eingerichtet (Pfad %s)...\n" #: .././quota/project.c:248 #, c-format msgid "Clearing project %s (path %s)...\n" msgstr "Projekt-Pfad %s wird bereinigt (Pfad %s)...\n" #: .././quota/project.c:271 #, c-format msgid "" "Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%" "d).\n" msgstr "" "Es wurden %d (%s und Befehlszeile) Pfade für Projekt %s mit\n" "Rekursionstiefe %s (%d) verarbeitet.\n" #: .././quota/project.c:273 msgid "infinite" msgstr "unendlich" #: .././quota/project.c:273 msgid "limited" msgstr "beschränkt" #: .././quota/project.c:318 #, c-format msgid "projects file \"%s\" doesn't exist\n" msgstr "Projektdatei »%s« existiert nicht\n" #: .././quota/project.c:325 #, c-format msgid "" "%s: only one projid/name can be specified when using -p , %d found.\n" msgstr "" "%s: Nur ein projid/Name kann angegeben werden, wenn -p benutzt\n" "wird, %d gefunden.\n" #: .././quota/project.c:334 #, c-format msgid "%s - no such project in %s\n" msgstr "%s - kein derartiges Projekt in %s\n" #: .././quota/project.c:348 msgid "tree" msgstr "Baum" #: .././quota/project.c:350 msgid "[-c|-s|-C|-d |-p ] project ..." msgstr "[-c|-s|-C|-d |-p ] Projekt ..." #: .././quota/project.c:353 msgid "check, setup or clear project quota trees" msgstr "Projekt-Quota-Bäume prüfen, einrichten oder bereinigen " #: .././quota/quot.c:55 #, c-format msgid "" "\n" " display a summary of filesystem ownership\n" "\n" " -a -- summarise for all local XFS filesystem mount points\n" " -c -- display three columns giving file size in kilobytes, number of files\n" " of that size, and cumulative total of kilobytes in that size or\n" " smaller file. The last row is used as an overflow bucket and is the\n" " total of all files greater than 500 kilobytes.\n" " -v -- display three columns containing the number of kilobytes not\n" " accessed in the last 30, 60, and 90 days.\n" " -g -- display group summary\n" " -p -- display project summary\n" " -u -- display user summary\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" "\n" " zeigt eine Übersicht des Eigentums am Dateisystem\n" "\n" " -a -- Summe für alle lokalen XFS-Einhängepunkte bilden\n" " -c -- zeigt drei Spalten mit Dateigröße in Kilobyte, Anzahl der Dateien\n" " mit dieser Größe und zusammengezählter Gesamtzahl von Kilobytes\n" " von Dateien mit dieser Größe oder kleinerer Dateien. Die letzte\n" " Reihe wird als Überlauf benutzt und besteht aus der Gesamtheit\n" " aller Dateien mit mehr als 500 Kilobyte.\n" " -v -- zeigt drei Spalten, die die Anzahl der Kilobytes enthalten, auf\n" " die in den letzten 30, 60 und 90 Tagen nicht zugegriffen wurde.\n" " -g -- Gruppen-Zusammenfassung anzeigen\n" " -p -- Projekt-Zusammenfassung anzeigen\n" " -u -- Benutzer-Zusammenfassung anzeigen\n" " -b -- Anzahl benutzter Blöcke anzeigen\n" " -i -- Anzahl benutzter Inodes anzeigen\n" " -r -- Anzahl benutzter Echtzeit-Blöcke anzeigen\n" " -n -- Übersetzung von Bezeichnern zu Namen überspringen, nur IDs\n" " ausgeben\n" " -N -- einleitende Kopfzeilen unterdrücken\n" " -f -- Ausgabe in eine Datei umleiten\n" " Der (optionale) Benutzer/Gruppe/Projekt an entweder durch Name oder\n" " Nummer (z.B. uid/gid/projid) angegeben werden.\n" "\n" #: .././quota/quot.c:219 #, c-format msgid "%s (%s) %s:\n" msgstr "%s (%s) %s:\n" #: .././quota/quot.c:295 #, c-format msgid "%s (%s):\n" msgstr "%s (%s):\n" #: .././quota/quot.c:300 .././quota/quot.c:304 #, c-format msgid "%d\t%llu\t%llu\n" msgstr "%d\t%llu\t%llu\n" #: .././quota/quot.c:414 msgid "quot" msgstr "quot" #: .././quota/quot.c:418 msgid "[-bir] [-gpu] [-acv] [-f file]" msgstr "[-bir] [-gpu] [-acv] [-f Datei]" #: .././quota/quot.c:419 msgid "summarize filesystem ownership" msgstr "Übersicht des Eigentums am Dateisystem" #: .././quota/quota.c:32 #, c-format msgid "" "\n" " display usage and quota information\n" "\n" " -g -- display group quota information\n" " -p -- display project quota information\n" " -u -- display user quota information\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -v -- increase verbosity in reporting (also dumps zero values)\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" "\n" " zeige Benutzungs- und Quota-Information\n" "\n" " -g -- zeige Gruppen-Quota-Information\n" " -p -- zeige Projekt-Quota-Information\n" " -u -- zeige Benutzer-Quota-Information\n" " -b -- Anzahl benutzter Blöcke anzeigen\n" " -i -- Anzahl benutzter Inodes anzeigen\n" " -r -- Anzahl benutzter Echtzeit-Blöcke anzeigen\n" " -h -- in für Menschen lesbarem Format ausgeben\n" " -n -- Übersetzung von Bezeichnern zu Namen überspringen, nur IDs\n" " ausgeben\n" " -N -- einleitende Kopfzeilen unterdrücken\n" " -v -- Ausführlichkeit der Ausgabe der Meldungen erhöhen (außerdem\n" " Nullwerte ausgeben)\n" " -f -- Ausgabe in eine Datei umleiten\n" " Der (optionale) Benutzer/Gruppe/Projekt an entweder durch Name oder\n" " Nummer (z.B. uid/gid/projid) angegeben werden.\n" "\n" #: .././quota/quota.c:85 #, c-format msgid "" "Disk quotas for %s %s (%u)\n" "Filesystem%s" msgstr "" "Platten-Quotas für %s %s (%u)\n" "Dateisystem%s" #: .././quota/quota.c:90 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr " Blöcke Quota Begrenzung Warnung/Zeit" #: .././quota/quota.c:91 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr " Blöcke Quota Begrenzung Warnung/Zeit " #: .././quota/quota.c:94 #, c-format msgid " Files Quota Limit Warn/Time " msgstr " Dateien Quota Begrenzung Warnung/Zeit" #: .././quota/quota.c:95 #, c-format msgid " Files Quota Limit Warn/Time " msgstr " Dateien Quota Begrenzung Warnung/Zeit " #: .././quota/quota.c:98 #, c-format msgid "Realtime Quota Limit Warn/Time " msgstr "Echtzeit Quota Begrenzung Warnung/Zeit" #: .././quota/quota.c:99 #, c-format msgid " Realtime Quota Limit Warn/Time " msgstr " Echtzeit Quota Begrenzung Warnung/Zeit " #: .././quota/quota.c:235 #, c-format msgid "%s: cannot find user %s\n" msgstr "%s: Benutzer %s kann nicht gefunden werden\n" #: .././quota/quota.c:285 #, c-format msgid "%s: cannot find group %s\n" msgstr "%s: Gruppe %s kann nicht gefunden werden\n" #: .././quota/quota.c:342 #, c-format msgid "%s: must specify a project name/ID\n" msgstr "%s: ein Projektname/ID muss angegeben werden\n" #: .././quota/quota.c:355 #, c-format msgid "%s: cannot find project %s\n" msgstr "%s: Projekt %s kann nicht gefunden werden\n" #: .././quota/quota.c:455 msgid "quota" msgstr "Quota" #: .././quota/quota.c:456 msgid "l" msgstr "l" #: .././quota/quota.c:460 msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." msgstr "[-bir] [-gpu] [-hnNv] [-f Datei] [id|name]..." #: .././quota/quota.c:461 msgid "show usage and limits" msgstr "zeige Aufruf und Beschränkungen" #: .././quota/report.c:34 .././quota/report.c:648 msgid "dump quota information for backup utilities" msgstr "Auszug der Quota-Information für Sicherungsprogramm anzeigen" #: .././quota/report.c:36 #, c-format msgid "" "\n" " create a backup file which contains quota limits information\n" " -g -- dump out group quota limits\n" " -p -- dump out project quota limits\n" " -u -- dump out user quota limits (default)\n" " -f -- write the dump out to the specified file\n" "\n" msgstr "" "\n" " eine Sicherungsdatei erzeugen, die Quota-Begrenzung-Informationen\n" " enthält\n" " -g -- Auszug von Gruppen-Quota-Begrenzungen\n" " -p -- Auszug von Projekt-Quota-Begrenzungen\n" " -u -- Auszug von Benutzer-Quota-Begrenzungen (Standard)\n" " -f -- den Auszug in eine angegebene Datei schreiben\n" "\n" #: .././quota/report.c:48 msgid "[-bir] [-gpu] [-ahntLNU] [-f file]" msgstr "[-bir] [-gpu] [-ahntLNU] [-f Datei]" #: .././quota/report.c:49 .././quota/report.c:657 msgid "report filesystem quota information" msgstr "Quota-Information des Dateisystems ausgeben" #: .././quota/report.c:51 #, c-format msgid "" "\n" " report used space and inodes, and quota limits, for a filesystem\n" " Example:\n" " 'report -igh'\n" " (reports inode usage for all groups, in an easy-to-read format)\n" " This command is the equivalent of the traditional repquota command, which\n" " prints a summary of the disk usage and quotas for the current filesystem,\n" " or all filesystems.\n" " -a -- report for all mounted filesystems with quota enabled\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the header from the output\n" " -t -- terse output format, hides rows which are all zero\n" " -L -- lower ID bound to report on\n" " -U -- upper ID bound to report on\n" " -g -- report group usage and quota information\n" " -p -- report project usage and quota information\n" " -u -- report user usage and quota information\n" " -b -- report blocks-used information only\n" " -i -- report inodes-used information only\n" " -r -- report realtime-blocks-used information only\n" "\n" msgstr "" "\n" " benutzten Speicher und Inodes und Quota-Beschränkungen für ein\n" " Dateisystem ausgeben\n" " Beispiel:\n" " 'report -igh'\n" " (gibt Inode-Nutzung für alle Gruppen in einfach lesbarem Format aus)\n" " Dieser Befehl entspricht dem traditionellen repquota-Befehl, der eine\n" " Zusammenfassung der Plattenbelegung und Quotas für das derzeitige\n" " Dateisystem oder alle Dateisysteme ausgibt.\n" " -a -- alle eingehängten Dateisysteme mit eingeschaltetem Quota\n" " anzeigen\n" " -h -- Anzeige in einem für Menschen lesbaren Format\n" " -n -- Übersetzung von Bezeichnern zu Namen überspringen, nur IDs\n" " ausgeben\n" " -N -- die Kopfzeilen in der Ausgabe unterdrücken\n" " -t -- kurzes Ausgabeformat, Zeilen, die nur Null enthalten, unterdrücken\n" " -L -- zeigt untere an den Bericht gebundene ID\n" " -U -- zeigt obere an den Bericht gebundene ID\n" " -g -- zeigt Gruppen-Nutzung und Quota-Information\n" " -p -- zeigt Projekt-Nutzung und Quota-Information\n" " -u -- zeigt Benutzer--Nutzung und Quota-Information\n" " -b -- zeigt nur Information über benutzte Blöcke\n" " -i -- zeigt nur Information über benutzte Inodes\n" " -r -- zeigt nur Information über benutzte Echtzeit-Blöcke\n" "\n" #: .././quota/report.c:228 #, c-format msgid "%s quota on %s (%s)\n" msgstr "%s Quota auf %s (%s)\n" #: .././quota/report.c:253 .././quota/report.c:261 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Benutzt Weich Hart Warnung/Gnadenfrist" #: .././quota/report.c:254 .././quota/report.c:262 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Benutzt Weich Hart Warnung/Gnadenfrist" #: .././quota/report.c:257 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Benutzt Weich Hart Warnung/Gnadenfrist" #: .././quota/report.c:258 #, c-format msgid " Used Soft Hard Warn/ Grace " msgstr " Benutzt Weich Hart Warnung/Gnadenfrist" #: .././quota/report.c:643 msgid "dump" msgstr "Ausgabe" #: .././quota/report.c:651 msgid "report" msgstr "Bericht" #: .././quota/report.c:652 msgid "repquota" msgstr "repquota" #: .././quota/report.c:656 msgid "[-bir] [-gpu] [-ahnt] [-f file]" msgstr "[-bir] [-gpu] [-ahnt] [-f Datei]" #: .././quota/state.c:33 #, c-format msgid "" "\n" " turn filesystem quota off, both accounting and enforcement\n" "\n" " Example:\n" " 'off -uv' (switch off user quota on the current filesystem)\n" " This command is the equivalent of the traditional quotaoff command,\n" " which disables quota completely on a mounted filesystem.\n" " Note that there is no 'on' command - for XFS filesystems (with the\n" " exception of the root filesystem on IRIX) quota can only be enabled\n" " at mount time, through the use of one of the quota mount options.\n" "\n" " The state command is useful for displaying the current state. Using\n" " the -v (verbose) option with the 'off' command will display the quota\n" " state for the affected filesystem once the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " Dateisystem-Quota ausschalten, sowohl Kontenführung als auch\n" " Vollstreckung\n" "\n" " Beispiel:\n" " 'off -uv' (schaltet Benutzer-Quota auf dem derzeitigen Dateisystem aus)\n" " Dieser Befehl entspricht dem traditionellen quotaoff-Befehl, der\n" " das Quota auf eingehängten Dateisystemen gänzlich abschaltet\n" " Merken sie sich, dass es keinen »an«-Befehl gibt - für XFS-Dateisysteme\n" " (mit Ausnahme des Wurzel-Dateisystems auf IRIX) kann Quota\n" " zur Einhängezeit durch Benutzung einer der\n" " Einhänge-Quota-Optionen eingeschaltet werden\n" "\n" " Der Status-Befehl ist nützlich zur Anzeige des gegenwärtigen Status.\n" " Die Benutzung der »-v«-Option (detailliert) mit dem »off«-Befehl gibt\n" " den Quota-Status für das betroffene Dateisystem aus, bis der\n" " Arbeitsvorgang komplett ist. Der betroffene Quota-Typ ist\n" " -g (Gruppen), -p (Projekte) oder -u (Benutzer) und Standard ist\n" " Benutzer-Quota (mehrere Typen können angegeben werden).\n" "\n" #: .././quota/state.c:56 #, c-format msgid "" "\n" " query the state of quota on the current filesystem\n" "\n" " This is a verbose status command, reporting whether or not accounting\n" " and/or enforcement are enabled for a filesystem, which inodes are in\n" " use as the quota state inodes, and how many extents and blocks are\n" " presently being used to hold that information.\n" " The quota type is specified via -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " den Status der Quota auf dem aktuellen Dateisystem abfragen\n" "\n" " Dies ist ein detailreicher Status-Befehl, der ausgibt, ob Kontierung\n" " und Vollstreckung für ein Dateisystem, dessen Inodes als\n" " Quota-Status-Inode in Gebrauch sind, eingeschaltet ist oder nicht\n" " und wie viele Erweiterungen und Blöcke derzeit benutzt werden, um diese\n" " Information aufzubewahren.\n" " Der Quota-Typ ist angegeben mittels -g (Gruppen), -p (Projekte)\n" " oder -u (Benutzer) und Standard ist Benutzer-Quota (mehrere\n" " Typen können angegeben werden).\n" "\n" #: .././quota/state.c:72 #, c-format msgid "" "\n" " enable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and has quota accounting enabled, but not\n" " quota enforcement, enforcement can be enabled with this command.\n" " With the -v (verbose) option, the status of the filesystem will be\n" " reported after the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " schaltet Quota-Erzwingung auf einem Dateisystem ein\n" "\n" " Wenn ein Dateisystem eingehängt und Quota eingeschaltet ist, aber keine \n" " Quota-Erzwingung, kann die Erzwingung mit diesem Befehl eingeschaltet\n" " werden. Mit der »-v«-Option (detailliert) wird der Status des\n" " Dateisystems nach Abschluss der Arbeitsgangs angezeigt.\n" " Der betroffene Quota-Typ ist -g (Gruppen), -p (Projekte) oder\n" " -u (Benutzer) und Standard ist Benutzer-Quota (mehrere Typen können\n" " angegeben werden).\n" #: .././quota/state.c:88 #, c-format msgid "" "\n" " disable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and is currently enforcing quota, this\n" " provides a mechanism to switch off the enforcement, but continue to\n" " perform used space (and used inodes) accounting.\n" " The affected quota type is -g (groups), -p (projects) or -u (users).\n" "\n" msgstr "" "\n" " schaltet Quota-Erzwingung auf einem Dateisystem aus\n" "\n" " Wenn ein Dateisystem eingehängt ist und derzeit Quota erzwingt,\n" " stellt dies einen Mechanismus zur Verfügung um die Erzwingung\n" " auszuschalten aber mit der Kontierung von benutztem Speicher (und\n" " benutzter Inodes) fortzufahren.\n" " Der betroffene Quota-Typ ist -g (Gruppen), -p (Projekte) oder\n" " -u (Benutzer).\n" "\n" #: .././quota/state.c:102 #, c-format msgid "" "\n" " remove any space being used by the quota subsystem\n" "\n" " Once quota has been switched 'off' on a filesystem, the space that\n" " was allocated to holding quota metadata can be freed via this command.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " durch das Quota-Untersystem benutzten Speicher freigeben\n" "\n" " Wenn das Quota auf einem Dateisystem ausgeschaltet wurde, kann der\n" " Speicher, der für die Quota-Metadaten zugeteilt wurde mit diesem Befehl\n" " freigegeben werden. Der betroffene Quota-Typ ist -g (Gruppen),\n" " -p (Projekte) oder -u (Benutzer) und Standard ist Benutzer-Quotaierung\n" " (mehrere Typen können angegeben werden)..\n" "\n" #: .././quota/state.c:121 #, c-format msgid "%s quota state on %s (%s)\n" msgstr "%s Quota-Status auf %s (%s)\n" #: .././quota/state.c:123 #, c-format msgid " Accounting: %s\n" msgstr "Kontierung: %s\n" #: .././quota/state.c:123 .././quota/state.c:124 msgid "ON" msgstr "AN" #: .././quota/state.c:123 .././quota/state.c:124 msgid "OFF" msgstr "AUS" #: .././quota/state.c:124 #, c-format msgid " Enforcement: %s\n" msgstr " Vollstreckung: %s\n" #: .././quota/state.c:125 #, c-format msgid " Inode: #%llu (%llu blocks, %lu extents)\n" msgstr " Inode: #%llu (%llu Blöcke, %lu Erweiterungen)\n" #: .././quota/state.c:137 #, c-format msgid "%s grace time: %s\n" msgstr "%s Gnadenfrist: %s\n" #: .././quota/state.c:154 #, c-format msgid "%s quota are not enabled on %s\n" msgstr "%s Quota ist auf %s nicht eingeschaltet\n" #: .././quota/state.c:524 .././quota/state.c:540 .././quota/state.c:548 #: .././quota/state.c:556 msgid "[-gpu] [-v]" msgstr "[-gpu] [-v]" #: .././quota/state.c:525 msgid "permanently switch quota off for a path" msgstr "Quota für den Pfad dauerhaft ausschalten" #: .././quota/state.c:528 msgid "state" msgstr "Status" #: .././quota/state.c:532 msgid "[-gpu] [-a] [-v] [-f file]" msgstr "[-gpu] [-a] [-v] [-f Datei]" #: .././quota/state.c:533 msgid "get overall quota state information" msgstr "umfassende Quota-Information erhalten" #: .././quota/state.c:536 msgid "enable" msgstr "einschalten" #: .././quota/state.c:541 msgid "enable quota enforcement" msgstr "Quota-Erzwingung einschalten" #: .././quota/state.c:544 msgid "disable" msgstr "ausschalten" #: .././quota/state.c:549 msgid "disable quota enforcement" msgstr "Quota-Erzwingung ausschalten" #: .././quota/state.c:552 msgid "remove" msgstr "entfernen" #: .././quota/state.c:557 msgid "remove quota extents from a filesystem" msgstr "Quota-Erweiterungen aus einem Dateisystem entfernen" #: .././quota/util.c:59 #, c-format msgid "[-none-]" msgstr "[-keins-]" #: .././quota/util.c:59 #, c-format msgid "[--none--]" msgstr "[--keins--]" #: .././quota/util.c:62 #, c-format msgid "[------]" msgstr "[------]" #: .././quota/util.c:62 #, c-format msgid "[--------]" msgstr "[--------]" #: .././quota/util.c:66 .././quota/util.c:69 msgid "day" msgstr "Tag" #: .././quota/util.c:66 .././quota/util.c:69 msgid "days" msgstr "Tage" #: .././quota/util.c:194 msgid "Blocks" msgstr "Blöcke" #: .././quota/util.c:194 msgid "Inodes" msgstr "Inodes" #: .././quota/util.c:194 msgid "Realtime Blocks" msgstr "Echtzeit-Blöcke" #: .././quota/util.c:209 msgid "User" msgstr "Benutzer" #: .././quota/util.c:209 msgid "Group" msgstr "Gruppe" #: .././quota/util.c:209 msgid "Project" msgstr "Projekt" #: .././quota/util.c:417 #, c-format msgid "%s: open on %s failed: %s\n" msgstr "%s: Öffnen auf %s fehlgeschlagen: %s\n" #: .././quota/util.c:423 #, c-format msgid "%s: fdopen on %s failed: %s\n" msgstr "%s: fdopen auf %s fehlgeschlagen: %s\n" #: .././repair/incore_ino.c:196 .././repair/incore_ino.c:205 #: .././repair/incore_ino.c:222 .././repair/incore_ino.c:231 msgid "could not allocate expanded nlink array\n" msgstr "erweiterte nlink-Matrix kann nicht alloziert werden.\n" #: .././repair/incore_ino.c:268 msgid "inode map malloc failed\n" msgstr "Inode map malloc fehlgeschlagen\n" #: .././repair/incore_ino.c:298 msgid "could not allocate nlink array\n" msgstr "nlink-Matrix kann nicht alloziert werden.\n" #: .././repair/incore_ino.c:390 msgid "add_aginode_uncertain - duplicate inode range\n" msgstr "add_aginode_uncertain - doppelter Inode-Bereich\n" #: .././repair/incore_ino.c:488 msgid "add_inode - duplicate inode range\n" msgstr "add_inode - doppelter Inode-Bereich\n" #: .././repair/incore_ino.c:579 #, c-format msgid "good inode list is --\n" msgstr "gute Inode-Liste ist --\n" #: .././repair/incore_ino.c:582 #, c-format msgid "uncertain inode list is --\n" msgstr "unsichere Inode-Liste ist --\n" #: .././repair/incore_ino.c:587 #, c-format msgid "agno %d -- no inodes\n" msgstr "agno %d -- keine Inodes\n" #: .././repair/incore_ino.c:591 #, c-format msgid "agno %d\n" msgstr "agno %d\n" #: .././repair/incore_ino.c:595 #, c-format msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" msgstr "\tptr = %lx, Start = 0x%x, frei = 0x%llx, bestätigt = 0x%llx\n" #: .././repair/incore_ino.c:646 msgid "couldn't malloc parent list table\n" msgstr "malloc von Elternlistentabelle konnte nicht durchgeführt werden\n" #: .././repair/incore_ino.c:657 .././repair/incore_ino.c:703 msgid "couldn't memalign pentries table\n" msgstr "memalign von pentries-Tabelle konnte nicht durchgeführt werden\n" #: .././repair/incore_ino.c:761 .././repair/incore_ino.c:767 msgid "could not malloc inode extra data\n" msgstr "malloc von Inode-Extradaten konnte nicht durchgeführt werden\n" #: .././repair/incore_ino.c:815 msgid "couldn't malloc inode tree descriptor table\n" msgstr "" "malloc von Inode-Datei-Deskriptor-Tabelle konnte nicht durchgeführt werden\n" #: .././repair/incore_ino.c:819 msgid "couldn't malloc uncertain ino tree descriptor table\n" msgstr "malloc von unbestimmter ino-Baum-Deskriptor-Tabelle konnte nicht\n" "durchgeführt werden\n" #: .././repair/incore_ino.c:824 msgid "couldn't malloc inode tree descriptor\n" msgstr "malloc von Baum-Deskriptor konnte nicht durchgeführt werden\n" #: .././repair/incore_ino.c:828 msgid "couldn't malloc uncertain ino tree descriptor\n" msgstr "" "malloc von unbestimmtem ino-Baum-Deskriptor konnte nicht durchgeführt\n" "werden\n" #: .././repair/incore_ino.c:839 msgid "couldn't malloc uncertain inode cache area\n" msgstr "" "malloc von unbestimmtem Inode-Zwischenspeicherbereich konnte nicht\n" "durchgeführt werden\n" #: .././repair/phase1.c:28 msgid "Sorry, could not find valid secondary superblock\n" msgstr "" "Entschuldigung, gültiger zweiter Superblock kann nicht gefunden werden\n" #: .././repair/phase1.c:29 msgid "Exiting now.\n" msgstr "Wird beendet.\n" #: .././repair/phase1.c:40 #, c-format msgid "could not allocate ag header buffer (%d bytes)\n" msgstr "ag-Kopf-Puffer (%d Bytes) kann nicht alloziert werden\n" #: .././repair/phase1.c:58 msgid "Phase 1 - find and verify superblock...\n" msgstr "Phase 1 - Superblock finden und überprüfen...\n" #: .././repair/phase1.c:74 msgid "error reading primary superblock\n" msgstr "Fehler beim Lesen des primären Superblocks\n" #: .././repair/phase1.c:80 #, c-format msgid "bad primary superblock - %s !!!\n" msgstr "falscher primärer Superblock - %s !!!\n" #: .././repair/phase1.c:87 #, c-format msgid "couldn't verify primary superblock - %s !!!\n" msgstr "primärer Superblock kann nicht überprüft werden - %s !!!\n" #: .././repair/phase1.c:105 msgid "superblock has a features2 mismatch, correcting\n" msgstr "" "Superblock hat eine fehlende features2-Übereinstimmung, wird berichtigt\n" #: .././repair/phase1.c:121 #, c-format msgid "Enabling lazy-counters\n" msgstr "Schalte lazy-counters ein\n" #: .././repair/phase1.c:125 #, c-format msgid "Disabling lazy-counters\n" msgstr "lazy-counters werden ausgeschaltet\n" #: .././repair/phase1.c:128 #, c-format msgid "Lazy-counters are already %s\n" msgstr "Lazy-counters sind bereits %s\n" #: .././repair/phase1.c:129 msgid "enabled" msgstr "eingeschaltet" #: .././repair/phase1.c:129 msgid "disabled" msgstr "ausgeschaltet" #: .././repair/phase1.c:136 msgid "writing modified primary superblock\n" msgstr "Schreiben verändert primären Superblock\n" #: .././repair/phase1.c:139 msgid "would write modified primary superblock\n" msgstr "Schreiben könnte primären Superblock verändern\n" #: .././repair/phase4.c:125 .././repair/phase5.c:1439 .././repair/phase3.c:160 #: .././repair/phase6.c:3595 #, c-format msgid " - agno = %d\n" msgstr " - agno = %d\n" #: .././repair/phase4.c:205 msgid "Phase 4 - check for duplicate blocks...\n" msgstr "Phase 4 - auf doppelte Blöcke überprüfen...\n" #: .././repair/phase4.c:206 msgid " - setting up duplicate extent list...\n" msgstr " - Liste mit doppeltem Ausmaß wird eingerichtet...\n" #: .././repair/phase4.c:220 msgid "root inode would be lost\n" msgstr "Wurzel-Inode könnte verloren worden sein\n" #: .././repair/phase4.c:222 msgid "root inode lost\n" msgstr "Wurzel-Inode wurde verloren\n" #: .././repair/phase4.c:256 #, c-format msgid "unknown block state, ag %d, block %d\n" msgstr "unbekannter Block-Status, ag %d, Block %d\n" #: .././repair/phase4.c:314 #, c-format msgid "unknown rt extent state, extent %llu\n" msgstr "unbekannter rt-Ausmaß-Status, Ausmaß %llu\n" #: .././repair/phase4.c:375 msgid " - check for inodes claiming duplicate blocks...\n" msgstr " - es wird geprüft ob Inodes Blocks doppelt beanspruchen...\n" #: .././repair/avl64.c:1032 .././repair/avl.c:1011 #, c-format msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" msgstr "avl_insert: Warnung! Doppelter Bereich [%llu,%llu]\n" #: .././repair/avl64.c:1227 .././repair/avl.c:1206 #, c-format msgid "Command [fpdir] : " msgstr "Befehl [fpdir] : " #: .././repair/avl64.c:1236 .././repair/avl.c:1215 #, c-format msgid "end of range ? " msgstr "Ende des Bereichs? " #: .././repair/avl64.c:1247 .././repair/avl.c:1226 #, c-format msgid "Cannot find %d\n" msgstr "%d kann nicht gefunden werden\n" #: .././repair/avl64.c:1260 .././repair/avl.c:1239 #, c-format msgid "size of range ? " msgstr "Größe des Bereichs? " #: .././repair/avl64.c:1271 .././repair/avl.c:1250 #, c-format msgid "End of range ? " msgstr "Ende des Bereichs? " #: .././repair/avl64.c:1275 .././repair/avl.c:1254 #, c-format msgid "checklen 0/1 ? " msgstr "checklen 0/1? " #: .././repair/avl64.c:1282 .././repair/avl.c:1261 #, c-format msgid "Found something\n" msgstr "Etwas gefunden\n" #: .././repair/progress.c:16 msgid "inodes" msgstr "Inodes" #: .././repair/progress.c:20 msgid "directories" msgstr "Verzeichnisse" #: .././repair/progress.c:22 msgid "allocation groups" msgstr "Allokations-Gruppen" #: .././repair/progress.c:24 msgid "AGI unlinked buckets" msgstr "AGI gelöste Verweisbehälter" #: .././repair/progress.c:28 msgid "realtime extents" msgstr "Echtzeitbereiche" #: .././repair/progress.c:30 msgid "unlinked lists" msgstr "unverknüpfte Listen" #: .././repair/progress.c:37 #, c-format msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" msgstr " - %02d:%02d:%02d: %s - %llu von %llu %s erledigt\n" #: .././repair/progress.c:39 #, c-format msgid " - %02d:%02d:%02d: %s - %llu %s done\n" msgstr " - %02d:%02d:%02d: %s - %llu %s erledigt\n" #: .././repair/progress.c:51 msgid "scanning filesystem freespace" msgstr "freier Speicher des Dateisystems wird gescannt" #: .././repair/progress.c:53 msgid "scanning agi unlinked lists" msgstr "unverknüpfte agi-Listen werden gescannt" #: .././repair/progress.c:55 msgid "check uncertain AG inodes" msgstr "einige unklare AG-Inodes werden geprüft" #: .././repair/progress.c:57 msgid "process known inodes and inode discovery" msgstr "bekannte Inodes werden abgearbeitet und Inodes entdeckt" #: .././repair/progress.c:59 msgid "process newly discovered inodes" msgstr "neu entdeckte Inodes werden abgearbeitet" #: .././repair/progress.c:61 msgid "setting up duplicate extent list" msgstr "Liste mit doppelten Bereichen wird eingerichtet" #: .././repair/progress.c:63 msgid "initialize realtime bitmap" msgstr "Echtzeit-Bitmap wird initialisiert" #: .././repair/progress.c:65 msgid "reset realtime bitmaps" msgstr "Echtzeit-Bitmap wird zurückgesetzt" #: .././repair/progress.c:67 msgid "check for inodes claiming duplicate blocks" msgstr "es wird geprüft, ob Inodes doppelte Blöcke beanspruchen" #: .././repair/progress.c:69 msgid "rebuild AG headers and trees" msgstr "AG-Köpfe und Bäume werden neu erstellt" #: .././repair/progress.c:71 msgid "traversing filesystem" msgstr "Dateisystem wird durchquert" #: .././repair/progress.c:73 msgid "traversing all unattached subtrees" msgstr "alle unabhängigen Unterbäume werden durchquert" #: .././repair/progress.c:75 msgid "moving disconnected inodes to lost+found" msgstr "nicht verbundene Inodes werden nach lost+found verschoben" #: .././repair/progress.c:77 msgid "verify and correct link counts" msgstr "Verweisanzahl wird geprüft und berichtigt" #: .././repair/progress.c:79 msgid "verify link counts" msgstr "Verweisanzahl wird geprüft" #: .././repair/progress.c:118 msgid "cannot malloc pointer to done vector\n" msgstr "malloc von Zeiger auf erledigten Vektor nicht möglich\n" #: .././repair/progress.c:134 msgid "unable to create progress report thread\n" msgstr "außerstande einen Fortschritts-Bericht-Thread zu erzeugen\n" #: .././repair/progress.c:173 msgid "progress_rpt: cannot malloc progress msg buffer\n" msgstr "progress_rpt: malloc Fortschritts-msg-Puffer\n" #: .././repair/progress.c:187 msgid "progress_rpt: cannot create timer\n" msgstr "progress_rpt: Zeitnehmer kann nicht erzeugt werden\n" #: .././repair/progress.c:190 msgid "progress_rpt: cannot set timer\n" msgstr "progress_rpt: Zeitnehmer kann nicht gesetzt werden\n" #: .././repair/progress.c:214 msgid "progress_rpt: cannot lock progress mutex\n" msgstr "progress_rpt: mutex-Fortschritt kann nicht gesperrt werden\n" #: .././repair/progress.c:251 .././repair/progress.c:354 #, c-format msgid "%s" msgstr "%s" #: .././repair/progress.c:259 #, c-format msgid "" "\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" msgstr "" "\t- %02d:%02d:%02d: Phase %d: verstrichene Zeit %s - %d abgearbeitet %s\n" "pro Minute\n" #: .././repair/progress.c:264 #, c-format msgid "" "\t- %02d:%02d:%02d: Phase %d: %llu%% done - estimated remaining time %s\n" msgstr "" "\t- %02d:%02d:%02d: Phase %d: %llu%% erledigt - geschätzte verbleibende\n" "Zeit %s\n" #: .././repair/progress.c:272 msgid "progress_rpt: error unlock msg mutex\n" msgstr "progress_rpt: Fehler beim Entsperren von msg mutex\n" #: .././repair/progress.c:278 msgid "cannot delete timer\n" msgstr "Zeitnehmer kann nicht gelöscht werden\n" #: .././repair/progress.c:292 msgid "set_progress_msg: cannot lock progress mutex\n" msgstr "set_progress_msg: Mutex-Fortschritt kann nicht gesperrt werden\n" #: .././repair/progress.c:302 msgid "set_progress_msg: cannot unlock progress mutex\n" msgstr "set_progress_msg: Mutex-Fortschritt kann nicht entsperrt werden\n" #: .././repair/progress.c:322 msgid "print_final_rpt: cannot lock progress mutex\n" msgstr "print_final_rpt: Mutex-Fortschritt kann nicht gesperrt werden\n" #: .././repair/progress.c:358 msgid "print_final_rpt: cannot unlock progress mutex\n" msgstr "print_final_rpt: Mutex-Fortschritt kann nicht entsperrt werden\n" #: .././repair/progress.c:407 #, c-format msgid "%02d:%02d:%02d" msgstr "%02d:%02d:%02d" #: .././repair/progress.c:429 #, c-format msgid "%d week" msgstr "%d Woche" #: .././repair/progress.c:439 #, c-format msgid "%d day" msgstr "%d Tag" #: .././repair/progress.c:446 .././repair/progress.c:463 #: .././repair/progress.c:481 .././repair/progress.c:491 msgid ", " msgstr ", " #: .././repair/progress.c:455 #, c-format msgid "%d hour" msgstr "%d Stunde" #: .././repair/progress.c:473 #, c-format msgid "%d minute" msgstr "%d Minute" #: .././repair/progress.c:488 #, c-format msgid "%d second" msgstr "%d Sekunde" #: .././repair/progress.c:509 #, c-format msgid "" "\n" " XFS_REPAIR Summary %s\n" msgstr "" "\n" " XFS_REPAIR Zusammenfassung %s\n" #: .././repair/progress.c:511 msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" msgstr "Phase\t\tStart\t\tEnde\t\tDauer\n" #: .././repair/progress.c:516 .././repair/progress.c:519 #, c-format msgid "Phase %d:\tSkipped\n" msgstr "Phase %d:\tÜbersprungen\n" #: .././repair/progress.c:523 #, c-format msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" msgstr "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" #: .././repair/progress.c:529 #, c-format msgid "" "\n" "Total run time: %s\n" msgstr "" "\n" "Gesamte Laufzeit: %s\n" #: .././repair/sb.c:100 msgid "" "\n" "attempting to find secondary superblock...\n" msgstr "" "\n" "es wird versucht einen zweiten Superblock zu finden...\n" #: .././repair/sb.c:105 msgid "error finding secondary superblock -- failed to memalign buffer\n" msgstr "" "Fehler beim Finden eines zweiten Superblocks -- memalign des Puffers\n" "fehlgeschlagen\n" #: .././repair/sb.c:142 msgid "found candidate secondary superblock...\n" msgstr "Kandidat für zweiten Superblock gefunden...\n" #: .././repair/sb.c:154 msgid "verified secondary superblock...\n" msgstr "zweiter Superblock geprüft...\n" #: .././repair/sb.c:159 msgid "unable to verify superblock, continuing...\n" msgstr "außerstande Superblock zu prüfen, wird fortgesetzt...\n" #: .././repair/sb.c:457 msgid "failed to memalign superblock buffer\n" msgstr "memalign des Superblock-Puffers fehlgeschlagen\n" #: .././repair/sb.c:464 msgid "couldn't seek to offset 0 in filesystem\n" msgstr "Versatz 0 im Dateisystem kann nicht positioniert werden\n" #: .././repair/sb.c:472 msgid "primary superblock write failed!\n" msgstr "Schreiben der primären Superblock fehlgeschlagen!\n" #: .././repair/sb.c:490 #, c-format msgid "error reading superblock %u -- failed to memalign buffer\n" msgstr "" "Fehler beim Lesen des Superblocks %u - memalign des Puffers\n" "fehlgeschlagen\n" #: .././repair/sb.c:500 #, c-format msgid "error reading superblock %u -- seek to offset %lld failed\n" msgstr "" "Fehler beim Lesen des Superblocks %u - positionieren des Versatzes %lld\n" "fehlgeschlagen\n" #: .././repair/sb.c:508 #, c-format msgid "superblock read failed, offset %lld, size %d, ag %u, rval %d\n" msgstr "" "Lesen des Superblocks fehlgeschlagen, Versatz %lld, Größe %d, ag %u,\n" "rval %d\n" #: .././repair/sb.c:556 msgid "couldn't malloc geometry structure\n" msgstr "malloc konnte nicht für Geometriestruktur erfolgen\n" #: .././repair/sb.c:701 msgid "calloc failed in verify_set_primary_sb\n" msgstr "calloc fehlgeschlagen in verify_set_primary_sb\n" #: .././repair/sb.c:772 msgid "" "Only two AGs detected and they do not match - cannot validate filesystem " "geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" "Nur zwei AGs wurden entdeckt und diese passen nicht - die Geometrie des\n" "Dateisystems konnte nicht bestätigt werden.\n" #: .././repair/sb.c:788 msgid "" "Only one AG detected - cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" "Nur ein AGs wurde entdeckt - die Geometrie des Dateisystems konnte nicht\n" "bestätigt werden.\n" "Benutzen Sie die force_geometry-Option -o um fortzufahren\n" #: .././repair/sb.c:803 msgid "Not enough matching superblocks - cannot proceed.\n" msgstr "" "Nicht genug passende Superblöcke - es kann nicht fortgefahren werden.\n" #: .././repair/sb.c:818 msgid "could not read superblock\n" msgstr "Superblock kann nicht gelesen werden\n" #: .././repair/phase5.c:235 msgid "could not set up btree block array\n" msgstr "btree-Block-Matrix kann nicht eingerichtet werden\n" #: .././repair/phase5.c:247 msgid "error - not enough free space in filesystem\n" msgstr "Fehler - nicht genug freier Platz im Dateisystem\n" #: .././repair/phase5.c:463 #, c-format msgid "can't rebuild fs trees -- not enough free space on ag %u\n" msgstr "" "fs-Bäume können nicht erneut gebildet werden -- nicht genug freier Platz\n" "auf ag %u\n" #: .././repair/phase5.c:487 #, c-format msgid "ag %u - not enough free space to build freespace btrees\n" msgstr "ag %u - nicht genug freier Platz im Freiplatz-btrees zu bilden\n" #: .././repair/phase5.c:522 #, c-format msgid "not enough free blocks left to describe all free blocks in AG %u\n" msgstr "" "nicht genügend freie Blöcke vorhandene um alle freien Blöcke in AG %u\n" "zu beschreiben\n" #: .././repair/phase5.c:1335 #, c-format msgid "lost %d blocks in ag %u\n" msgstr "%d Blöcke in ag %u verloren\n" #: .././repair/phase5.c:1338 #, c-format msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" msgstr "" "man dachte, %d Blöcke würden in ag %u verloren gehen, aktuell verloren %d\n" #: .././repair/phase5.c:1385 .././repair/xfs_repair.c:810 msgid "couldn't get superblock\n" msgstr "Superblock kann nicht bekommen werden\n" #: .././repair/phase5.c:1462 #, c-format msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" msgstr "" "außerstande AG %u erneut zu bilden. Nicht genug freier Platz in on-disk AG.\n" #: .././repair/phase5.c:1502 #, c-format msgid "unable to rebuild AG %u. No free space.\n" msgstr "außerstande AG %u erneut zu bilden. Nicht genug Platz.\n" #: .././repair/phase5.c:1529 #, c-format msgid "lost %d blocks in agno %d, sorry.\n" msgstr "%d Blöcke in agno %d verloren, Entschuldigung.\n" #: .././repair/phase5.c:1598 msgid "Phase 5 - rebuild AG headers and trees...\n" msgstr "Phase 5 - AG-Köpfe und Bäume werden erneut gebildet...\n" #: .././repair/phase5.c:1628 msgid "cannot alloc sb_icount_ag buffers\n" msgstr "sb_icount_ag-Puffer können nicht alloziert werden\n" #: .././repair/phase5.c:1632 msgid "cannot alloc sb_ifree_ag buffers\n" msgstr "sb_ifree_ag-Puffer können nicht alloziert werden\n" #: .././repair/phase5.c:1636 msgid "cannot alloc sb_fdblocks_ag buffers\n" msgstr "sb_fdblocks_ag-Puffer können nicht alloziert werden\n" #: .././repair/phase5.c:1655 msgid " - generate realtime summary info and bitmap...\n" msgstr " - Echtzeit-Zusammenfassung und Bitmap wird erzeugt...\n" #: .././repair/phase5.c:1661 msgid " - reset superblock...\n" msgstr " - Superblock wird zurückgesetzt...\n" #: .././repair/versions.c:73 #, c-format msgid "bogus quota flags 0x%x set in superblock" msgstr "fingierte Quota-Markierungen 0x%x im Superblock gesetzt" #: .././repair/versions.c:86 msgid ", bogus flags will be cleared\n" msgstr ", fingierte Markierungen werden bereinigt\n" #: .././repair/versions.c:88 msgid ", bogus flags would be cleared\n" msgstr ", fingierte Markierungen könnten bereinigt werden\n" #: .././repair/versions.c:141 msgid "This filesystem has uninitialized extent flags.\n" msgstr "Dieses Dateisystem hat nicht initialisierte Ausmaß-Markierungen\n" #: .././repair/versions.c:149 msgid "This filesystem is marked shared.\n" msgstr "Dieses Dateisystem ist als gemeinsam nutzbar markiert.\n" #: .././repair/versions.c:155 msgid "" "This filesystem uses feature(s) not yet supported in this release.\n" "Please run a more recent version of xfs_repair.\n" msgstr "" "Dieses Dateisystem benutzt Merkmale, die von dieser Veröffentlichung\n" "noch nicht unterstützt werden.\n" "Bitte führen Sie eine aktuellere Version von xfs_repair aus.\n" #: .././repair/versions.c:161 #, c-format msgid "WARNING: unknown superblock version %d\n" msgstr "WARNUNG: unbekannte Superblock-Version %d\n" #: .././repair/versions.c:164 msgid "This filesystem contains features not understood by this program.\n" msgstr "" "Dieses Dateisystem enthält Merkmale, die von diesem Programm nicht\n" "verstanden werden.\n" #: .././repair/versions.c:172 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twill be downgraded. This may cause loss of filesystem meta-data\n" msgstr "" "WARNUNG: Sie haben superblock-feature-bits-allowed verboten, aber dieser\n" "\tSuperblock hat Funktions-Bits. Der Superblock wird herabgestuft. Dies\n" "\tkann den Verlust von Dateisystem-Metadaten zur Folge haben\n" #: .././repair/versions.c:177 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twould be downgraded. This might cause loss of filesystem\n" "\tmeta-data.\n" msgstr "" "WARNUNG: Sie haben superblock-feature-bits-allowed verboten, aber dieser\n" "\tSuperblock hat Funktions-Bits. Der Superblock wird herabgestuft. Dies\n" "\tkönnte den Verlust von Dateisystem-Metadaten zur Folge haben\n" #: .././repair/versions.c:191 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attributes will be removed.\n" msgstr "" "WARNUNG: Sie haben Attribute verboten, aber dieses Dateisystem hat\n" "\tAttribute. Das Dateisystem wird herabgestuft und alle Attribute werden\n" "\tentfernt\n" #: .././repair/versions.c:196 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attributes would be removed.\n" msgstr "" "WARNUNG: Sie haben Attribute verboten, aber dieses Dateisystem hat\n" "\tAttribute. Das Dateisystem könnte herabgestuft und alle Attribute\n" "\tentfernt werden\n" #: .././repair/versions.c:209 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attr2 attributes will be removed.\n" msgstr "" "WARNUNG: Sie haben attr2-Attribute verboten, aber dieses Dateisystem hat\n" "\tAttribute. Das Dateisystem wird herabgestuft und alle attr2-Attribute\n" "\twerden entfernt\n" #: .././repair/versions.c:214 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attr2 attributes would be removed.\n" msgstr "" "WARNUNG: Sie haben attr2-Attribute verboten, aber dieses Dateisystem hat\n" "\tAttribute. Das Dateisystem wird herabgestuft und alle attr2-Attribute\n" "\twerden entfernt\n" #: .././repair/versions.c:227 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem will be downgraded and\n" "\tall version 2 inodes will be converted to version 1 inodes.\n" "\tThis may cause some hard links to files to be destroyed\n" msgstr "" "WARNUNG: Sie haben Version-2-Inodes verboten, aber dieses Dateisystem hat\n" "\tVersion-2-Inodes. Das Dateisystem wird herabgestuft und alle\n" "\tVersion-2-Inodes werden in Version-1-Inodes umgewandelt. Dies kann zur\n" "\tFolge haben, dass einige Hardlinks auf Dateien zerstört werden.\n" #: .././repair/versions.c:233 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem would be downgraded and\n" "\tall version 2 inodes would be converted to version 1 inodes.\n" "\tThis might cause some hard links to files to be destroyed\n" msgstr "" "WARNUNG: Sie haben Version-2-Inodes verboten, aber dieses Dateisystem hat\n" "\tVersion-2-Inodes. Das Dateisystem könnte herabgestuft und alle\n" "\tVersion-2-Inodes in Version-1-Inodes umgewandelt erden. Dies könnte zur\n" "\tFolge haben, dass einige Hardlinks auf Dateien zerstört werden.\n" #: .././repair/versions.c:247 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem will be downgraded and\n" "\tall quota information will be removed.\n" msgstr "" "WARNUNG: Sie haben Quota verboten, aber dieses Dateisystem hat\n" "\tQuota. Das Dateisystem wird herabgestuft und jegliche Quota-\n" "\tInformation wird entfernt.\n" #: .././repair/versions.c:252 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem would be downgraded and\n" "\tall quota information would be removed.\n" msgstr "" "WARNUNG: Sie haben Quota verboten, aber dieses Dateisystem hat\n" "\tQuota. Das Dateisystem könnte herabgestuft und jegliche Quota-\n" "\tInformation entfernt werden.\n" #: .././repair/versions.c:276 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem will be downgraded.\n" "\tThis will permanently degrade the performance of this filesystem.\n" msgstr "" "WARNUNG: Sie haben angepasste Inodes verboten, aber dieses Dateisystem\n" "\that angepasste Inodes. Das Dateisystem wird herabgestuft.\n" "\tDies wird die Leistungsfähigkeit des Dateisystems dauerhaft mindern.\n" #: .././repair/versions.c:281 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem would be downgraded.\n" "\tThis would permanently degrade the performance of this filesystem.\n" msgstr "" "WARNUNG: Sie haben angepasste Inodes verboten, aber dieses Dateisystem\n" "\that angepasste Inodes. Das Dateisystem könnte herabgestuft werden.\n" "\tDies könnte die Leistungsfähigkeit des Dateisystems dauerhaft mindern\n" #: .././repair/threads.c:90 #, c-format msgid "cannot create worker threads, error = [%d] %s\n" msgstr "Arbeiter-Threads können nicht erzeugt werden, Fehler = [%d] %s\n" #: .././repair/threads.c:108 #, c-format msgid "cannot allocate worker item, error = [%d] %s\n" msgstr "Arbeiter-Gegenstand kann nicht alloziert werden, Fehler = [%d] %s\n" #: .././repair/bmap.c:43 #, c-format msgid "realloc failed in blkent_append (%u bytes)\n" msgstr "»realloc« in »blkent_append« fehlgeschlagen (%u Bytes)\n" #: .././repair/bmap.c:65 #, c-format msgid "malloc failed in blkent_new (%u bytes)\n" msgstr "»malloc« in »blkent_append« fehlgeschlagen (%u Bytes)\n" #: .././repair/bmap.c:91 #, c-format msgid "malloc failed in blkent_prepend (%u bytes)\n" msgstr "»malloc« in »blkent_prepend« fehlgeschlagen (%u Bytes)\n" #: .././repair/bmap.c:118 #, c-format msgid "malloc failed in blkmap_alloc (%u bytes)\n" msgstr "»malloc« in »blkent_alloc« fehlgeschlagen (%u Bytes)\n" #: .././repair/bmap.c:216 #, c-format msgid "blkmap_getn realloc failed (%u bytes)\n" msgstr "»blkmap_getn realloc« fehlgeschlagen (%u Bytes)\n" #: .././repair/bmap.c:252 #, c-format msgid "realloc failed in blkmap_grow (%u bytes)\n" msgstr "»realloc« in »blkent_grow« fehlgeschlagen (%u Bytes)\n" #: .././repair/phase2.c:65 #, c-format msgid "" "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" msgstr "" "zero_log: Kopf/Fuß des Protokolls kann nicht gefunden werden\n" "(xlog_find_tail=%d), wird trotzdem auf Null gesetzt\n" #: .././repair/phase2.c:70 #, c-format msgid "zero_log: head block %lld tail block %lld\n" msgstr "zero_log: Kopfblock %lld Fußblock %lld\n" #: .././repair/phase2.c:76 msgid "" "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n" msgstr "" "ALARM: Das Dateisystem hat wertvolle Metadaten-Änderungen in einem\n" "Protokoll, das zerstört wird, weil die -L-Option benutzt wird.\n" #: .././repair/phase2.c:80 msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" "FEHLER: Das Dateisystem hat wertvolle Metadaten-Änderungen in einem\n" "Protokoll, das wiederholt werden sollte. Hängen Sie das Dateisystem ein,\n" "um das Protokoll zu wiederholen und hängen Sie es wieder aus um\n" "xfs_repair erneut auszuführen. Wenn Sie außer Stande sind, das\n" "Dateisystem einzuhängen, benutzen Sie die -L-Option um das Protokoll zu\n" "zerstören und versuchen Sie eine Reparatur.\n" "Beachten Sie, dass die Zerstörung des Protokolls Schaden verursachen\n" "kann -- bitte versuchen sie das Dateisystem einzuhängen ehe Sie dies tun.\n" #: .././repair/phase2.c:122 msgid "" "This filesystem has an external log. Specify log device with the -l " "option.\n" msgstr "" "Das Dateisystem hat ein externes Protokoll. Geben Sie das Protokoll-Gerät\n" "mit der Option -l an.\n" #: .././repair/phase2.c:125 #, c-format msgid "Phase 2 - using external log on %s\n" msgstr "Phase 2 - ein externes Protokoll auf %s benutzen\n" #: .././repair/phase2.c:127 msgid "Phase 2 - using internal log\n" msgstr "Phase 2 - ein internes Protokoll benutzen\n" #: .././repair/phase2.c:131 msgid " - zero log...\n" msgstr " - Null-Protokoll...\n" #: .././repair/phase2.c:135 msgid " - scan filesystem freespace and inode maps...\n" msgstr "" " - freier Speicher und Inode-Karten des Dateisystems werden\n" "gescannt...\n" #: .././repair/phase2.c:162 msgid "root inode chunk not found\n" msgstr "Wurzel-Inode-Stück nicht gefunden\n" #: .././repair/phase2.c:184 msgid " - found root inode chunk\n" msgstr " - Wurzel-Inode-Stück gefunden\n" #: .././repair/phase2.c:190 msgid "root inode marked free, " msgstr "Wurzel-Inode als frei gekennzeichnet, " #: .././repair/phase2.c:193 .././repair/phase2.c:202 .././repair/phase2.c:211 #: .././repair/dir2.c:1577 .././repair/dir2.c:1609 msgid "correcting\n" msgstr "wird berichtigt\n" #: .././repair/phase2.c:195 .././repair/phase2.c:204 .././repair/phase2.c:213 #: .././repair/dir2.c:1581 .././repair/dir2.c:1613 msgid "would correct\n" msgstr "könnte berichtigt werden\n" #: .././repair/phase2.c:199 msgid "realtime bitmap inode marked free, " msgstr "Echtzeit-Bitmap-Inode als frei gekennzeichnet, " #: .././repair/phase2.c:208 msgid "realtime summary inode marked free, " msgstr "Echtzeit-Zusammenfassungs-Inode als frei gekennzeichnet, " #: .././repair/phase7.c:43 #, c-format msgid "resetting inode %llu nlinks from %d to %d\n" msgstr "Inode %llu nlinks wird von %d auf %d zurückgesetzt\n" #: .././repair/phase7.c:49 #, c-format msgid "" "nlinks %d will overflow v1 ino, ino %llu will be converted to version 2\n" msgstr "" "nlinks %d wird überlaufen v1 ino, ino %llu wird zu Version 2 umgewandelt\n" #: .././repair/phase7.c:55 #, c-format msgid "would have reset inode %llu nlinks from %d to %d\n" msgstr "Inode %llu nlinks könnte von %d auf %d zurückgesetzt werden\n" #: .././repair/phase7.c:83 .././repair/phase6.c:3238 .././repair/phase6.c:3241 #, c-format msgid "couldn't map inode %llu, err = %d\n" msgstr "Inode %llu kann nicht kartiert werden, err = %d\n" #: .././repair/phase7.c:87 #, c-format msgid "couldn't map inode %llu, err = %d, can't compare link counts\n" msgstr "" "Inode %llu kann nicht kartiert werden, err = %d, Anzahl der Verweise kann\n" "nicht verglichen werden\n" #: .././repair/phase7.c:126 msgid "Phase 7 - verify and correct link counts...\n" msgstr "Phase 7 - Verweisanzahl wird geprüft und berichtigt...\n" #: .././repair/phase7.c:128 msgid "Phase 7 - verify link counts...\n" msgstr "Phase 7 - Verweisanzahl wird geprüft\n" #: .././repair/rt.c:47 msgid "couldn't allocate memory for incore realtime bitmap.\n" msgstr "Speicher für Incore-Echtzeit-Bitmap kann nicht alloziert werden.\n" #: .././repair/rt.c:51 msgid "couldn't allocate memory for incore realtime summary info.\n" msgstr "" "Speicher für Incore-Echtzeit-Zusammenfassungs-Info kann nicht alloziert\n" "werden.\n" #: .././repair/rt.c:203 #, c-format msgid "can't find block %d for rtbitmap inode\n" msgstr "Block %d für rtbitmap-Inode kann nicht gefunden werden\n" #: .././repair/rt.c:211 #, c-format msgid "can't read block %d for rtbitmap inode\n" msgstr "Block %d für rtbitmap-Inode kann nicht gelesen werden\n" #: .././repair/rt.c:265 #, c-format msgid "block %d for rtsummary inode is missing\n" msgstr "Block %d für rtsummary-Inode fehlt\n" #: .././repair/rt.c:273 #, c-format msgid "can't read block %d for rtsummary inode\n" msgstr "Block %d für rtsummary-Inode kann nicht gelesen werden\n" #: .././repair/scan.c:63 .././repair/scan.c:107 #, c-format msgid "can't read btree block %d/%d\n" msgstr "btree-Block %d/%d kann nicht gelesen werden\n" #: .././repair/scan.c:165 #, c-format msgid "bad magic # %#x in inode %llu (%s fork) bmbt block %llu\n" msgstr "falsche magische # %#x in Inode %llu (%s fork) bmbt Block %llu\n" #: .././repair/scan.c:171 #, c-format msgid "expected level %d got %d in inode %llu, (%s fork) bmbt block %llu\n" msgstr "" "erwartete Stufe %d hat %d in Inode %llu (%s Unterelement) bmbt Block %llu\n" #: .././repair/scan.c:191 #, c-format msgid "" "bad fwd (right) sibling pointer (saw %llu parent block says %llu)\n" "\tin inode %llu (%s fork) bmap btree block %llu\n" msgstr "" "falscher fwd (rechts) Geschwisterzeiger (%llu gesehen Elternblock\n" "\tsagt %llu) in Inode %llu (%s Unterelement) bmap btree Block %llu\n" #: .././repair/scan.c:201 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu parent block says %llu)\n" "\tin inode %llu (%s fork) bmap btree block %llu\n" msgstr "" "falscher zurück (links) Geschwisterzeiger (%llu gesehen Elternblock\n" "\tsagt %llu) in Inode %llu (%s Unterelement) bmap btree Block %llu\n" #: .././repair/scan.c:215 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu should be NULL (0))\n" "\tin inode %llu (%s fork) bmap btree block %llu\n" msgstr "" "falscher zurück (links) Geschwisterzeiger (%llu gesehen könnte NULL (0)\n" "\tsein) in Inode %llu (%s Unterelement) bmap btree Block %llu\n" #: .././repair/scan.c:250 .././repair/scan.c:258 #, c-format msgid "inode 0x%llx bmap block 0x%llx claimed, state is %d\n" msgstr "Inode 0x%llx bmap Block 0x%llx beansprucht, Status ist %d\n" #: .././repair/scan.c:274 #, c-format msgid "bad state %d, inode 0x%llx bmap block 0x%llx\n" msgstr "falscher Status %d, Inode 0x%llx bmap Block 0x%llx\n" #: .././repair/scan.c:300 .././repair/scan.c:350 #, c-format msgid "inode 0x%llx bad # of bmap records (%u, min - %u, max - %u)\n" msgstr "Inode 0x%llx falsche # von bmap-Datensätzen (%u, Min - %u, Max - %u)\n" #: .././repair/scan.c:330 #, c-format msgid "" "out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n" msgstr "" "bmap-Schlüssel außer Betrieb (Dateiversatz) in Inode %llu,\n" "%s Unterelement, fsbno %llu\n" #: .././repair/scan.c:366 .././repair/dinode.c:1228 #, c-format msgid "bad bmap btree ptr 0x%llx in ino %llu\n" msgstr "falscher bmap btree ptr 0x%llx in ino %llu\n" #: .././repair/scan.c:393 #, c-format msgid "" "correcting bt key (was %llu, now %llu) in inode %llu\n" "\t\t%s fork, btree block %llu\n" msgstr "" "bt-Schlüssel wird korrigiert (war %llu, nun %llu) in Inode %llu\n" "\t\t%s Unterelement, btree Block %llu\n" #: .././repair/scan.c:404 #, c-format msgid "" "bad btree key (is %llu, should be %llu) in inode %llu\n" "\t\t%s fork, btree block %llu\n" msgstr "" "falscher btree-Schlüssel (ist %llu, könnte %llu sein) in Inode %llu\n" "\t\t%s Unterelement, btree-Block %llu\n" #: .././repair/scan.c:421 #, c-format msgid "" "bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n" "\tin inode %llu (%s fork) bmap btree block %llu\n" msgstr "" "falscher fwd (rechts) Geschwisterzeiger (%llu gesehen könnte NULLDFSBNO\n" "\tsein) in Inode %llu (%s Unterelement) »bmap btree«-Block %llu\n" #: .././repair/scan.c:460 #, c-format msgid "bad magic # %#x in btbno block %d/%d\n" msgstr "falsche magische # %#x in btbno-Block %d/%d\n" #: .././repair/scan.c:467 #, c-format msgid "expected level %d got %d in btbno block %d/%d\n" msgstr "erwartete Stufe %d hat %d in btbno-Block %d/%d\n" #: .././repair/scan.c:486 #, c-format msgid "" "bno freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" "bno freespace btree Block beansprucht (Status %d), agno %d, bno %d,\n" "Suspekt %d\n" #: .././repair/scan.c:529 #, c-format msgid "block (%d,%d) multiply claimed by bno space tree, state - %d\n" msgstr "Block (%d,%d) mehrfach beansprucht vonbno space tree, Status - %d\n" #: .././repair/scan.c:604 #, c-format msgid "bad magic # %#x in btcnt block %d/%d\n" msgstr "falsche magische # %#x in btcnt-Block %d/%d\n" #: .././repair/scan.c:611 #, c-format msgid "expected level %d got %d in btcnt block %d/%d\n" msgstr "erwartete Stufe %d hat %d in btcnt-Block %d/%d\n" #: .././repair/scan.c:630 #, c-format msgid "" "bcnt freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" "bcnt freespace btree Block beansprucht (Status %d), agno %d, bno %d,\n" "Suspekt %d\n" #: .././repair/scan.c:680 #, c-format msgid "block (%d,%d) already used, state %d\n" msgstr "Block (%d,%d) bereits benutzt, Status %d\n" #: .././repair/scan.c:768 #, c-format msgid "bad magic # %#x in inobt block %d/%d\n" msgstr "falsche magische # %#x in inobt-Block %d/%d\n" #: .././repair/scan.c:776 #, c-format msgid "expected level %d got %d in inobt block %d/%d\n" msgstr "erwartete Stufe %d hat %d in inobt-Block %d/%d\n" #: .././repair/scan.c:799 #, c-format msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "" "Inode-btree-Block beansprucht (Status %d), agno %d, bno %d, verdächtig %d\n" #: .././repair/scan.c:822 #, c-format msgid "dubious inode btree block header %d/%d\n" msgstr "fragwürdiger Inode-btree-Kopf %d/%d\n" #: .././repair/scan.c:859 #, c-format msgid "badly aligned inode rec (starting inode = %llu)\n" msgstr "schlecht ausgerichteter Inode-rec (Start-Inode = %llu)\n" #: .././repair/scan.c:875 #, c-format msgid "bad starting inode # (%llu (0x%x 0x%x)) in ino rec, skipping rec\n" msgstr "" "falsche Start-Inode # (%llu(0x%x 0x%x)) in ino rec, rec wird übersprungen\n" #: .././repair/scan.c:884 #, c-format msgid "bad ending inode # (%llu (0x%x 0x%x)) in ino rec, skipping rec\n" msgstr "" "falsch verschlüsselte Inode # (%llu (0x%x 0x%x)) in ino rec, rec wird\n" "übersprungen\n" #: .././repair/scan.c:913 #, c-format msgid "" "inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" msgstr "" "Inode Chunk beansprucht benutzten Block, inobt Block - agno %d, bno %d,\n" "inopb %d\n" #: .././repair/scan.c:938 #, c-format msgid "inode rec for ino %llu (%d/%d) overlaps existing rec (start %d/%d)\n" msgstr "" "Inode-rec für ino %llu (%d/%d) überlappt existierenden rec (Start %d/%d)\n" #: .././repair/scan.c:990 #, c-format msgid "ir_freecount/free mismatch, inode chunk %d/%d, freecount %d nfree %d\n" msgstr "" "ir_freecount/frei keine Übereinstimmung, Inode-Chunk %d/%d,\n" "freecount %d nfree %d\n" #: .././repair/scan.c:1061 #, c-format msgid "can't read agfl block for ag %d\n" msgstr "agfl-Block für ag %d kann nicht gelesen werden\n" #: .././repair/scan.c:1074 #, c-format msgid "bad agbno %u in agfl, agno %d\n" msgstr "falsche agbno %u in agfl, agno %d\n" #: .././repair/scan.c:1083 #, c-format msgid "freeblk count %d != flcount %d in ag %d\n" msgstr "freeblk-Anzahl %d != flcount %d in ag %d\n" #: .././repair/scan.c:1110 #, c-format msgid "can't get root superblock for ag %d\n" msgstr "Wurzel-Superblock für ag %d kann nicht erlangt werden\n" #: .././repair/scan.c:1116 msgid "can't allocate memory for superblock\n" msgstr "Speicher für Superblock kann nicht alloziert werden\n" #: .././repair/scan.c:1126 #, c-format msgid "can't read agf block for ag %d\n" msgstr "agf-Block für ag %d kann nicht gelesen werden\n" #: .././repair/scan.c:1137 #, c-format msgid "can't read agi block for ag %d\n" msgstr "agi-Block für ag %d kann nicht gelesen werden\n" #: .././repair/scan.c:1161 #, c-format msgid "reset bad sb for ag %d\n" msgstr "falscher sb für ag %d wird zurückgesetzt\n" #: .././repair/scan.c:1164 #, c-format msgid "would reset bad sb for ag %d\n" msgstr "falscher sb für ag %d könnte zurückgesetzt werden\n" #: .././repair/scan.c:1169 #, c-format msgid "reset bad agf for ag %d\n" msgstr "falscher agf für ag %d wird zurückgesetzt\n" #: .././repair/scan.c:1172 #, c-format msgid "would reset bad agf for ag %d\n" msgstr "falscher agf für ag %d könnte zurückgesetzt werden\n" #: .././repair/scan.c:1177 #, c-format msgid "reset bad agi for ag %d\n" msgstr "falscher agi für ag %d wird zurückgesetzt\n" #: .././repair/scan.c:1180 #, c-format msgid "would reset bad agi for ag %d\n" msgstr "falscher agi für ag %d könnte zurückgesetzt werden\n" #: .././repair/scan.c:1190 #, c-format msgid "bad uncorrected agheader %d, skipping ag...\n" msgstr "falscher nicht berichtigter agheader %d, ag wird übersprungen...\n" #: .././repair/scan.c:1204 #, c-format msgid "bad agbno %u for btbno root, agno %d\n" msgstr "falscher agbno %u für btbno-Wurzel, agno %d\n" #: .././repair/scan.c:1214 #, c-format msgid "bad agbno %u for btbcnt root, agno %d\n" msgstr "falscher agbno %u für btbcnt-Wurzel, agno %d\n" #: .././repair/scan.c:1223 #, c-format msgid "bad agbno %u for inobt root, agno %d\n" msgstr "falscher agbno %u für inobt-Wurzel, agno %d\n" #: .././repair/dir.c:153 #, c-format msgid "invalid inode number %llu in directory %llu\n" msgstr "ungültige Inode-Nummer %llu in Verzeichnis %llu\n" #: .././repair/dir.c:158 #, c-format msgid "entry in shortform dir %llu references rt bitmap inode %llu\n" msgstr "Eintrag in Kurzform dir %llu bezieht sich auf Bitmap-Inode %llu\n" #: .././repair/dir.c:163 #, c-format msgid "entry in shortform dir %llu references rt summary inode %llu\n" msgstr "" "Eintrag in Kurzform dir %llu bezieht sich auf Zusammenfassungs-Inode %llu\n" #: .././repair/dir.c:168 #, c-format msgid "entry in shortform dir %llu references user quota inode %llu\n" msgstr "" "Eintrag in Kurzform dir %llu bezieht sich auf\n" "Benutzer-Quota-Inode %llu\n" #: .././repair/dir.c:173 #, c-format msgid "entry in shortform dir %llu references group quota inode %llu\n" msgstr "" "Eintrag in Kurzform dir %llu bezieht sich auf\n" "Gruppen-Quota-Inode %llu\n" #: .././repair/dir.c:193 #, c-format msgid "entry references free inode %llu in shortform directory %llu\n" msgstr "" "Eintrag bezieht sich auf freien Inode %llu in Kurzform-Verzeichnis %llu\n" #: .././repair/dir.c:212 #, c-format msgid "entry references non-existent inode %llu in shortform dir %llu\n" msgstr "" "Eintrag bezieht sich auf nicht existierenden Inode %llu in\n" "Kurzform-dir %llu\n" #: .././repair/dir.c:236 .././repair/dir2.c:990 #, c-format msgid "zero length entry in shortform dir %llu, resetting to %d\n" msgstr "" "Eintrag mit Länge Null in Kurzform-dir %llu, wird auf %d zurückgesetzt\n" #: .././repair/dir.c:241 .././repair/dir2.c:996 #, c-format msgid "zero length entry in shortform dir %llu, would set to %d\n" msgstr "" "Eintrag mit Länge Null in Kurzform-dir %llu, könnte auf %d zurückgesetzt\n" "werden\n" #: .././repair/dir.c:246 #, c-format msgid "zero length entry in shortform dir %llu, " msgstr "Eintrag mit Länge Null in Kurzform-dir %llu, " #: .././repair/dir.c:249 .././repair/dir.c:292 .././repair/dir2.c:1049 #, c-format msgid "junking %d entries\n" msgstr "%d Einträge werden verworfen\n" #: .././repair/dir.c:252 .././repair/dir.c:301 .././repair/dir2.c:1058 #, c-format msgid "would junk %d entries\n" msgstr "%d Einträge könnten verworfen werden\n" #: .././repair/dir.c:270 .././repair/dir2.c:1026 #, c-format msgid "size of last entry overflows space left in in shortform dir %llu, " msgstr "Größe des letzten Eintrag-Überlauf-Raums bleibt in Kurzform-dir %llu, " #: .././repair/dir.c:273 .././repair/dir2.c:1030 #, c-format msgid "resetting to %d\n" msgstr "es wird auf %d zurückgesetzt\n" #: .././repair/dir.c:278 .././repair/dir2.c:1035 #, c-format msgid "would reset to %d\n" msgstr "es könnte auf %d zurückgesetzt werden\n" #: .././repair/dir.c:283 .././repair/dir2.c:1039 #, c-format msgid "size of entry #%d overflows space left in in shortform dir %llu\n" msgstr "" "Größe des letzten Eintrag-#%d-Überlauf-Raums bleibt in Kurzform-dir %llu\n" #: .././repair/dir.c:288 .././repair/dir2.c:1045 #, c-format msgid "junking entry #%d\n" msgstr "Eintrag #%d wird verworfen\n" #: .././repair/dir.c:297 .././repair/dir2.c:1054 #, c-format msgid "would junk entry #%d\n" msgstr "Eintrag #%d könnte verworfen werden\n" #: .././repair/dir.c:320 .././repair/dir2.c:1076 #, c-format msgid "entry contains illegal character in shortform dir %llu\n" msgstr "Eintrag enthält unerlaubtes Zeichen in Kurzform-dir %llu\n" #: .././repair/dir.c:374 .././repair/dir2.c:1140 #, c-format msgid "junking entry \"%s\" in directory inode %llu\n" msgstr "Eintrag »%s« in Verzeichnis-Inode %llu wird verworfen\n" #: .././repair/dir.c:378 .././repair/dir2.c:1144 #, c-format msgid "would have junked entry \"%s\" in directory inode %llu\n" msgstr "Eintrag »%s« in Verzeichnis-Inode %llu könnte verworfen worden sein\n" #: .././repair/dir.c:404 .././repair/dir2.c:1171 #, c-format msgid "would have corrected entry count in directory %llu from %d to %d\n" msgstr "" "Eintragsanzahl könnte im Verzeichnis %llu von %d auf %d korrigiert\n" "worden sein\n" #: .././repair/dir.c:408 .././repair/dir2.c:1175 #, c-format msgid "corrected entry count in directory %llu, was %d, now %d\n" msgstr "berichtigte Eintragsanzahl im Verzeichnis %llu, war %d, nun %d\n" #: .././repair/dir.c:419 .././repair/dir2.c:1204 #, c-format msgid "would have corrected directory %llu size from %lld to %lld\n" msgstr "" "Größe des Verzeichnisses %llu könnte von %lld auf %lld berichtigt worden\n" "sein\n" #: .././repair/dir.c:424 .././repair/dir2.c:1210 #, c-format msgid "corrected directory %llu size, was %lld, now %lld\n" msgstr "Größe des Verzeichnisses %llu berichtigt, war %lld, nun %lld\n" #: .././repair/dir.c:446 .././repair/dir2.c:1252 #, c-format msgid "bogus .. inode number (%llu) in directory inode %llu, " msgstr "fingiert .. Inode-Nummer (%llu) in Verzeichnis-Inode %llu, " #: .././repair/dir.c:449 .././repair/dir.c:483 .././repair/dir2.c:1257 #: .././repair/dir2.c:1292 msgid "clearing inode number\n" msgstr "Inode-Nummer wird bereinigt\n" #: .././repair/dir.c:455 .././repair/dir.c:489 .././repair/dir2.c:1263 #: .././repair/dir2.c:1298 msgid "would clear inode number\n" msgstr "Inode-Nummer könnte bereinigt werden\n" #: .././repair/dir.c:463 .././repair/dir2.c:1270 #, c-format msgid "corrected root directory %llu .. entry, was %llu, now %llu\n" msgstr "Wurzel-Verzeichnis %llu berichtigt .. Eintrag war %llu, nun %llu\n" #: .././repair/dir.c:471 .././repair/dir2.c:1278 #, c-format msgid "would have corrected root directory %llu .. entry from %llu to %llu\n" msgstr "" "Wurzel-Verzeichnis %llu könnte berichtigt worden sein .. Eintrag von\n" "%llu zu %llu\n" #: .././repair/dir.c:480 #, c-format msgid "bad .. entry in dir ino %llu, points to self, " msgstr "falscher ..-Eintrag in dir ino %llu, zeigt auf sich selbst, " #: .././repair/dir.c:528 #, c-format msgid "bad range claimed [%d, %d) in da block\n" msgstr "falscher Bereich beansprucht [%d, %d) in da-Block\n" #: .././repair/dir.c:535 #, c-format msgid "byte range end [%d %d) in da block larger than blocksize %d\n" msgstr "Byte-Bereichsende [%d, %d) in da-Block größer als Blockgröße %d\n" #: .././repair/dir.c:542 #, c-format msgid "multiply claimed byte %d in da block\n" msgstr "mehrfach beanspruchtes Byte %d in da-Block\n" #: .././repair/dir.c:572 #, c-format msgid "hole (start %d, len %d) out of range, block %d, dir ino %llu\n" msgstr "" "Loch (Start %d, len %d) außerhalb des Bereiches, Block %d, dir ino %llu\n" #: .././repair/dir.c:583 #, c-format msgid "hole claims used byte %d, block %d, dir ino %llu\n" msgstr "Loch beansprucht benutztes Byte %d, Block %d, dir ino %llu\n" #: .././repair/dir.c:698 #, c-format msgid "- derived hole value %d, saw %d, block %d, dir ino %llu\n" msgstr "- abgeleiteter Lochwert %d, gesehen %d, Block %d, dir ino %llu\n" #: .././repair/dir.c:717 #, c-format msgid "" "- derived hole (base %d, size %d) in block %d, dir inode %llu not found\n" msgstr "" "- abgeleitetes Loch (Basis %d, Größe %d) in Block %d, dir Inode %llu\n" "nicht gefunden\n" #: .././repair/dir.c:793 .././repair/dir.c:971 .././repair/phase6.c:1198 #: .././repair/phase6.c:1566 #, c-format msgid "can't read block %u (fsbno %llu) for directory inode %llu\n" msgstr "" "Block %u(fsbno %llu) kann nicht gelesen werden für Verzeichnis-Inode %llu\n" #: .././repair/dir.c:797 #, c-format msgid "can't read block %u (fsbno %llu) for attrbute fork of inode %llu\n" msgstr "" "Block %u(fsbno %llu) kann nicht gelesen werden für Attributs-Unterelement\n" "des Inodes %llu\n" #: .././repair/dir.c:806 .././repair/dir.c:981 .././repair/phase6.c:1208 #, c-format msgid "bad dir/attr magic number in inode %llu, file bno = %u, fsbno = %llu\n" msgstr "falsche dir/attr magische Nummer in Inode %llu, Datei bno = %u,\n" "fsbno = %llu\n" #: .././repair/dir.c:814 .././repair/dir2.c:333 #, c-format msgid "bad record count in inode %llu, count = %d, max = %d\n" msgstr "falsche Datensatz-Anzahl in Inode %llu, Anzahl = %d max = %d\n" #: .././repair/dir.c:833 .././repair/dir2.c:356 #, c-format msgid "bad directory btree for directory inode %llu\n" msgstr "falscher Verzeichnis-btree für Verzeichnis-Inode %llu\n" #: .././repair/dir.c:837 #, c-format msgid "bad attribute fork btree for inode %llu\n" msgstr "falsches Attributs-Unterelement btree für Inode %llu\n" #: .././repair/dir.c:891 #, c-format msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "release_da_cursor_int hat unerwartetes Nicht-Null bp, dabno = %u\n" #: .././repair/dir.c:952 .././repair/dir.c:997 #, c-format msgid "bmap of block #%u of inode %llu failed\n" msgstr "bmap des Blocks #%u des Inodes %llu fehlgeschlagen\n" #: .././repair/dir.c:1043 #, c-format msgid "directory/attribute block used/count inconsistency - %d/%hu\n" msgstr "Verzeichnis-/Attributsblock benutzt/Unstimmigkeit gezählt - %d/%hu\n" #: .././repair/dir.c:1053 .././repair/dir2.c:479 #, c-format msgid "" "directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" msgstr "" "Verzeichnis-/Attributsblock Hash-Wert-Unstimmigkeit, erwartet > %u /\n" "gesehen %u\n" #: .././repair/dir.c:1060 .././repair/dir2.c:486 #, c-format msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" msgstr "falscher Verzeichnis-/Attribut-Block-Zeiger, erwartet 0, gesehen %u\n" #: .././repair/dir.c:1066 #, c-format msgid "bad directory block in dir ino %llu\n" msgstr "falscher Verzeichnis-Block in dir ino %llu\n" #: .././repair/dir.c:1096 #, c-format msgid "" "correcting bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in non-leaf dir/attr-Block wird korrigiert\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir.c:1104 #, c-format msgid "" "would correct bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "würde hashval in non-leaf dir/attr-Block korrigieren\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir.c:1242 .././repair/dir2.c:650 #, c-format msgid "can't get map info for block %u of directory inode %llu\n" msgstr "" "Karten-Info für Block %u des Verzeichnis-Inodes %llu kann nicht bezogen\n" "werden\n" #: .././repair/dir.c:1251 #, c-format msgid "can't read block %u (%llu) for directory inode %llu\n" msgstr "Block %u (%llu) für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/dir.c:1264 #, c-format msgid "bad magic number %x in block %u (%llu) for directory inode %llu\n" msgstr "" "falsche magische Nummer %x in Block %u (%llu) füu Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1272 #, c-format msgid "bad back pointer in block %u (%llu) for directory inode %llu\n" msgstr "" "falscher Rückwarts-Zeiger in Block %u (%llu) für Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1278 #, c-format msgid "entry count %d too large in block %u (%llu) for directory inode %llu\n" msgstr "" "Eintragsanzahl %d zu groß in Block %u (%llu) für Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1285 #, c-format msgid "bad level %d in block %u (%llu) for directory inode %llu\n" msgstr "falsche Stufe %d in Block %u (%llu) für Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1343 #, c-format msgid "" "correcting bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in innerem dir/attr-Block wird berichtigt\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir.c:1351 #, c-format msgid "" "would correct bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in innerem dir/attr-Block könnte berichtigt werden\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir.c:1462 #, c-format msgid "" "directory block header conflicts with used space in directory inode %llu\n" msgstr "" "Kopf des Verzeichnisblocks hat einen Konflikt mit dem benutzten Raum im\n" "Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1491 #, c-format msgid "" "nameidx %d for entry #%d, bno %d, ino %llu > fs blocksize, deleting entry\n" msgstr "" "nameidx %d für Eintrag #%d, bno %d, ino %llu > fs Blockgröße, Eintrag\n" "wird gelöscht\n" #: .././repair/dir.c:1528 #, c-format msgid "" "nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, marking entry bad\n" msgstr "" "nameidx %d, Eintrag #%d, bno %d, ino %llu > fs Blockgröße, falscher\n" "Eintrag wird gekennzeichnet\n" #: .././repair/dir.c:1543 #, c-format msgid "" "nameidx %d, entry #%d, bno %d, ino %llu > fs blocksize, would delete entry\n" msgstr "" "nameidx %d für Eintrag #%d, bno %d, ino %llu > fs Blockgröße, Eintrag\n" "könnte gelöscht werden.\n" #: .././repair/dir.c:1580 #, c-format msgid "invalid ino number %llu in dir ino %llu, entry #%d, bno %d\n" msgstr "ungültige ino-Nummer %llu in dir ino %llu, Eintrag #%d, bno %d\n" #: .././repair/dir.c:1584 .././repair/dir.c:1600 .././repair/dir.c:1617 #: .././repair/dir.c:1633 .././repair/dir.c:1650 #, c-format msgid "\tclearing ino number in entry %d...\n" msgstr "\tino-Nummer in Eintrag %d wird bereinigt...\n" #: .././repair/dir.c:1591 .././repair/dir.c:1608 .././repair/dir.c:1624 #: .././repair/dir.c:1641 .././repair/dir.c:1658 #, c-format msgid "\twould clear ino number in entry %d...\n" msgstr "\tino-Nummer in Eintrag %d könnte bereinigt werden...\n" #: .././repair/dir.c:1596 #, c-format msgid "" "entry #%d, bno %d in directory %llu references realtime bitmap inode %llu\n" msgstr "" "Eintrag #%d, bno %d in Verzeichnis %llu bezieht sich auf\n" "Echtzeit-Bitmap-Inode %llu\n" #: .././repair/dir.c:1613 #, c-format msgid "" "entry #%d, bno %d in directory %llu references realtime summary inode %llu\n" msgstr "" "Eintrag #%d, bno %d in Verzeichnis %llu bezieht sich auf\n" "Echtzeit-Zusammenfassungs-Inode %llu\n" #: .././repair/dir.c:1629 #, c-format msgid "entry #%d, bno %d in directory %llu references user quota inode %llu\n" msgstr "" "Eintrag #%d, bno %d in Verzeichnis %llu bezieht sich auf\n" "Benutzer-Quota-Inode %llu\n" #: .././repair/dir.c:1646 #, c-format msgid "entry #%d, bno %d in directory %llu references group quota inode %llu\n" msgstr "" "Eintrag #%d, bno %d in Verzeichnis %llu bezieht sich auf\n" "Gruppen-Quota-Inode %llu\n" #: .././repair/dir.c:1683 #, c-format msgid "entry references free inode %llu in directory %llu, will clear entry\n" msgstr "" "Eintrag bezieht sich auf freien Inode %llu im Verzeichnis %llu, Eintrag\n" "soll bereinigt werden\n" #: .././repair/dir.c:1691 #, c-format msgid "entry references free inode %llu in directory %llu, would clear entry\n" msgstr "" "Eintrag bezieht sich auf freien Inode %llu im Verzeichnis %llu, Eintrag\n" "könnte bereinigt werden\n" #: .././repair/dir.c:1699 #, c-format msgid "bad ino number %llu in dir ino %llu, entry #%d, bno %d\n" msgstr "falsche ino-Nummer %llu in dir ino %llu, Eintrag #%d, bno %d\n" #: .././repair/dir.c:1702 msgid "clearing inode number...\n" msgstr "Inode-Nummer wird bereinigt...\n" #: .././repair/dir.c:1707 msgid "would clear inode number...\n" msgstr "Inode-Nummer könnte bereinigt werden...\n" #: .././repair/dir.c:1727 #, c-format msgid "entry #%d, dir inode %llu, has zero-len name, deleting entry\n" msgstr "" "Eintrag #%d, dir Inode %llu, hat zero-len Name, Eintrag wird gelöscht\n" #: .././repair/dir.c:1765 #, c-format msgid "entry #%d, dir inode %llu, has zero-len name, marking entry bad\n" msgstr "" "Eintrag #%d, dir Inode %llu, hat zero-len Name, Eintrag wird\n" "gekennzeichnet\n" #: .././repair/dir.c:1778 #, c-format msgid "" "bad size, entry #%d in dir inode %llu, block %u -- entry overflows block\n" msgstr "" "falsche Größe, Eintrag #%d in dir Inode %llu, Block %u -- Eintrag\n" "überflutet Block\n" #: .././repair/dir.c:1789 #, c-format msgid "" "dir entry slot %d in block %u conflicts with used space in dir inode %llu\n" msgstr "" "dir-Eintrag-Slot %d in Block %u hat einen Konflikt mit dem benutzten\n" "Raum im Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1828 #, c-format msgid "illegal name \"%s\" in directory inode %llu, entry will be cleared\n" msgstr "" "unerlaubter Name »%s« im Verzeichnis-Inode %llu, Eintrag soll bereinigt\n" "werden\n" #: .././repair/dir.c:1834 #, c-format msgid "illegal name \"%s\" in directory inode %llu, entry would be cleared\n" msgstr "" "unerlaubter Name »%s« im Verzeichnis-Inode %llu, Eintrag könnte bereinigt\n" "werden\n" #: .././repair/dir.c:1844 #, c-format msgid "\tmismatched hash value for entry \"%s\"\n" msgstr "\tnicht übereinstimmender Hash-Wert für Eintrag »%s«\n" #: .././repair/dir.c:1848 #, c-format msgid "\t\tin directory inode %llu. resetting hash value.\n" msgstr "\t\tin Verzeichnis-Inode %llu. Hash-Wert wird zurückgesetzt.\n" #: .././repair/dir.c:1854 #, c-format msgid "\t\tin directory inode %llu. would reset hash value.\n" msgstr "" "\t\tin Verzeichnis-Inode %llu. Hash-Wert könnte zurückgesetzt werden.\n" #: .././repair/dir.c:1884 #, c-format msgid "\tbad hash ordering for entry \"%s\"\n" msgstr "\t falsche Hash-Anforderung für Eintrag »%s«\n" #: .././repair/dir.c:1888 #, c-format msgid "\t\tin directory inode %llu. will clear entry\n" msgstr "\t\tin Verzeichnis-Inode %llu. Eintrag soll bereinigt werden\n" #: .././repair/dir.c:1895 #, c-format msgid "\t\tin directory inode %llu. would clear entry\n" msgstr "\t\tin Verzeichnis-Inode %llu. Eintrag könnte bereinigt werden\n" #: .././repair/dir.c:1911 #, c-format msgid "" "name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %llu\n" msgstr "" "Name »%s« (Block %u, Slot %d) hat einen Konflikt mit benutztem Raum in\n" "dir-Inode %llu\n" #: .././repair/dir.c:1918 #, c-format msgid "will clear entry \"%s\" (#%d) in directory inode %llu\n" msgstr "Eintrag »%s« (#%d) soll gelöscht werden in Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1922 #, c-format msgid "would clear entry \"%s\" (#%d)in directory inode %llu\n" msgstr "Eintrag »%s« (#%d) könnte gelöscht werden in Verzeichnis-Inode %llu\n" #: .././repair/dir.c:1958 #, c-format msgid "bad .. entry in dir ino %llu, points to self" msgstr "falscher ..-Eintrag in dir ino %llu, zeigt auf sich selbst" #: .././repair/dir.c:1962 .././repair/dir.c:2059 msgid "will clear entry\n" msgstr "Eintrag soll gelöscht werden\n" #: .././repair/dir.c:1967 .././repair/dir.c:2063 .././repair/dir2.c:1641 msgid "would clear entry\n" msgstr "Eintrag könnte gelöscht werden\n" #: .././repair/dir.c:1977 #, c-format msgid "correcting .. entry in root inode %llu, was %llu\n" msgstr "wird berichtigt .. Eintrag in Wurzel-Inode %llu, war %llu\n" #: .././repair/dir.c:1984 #, c-format msgid "bad .. entry (%llu) in root inode %llu should be %llu\n" msgstr "falscher .. Eintrag (%llu) in Wurzel-Inode %llu könnte %llu sein\n" #: .././repair/dir.c:2001 #, c-format msgid "multiple .. entries in directory inode %llu, will clear second entry\n" msgstr "" "mehrfache .. Einträge in Verzeichnis-Inode %llu, zweiter Eintrag wird\n" "bereinigt werden\n" #: .././repair/dir.c:2007 #, c-format msgid "multiple .. entries in directory inode %llu, would clear second entry\n" msgstr "" "mehrfache .. Einträge in Verzeichnis-Inode %llu, zweiter Eintrag könnte\n" "bereinigt werden\n" #: .././repair/dir.c:2020 #, c-format msgid ". in directory inode %llu has wrong value (%llu), fixing entry...\n" msgstr "" ". in Verzeichnis-Inode %llu hat falschen Wert (%llu), stelle Eintrag\n" "wieder her ..\n" #: .././repair/dir.c:2027 #, c-format msgid ". in directory inode %llu has wrong value (%llu)\n" msgstr ". in Verzeichnis-Inode %llu hat falschen Wert (%llu)\n" #: .././repair/dir.c:2033 #, c-format msgid "multiple . entries in directory inode %llu\n" msgstr "mehrfache .. Einträge in Verzeichnis-Inode %llu\n" #: .././repair/dir.c:2040 #, c-format msgid "will clear one . entry in directory inode %llu\n" msgstr "ein . Eintrag in Verzeichnis-Inode %llu wird bereinigt\n" #: .././repair/dir.c:2046 #, c-format msgid "would clear one . entry in directory inode %llu\n" msgstr "ein . Eintrag in Verzeichnis-Inode %llu könnte bereinigt werden\n" #: .././repair/dir.c:2056 #, c-format msgid "entry \"%s\" in directory inode %llu points to self, " msgstr "Eintrag »%s« in Verzeichnis-Inode %llu zeigt auf sich selbst, " #: .././repair/dir.c:2081 #, c-format msgid "" "- resetting first used heap value from %d to %d in block %u of dir ino %llu\n" msgstr "" "- zuerst benutzter heap-Wert wird von %d auf %d in Block %u von \n" "dir ino %llu zurückgesetzt\n" #: .././repair/dir.c:2089 #, c-format msgid "" "- would reset first used value from %d to %d in block %u of dir ino %llu\n" msgstr "" "- zuerst benutzter heap-Wert könnte von %d auf %d in Block %u von \n" "dir ino %llu zurückgesetzt werden\n" #: .././repair/dir.c:2099 #, c-format msgid "- resetting namebytes cnt from %d to %d in block %u of dir inode %llu\n" msgstr "" "- Namensbytes cnt werden von %d auf %d in Block %u von dir ino %llu\n" "zurückgesetzt\n" #: .././repair/dir.c:2107 #, c-format msgid "" "- would reset namebytes cnt from %d to %d in block %u of dir inode %llu\n" msgstr "" "- Namensbytes cnt könnten von %d auf %d in Block %u von dir ino %llu\n" "zurückgesetzt werden\n" #: .././repair/dir.c:2142 #, c-format msgid "- found unexpected lost holes in block %u, dir inode %llu\n" msgstr "- unerwartet verlorene Löcher in Block %u, dir-Inode %llu gefunden\n" #: .././repair/dir.c:2150 #, c-format msgid "- hole info non-optimal in block %u, dir inode %llu\n" msgstr "- Loch-Info nicht optimal in Block %u, dir-Inode %llu\n" #: .././repair/dir.c:2157 #, c-format msgid "- hole info incorrect in block %u, dir inode %llu\n" msgstr "- Loch-Info falsch in Block %u, dir-Inode %llu\n" #: .././repair/dir.c:2168 #, c-format msgid "- existing hole info for block %d, dir inode %llu (base, size) - \n" msgstr "" "- existierende Loch-Info für Block %d, dir-Inode %llu (Basis, Größe) - \n" #: .././repair/dir.c:2176 #, c-format msgid "- holes flag = %d\n" msgstr "- Loch-Kennzeichner = %d\n" #: .././repair/dir.c:2182 #, c-format msgid "- compacting block %u in dir inode %llu\n" msgstr "- Block %u in dir-Inode %llu wird verdichtet\n" #: .././repair/dir.c:2223 #, c-format msgid "not enough space in block %u of dir inode %llu for all entries\n" msgstr "nicht genug Platz in Block %u von dir-Inode %llu für alle Einträge\n" #: .././repair/dir.c:2291 #, c-format msgid "- would compact block %u in dir inode %llu\n" msgstr "- Block %u in dir-Inode %llu könnte verdichtet werden\n" #: .././repair/dir.c:2353 .././repair/dir2.c:1823 #, c-format msgid "can't map block %u for directory inode %llu\n" msgstr "Block %u für Verzeichnis-Inode %llu kann nicht kartiert werden\n" #: .././repair/dir.c:2364 #, c-format msgid "" "can't read file block %u (fsbno %llu, daddr %lld) for directory inode %llu\n" msgstr "" "Block %u (fsbno %llu, daddr %lld) für Verzeichnis-Inode %llu kann nicht\n" "gelesen werden\n" #: .././repair/dir.c:2378 .././repair/dir.c:2639 #, c-format msgid "bad directory leaf magic # %#x for dir ino %llu\n" msgstr "falsches Verzeichnis-Blatt magische # %#x für dir ino %llu\n" #: .././repair/dir.c:2417 #, c-format msgid "" "bad sibling back pointer for directory block %u in directory inode %llu\n" msgstr "" "falscher Geschwister-Rückwärts-Zeiger für Verzeichnis-Block %u in\n" "Verzeichnis-Inode %llu\n" #: .././repair/dir.c:2449 .././repair/dir2.c:1900 #, c-format msgid "bad hash path in directory %llu\n" msgstr "falscher Hash-Pfad in Verzeichnis %llu\n" #: .././repair/dir.c:2559 #, c-format msgid "out of range internal directory block numbers (inode %llu)\n" msgstr "interne Verzeichnis-Blocknummern (Inode %llu) außerhalb des Bereichs\n" #: .././repair/dir.c:2565 #, c-format msgid "setting directory inode (%llu) size to %llu bytes, was %lld bytes\n" msgstr "" "Größe des Verzeichnis-Inodes (%llu) wird auf %llu Bytes gesetzt,\n" "war %lld Bytes\n" #: .././repair/dir.c:2619 #, c-format msgid "block 0 for directory inode %llu is missing\n" msgstr "Block 0 für Verzeichnis-Inode %llu fehlt\n" #: .././repair/dir.c:2626 #, c-format msgid "can't read block 0 for directory inode %llu\n" msgstr "Block 0 für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/dir.c:2662 #, c-format msgid "clearing forw/back pointers for directory inode %llu\n" msgstr "" "Vorwärts-/Rückwärtszeiger für Verzeichnis-Inode %llu werden bereinigt\n" #: .././repair/dir.c:2668 #, c-format msgid "would clear forw/back pointers for directory inode %llu\n" msgstr "" "Vorwärts-/Rückwärtszeiger für Verzeichnis-Inode %llu könnten bereinigt\n" "werden.\n" #: .././repair/dir.c:2733 .././repair/dir2.c:2105 #, c-format msgid "no . entry for directory %llu\n" msgstr "kein . Eintrag für Verzeichnis %llu\n" #: .././repair/dir.c:2742 .././repair/dir2.c:2115 #, c-format msgid "no .. entry for directory %llu\n" msgstr "kein .. Eintrag für Verzeichnis %llu\n" #: .././repair/dir.c:2744 .././repair/dir2.c:2117 #, c-format msgid "no .. entry for root directory %llu\n" msgstr "kein .. Eintrag für Wurzelverzeichnis %llu\n" #: .././repair/incore_ext.c:121 .././repair/incore_ext.c:679 msgid "couldn't allocate new extent descriptors.\n" msgstr "neue Umfang-Deskriptoren können nicht alloziert werden.\n" #: .././repair/incore_ext.c:254 msgid "duplicate bno extent range\n" msgstr "doppelter bno-Umfangs-Bereich\n" #: .././repair/incore_ext.c:391 msgid ": duplicate bno extent range\n" msgstr ": doppelter bno-Umfangs-Bereich\n" #: .././repair/incore_ext.c:555 .././repair/incore_ext.c:606 #: .././repair/incore_ext.c:797 .././repair/incore_ext.c:852 msgid "duplicate extent range\n" msgstr "doppelter Umfangs-Bereich\n" #: .././repair/incore_ext.c:910 msgid "couldn't malloc dup extent tree descriptor table\n" msgstr "" "malloc dup extent konnte nicht für Baum-Deskriptor-Tabelle ausgeführt\n" "werden\n" #: .././repair/incore_ext.c:915 msgid "couldn't malloc free by-bno extent tree descriptor table\n" msgstr "" "malloc free by-bno extent konnte nicht für Baum-Deskriptor-Tabelle\n" "ausgeführt werden\n" #: .././repair/incore_ext.c:920 msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" msgstr "" "malloc free by-bcnt extent konnte nicht für Baum-Deskriptor-Tabelle\n" "ausgeführt werden\n" #: .././repair/incore_ext.c:926 msgid "couldn't malloc dup extent tree descriptor\n" msgstr "malloc dup extent konnte nicht für Baum-Deskriptor ausgeführt werden\n" #: .././repair/incore_ext.c:930 msgid "couldn't malloc bno extent tree descriptor\n" msgstr "malloc bno extent konnte nicht für Baum-Deskriptor ausgeführt werden\n" #: .././repair/incore_ext.c:934 msgid "couldn't malloc bcnt extent tree descriptor\n" msgstr "" "malloc bcnt extent konnte nicht für Baum-Deskriptor ausgeführt werden\n" #: .././repair/incore_ext.c:944 msgid "couldn't malloc dup rt extent tree descriptor\n" msgstr "" "malloc dup rt extent konnte nicht für Baum-Deskriptor ausgeführt werden\n" #: .././repair/dir2.c:56 #, c-format msgid "malloc failed (%u bytes) dir2_add_badlist:ino %llu\n" msgstr "malloc fehlgeschlagen (%u Bytes) dir2_add_badlist:ino %llu\n" #: .././repair/dir2.c:97 .././repair/dir2.c:208 .././repair/dir2.c:244 msgid "couldn't malloc dir2 buffer list\n" msgstr "malloc dir2 Pufferliste konnte nicht ausgeführt werden\n" #: .././repair/dir2.c:124 msgid "couldn't malloc dir2 buffer header\n" msgstr "malloc dir2 Pufferkopfzeilen konnte nicht ausgeführt werden\n" #: .././repair/dir2.c:141 msgid "couldn't malloc dir2 buffer data\n" msgstr "malloc dir2 Pufferdaten konnte nicht ausgeführt werden\n" #: .././repair/dir2.c:305 .././repair/dir2.c:661 .././repair/dir2.c:1705 #: .././repair/phase6.c:2272 #, c-format msgid "can't read block %u for directory inode %llu\n" msgstr "Block %u für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/dir2.c:315 #, c-format msgid "found non-root LEAFN node in inode %llu bno = %u\n" msgstr "Nicht-Wurzel-LEAFN-Knoten gefunden in Inode %llu bno = %u\n" #: .././repair/dir2.c:324 #, c-format msgid "bad dir magic number 0x%x in inode %llu bno = %u\n" msgstr "falsche magische Nummer 0x%x in Inode %llu bno = %u\n" #: .././repair/dir2.c:345 #, c-format msgid "bad header depth for directory inode %llu\n" msgstr "falsche Kopfzeilentiefe für Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:407 #, c-format msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "release_dir2_cursor_int hat unerwartetes Nicht-Null-bp, dabno = %u\n" #: .././repair/dir2.c:470 #, c-format msgid "directory block used/count inconsistency - %d / %hu\n" msgstr "Verzeichnis-Block benutzt/Anzahl unvollständig - %d / %hu\n" #: .././repair/dir2.c:492 #, c-format msgid "bad directory block in inode %llu\n" msgstr "falscher Verzeichnisblock in Inode %llu\n" #: .././repair/dir2.c:512 #, c-format msgid "" "correcting bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in non-leaf dir-Block wird koorigiert\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir2.c:519 #, c-format msgid "" "would correct bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in non-leaf dir-Block würde koorigiert\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir2.c:674 #, c-format msgid "bad magic number %x in block %u for directory inode %llu\n" msgstr "falsche Magische Nummer %x in Block %u für Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:682 #, c-format msgid "bad back pointer in block %u for directory inode %llu\n" msgstr "falscher Rückwärts-Zeiger in Block %u für Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:688 #, c-format msgid "entry count %d too large in block %u for directory inode %llu\n" msgstr "Eintragsanzahl %d in Block %u für Verzeichnis-Inode %llu zu groß\n" #: .././repair/dir2.c:695 #, c-format msgid "bad level %d in block %u for directory inode %llu\n" msgstr "falsche Stufe %d in Block %u für Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:738 #, c-format msgid "" "correcting bad hashval in interior dir block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in interior dir-Block wird koorigiert\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir2.c:745 #, c-format msgid "" "would correct bad hashval in interior dir block\n" "\tin (level %d) in inode %llu.\n" msgstr "" "falscher hashval in interior dir-Block würde koorigiert\n" "\tin (Stufe %d) in Inode %llu.\n" #: .././repair/dir2.c:779 msgid "couldn't malloc dir2 shortform copy\n" msgstr "malloc dir2 Kurzformkopie kann nicht durchgeführt werden\n" #: .././repair/dir2.c:917 msgid "current" msgstr "aktuell" #: .././repair/dir2.c:920 .././repair/dir2.c:1443 msgid "invalid" msgstr "ungültig" #: .././repair/dir2.c:923 .././repair/dir2.c:1445 msgid "realtime bitmap" msgstr "Echtzeit-Bitmap" #: .././repair/dir2.c:926 .././repair/dir2.c:1447 msgid "realtime summary" msgstr "Echtzeit-Zusammenfassung" #: .././repair/dir2.c:929 .././repair/dir2.c:1449 msgid "user quota" msgstr "Benutzer-Quota" #: .././repair/dir2.c:932 .././repair/dir2.c:1451 msgid "group quota" msgstr "Gruppen-Quota" #: .././repair/dir2.c:966 .././repair/dir2.c:1460 msgid "non-existent" msgstr "nicht existent" #: .././repair/dir2.c:970 #, c-format msgid "entry \"%*.*s\" in shortform directory %llu references %s inode %llu\n" msgstr "" "Eintrag »%*.*s« in Kurzform-Verzeichnis %llu verweist auf %s Inode %llu\n" #: .././repair/dir2.c:1002 #, c-format msgid "zero length entry in shortform dir %llu" msgstr "Eintrag der Länge Null in Kurzform dir %llu" #: .././repair/dir2.c:1006 #, c-format msgid ", junking %d entries\n" msgstr ", %d Einträge werden verworfen\n" #: .././repair/dir2.c:1009 #, c-format msgid ", would junk %d entries\n" msgstr ", %d Einträge könnten verworfen werden\n" #: .././repair/dir2.c:1083 #, c-format msgid "entry contains offset out of order in shortform dir %llu\n" msgstr "Eintrag enthält Versatz außer Betrieb in Kurzform-dir %llu\n" #: .././repair/dir2.c:1186 #, c-format msgid "would have corrected i8 count in directory %llu from %d to %d\n" msgstr "" "i8-Anzahl in Verzeichnis %llu könnte von %d auf %d berichtigt worden sein\n" #: .././repair/dir2.c:1190 #, c-format msgid "corrected i8 count in directory %llu, was %d, now %d\n" msgstr "i8-Anzahl in Verzeichnis %llu wurde berichtigt, war %d, nun %d\n" #: .././repair/dir2.c:1224 #, c-format msgid "directory %llu offsets too high\n" msgstr "Verzeichnis %llu Versätze zu groß\n" #: .././repair/dir2.c:1229 #, c-format msgid "would have corrected entry offsets in directory %llu\n" msgstr "Eintrags-Versätze in Verzeichnis %llu könnten berichtigt worden sein\n" #: .././repair/dir2.c:1233 #, c-format msgid "corrected entry offsets in directory %llu\n" msgstr "Eintrags-Versätze in Verzeichnis %llu wurden berichtigt\n" #: .././repair/dir2.c:1288 #, c-format msgid "bad .. entry in directory inode %llu, points to self, " msgstr "falscher .. Eintrag in Verzeichnis-Inode %llu, zeigt auf sich selbst, " #: .././repair/dir2.c:1401 #, c-format msgid "corrupt block %u in directory inode %llu\n" msgstr "kaputter Block %u in Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:1404 msgid "\twill junk block\n" msgstr "\tBlock wird weggeworfen\n" #: .././repair/dir2.c:1406 msgid "\twould junk block\n" msgstr "\tBlock könnte weggeworfen werden\n" #: .././repair/dir2.c:1488 #, c-format msgid "" "entry \"%*.*s\" at block %u offset %d in directory inode %llu references %s " "inode %llu\n" msgstr "" "Eintrag »%*.*s« in Block %u Versatz %d in Verzeichnis-Inode %llu bezieht\n" "sich auf %s Inode %llu\n" #: .././repair/dir2.c:1499 #, c-format msgid "entry at block %u offset %d in directory inode %llu has 0 namelength\n" msgstr "" "Eintrag in Block %u Versatz %d in Verzeichnis-Inode %llu hat\n" "Namenslänge 0\n" #: .././repair/dir2.c:1511 #, c-format msgid "\tclearing inode number in entry at offset %d...\n" msgstr "\t Inode-Nummer im Eintrag bei Versatz %d wird bereinigt...\n" #: .././repair/dir2.c:1518 #, c-format msgid "\twould clear inode number in entry at offset %d...\n" msgstr "\t Inode-Nummer im Eintrag bei Versatz %d könnte bereinigt werden...\n" #: .././repair/dir2.c:1531 #, c-format msgid "" "entry at block %u offset %d in directory inode %llu has illegal name \"%*.*s" "\": " msgstr "" "Eintrag in Block %u Versatz %d in Verzeichnis-Inode %llu hat unerlaubten\n" "Namen »%*.*s«: " #: .././repair/dir2.c:1561 #, c-format msgid "bad .. entry in directory inode %llu, points to self: " msgstr "falscher .. Eintrag in Verzeichnis-Inode %llu zeigt auf sich selbst: " #: .././repair/dir2.c:1572 #, c-format msgid "bad .. entry in root directory inode %llu, was %llu: " msgstr "falscher .. Eintrag in Wurzelverzeichnis-Inode %llu, war %llu: " #: .././repair/dir2.c:1592 #, c-format msgid "multiple .. entries in directory inode %llu: " msgstr "mehrere .. Einträge in Verzeichnis-Inode %llu: " #: .././repair/dir2.c:1605 #, c-format msgid "bad . entry in directory inode %llu, was %llu: " msgstr "falscher . Eintrag in Verzeichnis-Inode %llu, war %llu: " #: .././repair/dir2.c:1617 #, c-format msgid "multiple . entries in directory inode %llu: " msgstr "mehrere . Einträge in Verzeichnis-Inode %llu: " #: .././repair/dir2.c:1627 #, c-format msgid "entry \"%*.*s\" in directory inode %llu points to self: " msgstr "Eintrag »%*.*s« in Verzeichnis-Inode %llu zeigt auf sich selbst: " #: .././repair/dir2.c:1639 msgid "clearing entry\n" msgstr "Eintrag wird bereinigt\n" #: .././repair/dir2.c:1653 #, c-format msgid "bad bestfree table in block %u in directory inode %llu: " msgstr "falsche bestfree-Tabelle in Block %u in Verzeichnis-Inode %llu: " #: .././repair/dir2.c:1656 msgid "repairing table\n" msgstr "Tabelle wird repariert\n" #: .././repair/dir2.c:1660 msgid "would repair table\n" msgstr "Tabelle könnte repariert werden\n" #: .././repair/dir2.c:1697 #, c-format msgid "block %u for directory inode %llu is missing\n" msgstr "Block %u für Verzeichnis-Inode %llu fehlt\n" #: .././repair/dir2.c:1714 #, c-format msgid "bad directory block magic # %#x in block %u for directory inode %llu\n" msgstr "" "falscher Verzeichnisblock magische # %#x in Block %u für\n" "Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:1758 #, c-format msgid "bad entry count in block %u of directory inode %llu\n" msgstr "falsche Eintragsanzahl in Block %u des Verzeichnis-Inodes %llu\n" #: .././repair/dir2.c:1766 #, c-format msgid "bad hash ordering in block %u of directory inode %llu\n" msgstr "falsche Hash-Reihenfolge in Block %u von Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:1775 #, c-format msgid "bad stale count in block %u of directory inode %llu\n" msgstr "falsche Stale-Anzahl in Block %u von Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:1833 #, c-format msgid "can't read file block %u for directory inode %llu\n" msgstr "Dateiblock %u für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/dir2.c:1844 #, c-format msgid "bad directory leaf magic # %#x for directory inode %llu block %u\n" msgstr "" "falsches Verzeichnisblatt magische # %#x für Verzeichnis-Inode %llu Block %u\n" #: .././repair/dir2.c:1874 #, c-format msgid "bad sibling back pointer for block %u in directory inode %llu\n" msgstr "" "falscher Geschwister-Rückwärts-Zeiger für Block %u in\n" "Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:2004 #, c-format msgid "block %llu for directory inode %llu is missing\n" msgstr "Block %llu für Verzeichnis-Inode %llu fehlt\n" #: .././repair/dir2.c:2013 #, c-format msgid "can't read block %llu for directory inode %llu\n" msgstr "Block %llu für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/dir2.c:2020 #, c-format msgid "" "bad directory block magic # %#x in block %llu for directory inode %llu\n" msgstr "" "falsches Verzeichnisblatt magische # %#x in Block %llu für\n" "Verzeichnis-Inode %llu\n" #: .././repair/dir2.c:2098 #, c-format msgid "bad size/format for directory %llu\n" msgstr "falsche Größe/Format für Verzeichnis %llu\n" #: .././repair/init.c:42 msgid "ts_alloc: cannot allocate thread specific storage\n" msgstr "ts_alloc: Thread-spezifischer Speicher kann nicht zugewiesen werden\n" #: .././repair/init.c:94 #, c-format msgid "getrlimit(RLIMIT_FSIZE) failed!\n" msgstr "getrlimit(RLIMIT_FSIZE) fehlgeschlagen!\n" #: .././repair/init.c:102 #, c-format msgid "setrlimit failed - current: %lld, max: %lld\n" msgstr "setrlimit fehlgeschlagen - aktuell: %lld, max: %lld\n" #: .././repair/init.c:149 msgid "couldn't initialize XFS library\n" msgstr "XFS-Bibliothek kann nicht initialisiert werden\n" #: .././repair/incore.c:38 msgid "couldn't allocate block map pointers\n" msgstr "Blockkarten-Zeiger können nicht alloziert werden\n" #: .././repair/incore.c:41 msgid "couldn't allocate block map locks\n" msgstr "Blockkarten-Sperren können nicht alloziert werden\n" #: .././repair/incore.c:49 #, c-format msgid "couldn't allocate block map, size = %d\n" msgstr "Blockkarten kann nicht alloziert werden, Größe = %d\n" #: .././repair/incore.c:67 #, c-format msgid "couldn't allocate realtime block map, size = %llu\n" msgstr "Echtzeit-Blockkarten können nicht alloziert werden, Größe = %llu\n" #: .././repair/dinode.c:70 msgid "Unknown inode format.\n" msgstr "Unbekanntes Inodeformat.\n" #: .././repair/dinode.c:87 #, c-format msgid "clearing inode %llu attributes\n" msgstr "Attribute des Inodes %llu werden bereinigt\n" #: .././repair/dinode.c:90 #, c-format msgid "would have cleared inode %llu attributes\n" msgstr "Attribute des Inodes %llu könnten bereinigt worden sein\n" #: .././repair/dinode.c:493 #, c-format msgid "inode %llu - bad rt extent start block number %llu, offset %llu\n" msgstr "" "Inode %llu - falsche »rt«-Erweiterungs-Startblock-Nummer %llu,\n" "Versatz %llu\n" #: .././repair/dinode.c:499 #, c-format msgid "inode %llu - bad rt extent last block number %llu, offset %llu\n" msgstr "" "Inode %llu - falsche »rt«-Erweiterungs-Endblock-Nummer %llu,Versatz %llu\n" #: .././repair/dinode.c:505 #, c-format msgid "" "inode %llu - bad rt extent overflows - start %llu, end %llu, offset %llu\n" msgstr "" "Inode %llu - falsche »rt«-Erweiterungs-Überläufe - Start %llu,\n" "Ende %llu, Versatz %llu\n" #: .././repair/dinode.c:519 #, c-format msgid "malformed rt inode extent [%llu %llu] (fs rtext size = %u)\n" msgstr "" "missgebildete »rt«-Inode-Erweiterung [%llu %llu] (fs rtext Größe = %u)\n" #: .././repair/dinode.c:537 #, c-format msgid "" "data fork in rt ino %llu claims dup rt extent, off - %llu, start - %llu, " "count %llu\n" msgstr "" "Daten-Unterelement in rt ino %llu beansprucht »dup rt«-Erweiterung,aus - %" "llu, Start - %llu, Anzahl %llu\n" #: .././repair/dinode.c:557 #, c-format msgid "bad state in rt block map %llu\n" msgstr "falscher Status in »rt«-Block-Karte %llu\n" #: .././repair/dinode.c:563 #, c-format msgid "data fork in rt inode %llu found metadata block %llu in rt bmap\n" msgstr "" "Daten-Unterelement in rt ino %llu fand Metadaten-Block %llu in rt bmap\n" #: .././repair/dinode.c:573 #, c-format msgid "data fork in rt inode %llu claims used rt block %llu\n" msgstr "" "Daten-Unterelement in »rt«-Inode %llu beansprucht benutzten\n" "»rt«-Block %llu\n" #: .././repair/dinode.c:580 #, c-format msgid "illegal state %d in rt block map %llu\n" msgstr "unerlaubter Status %d in »rt«-Block-Karte %llu\n" #: .././repair/dinode.c:636 msgid "real-time" msgstr "Echtzeit" #: .././repair/dinode.c:638 msgid "regular" msgstr "regelmäßig" #: .././repair/dinode.c:647 #, c-format msgid "" "bmap rec out of order, inode %llu entry %d [o s c] [%llu %llu %llu], %d [%" "llu %llu %llu]\n" msgstr "" "bmap rec außer Betrieb, Inode %llu Eintrag %d [o s c] [%llu %llu %llu], %d [%" "llu %llu %llu]\n" #: .././repair/dinode.c:661 #, c-format msgid "zero length extent (off = %llu, fsbno = %llu) in ino %llu\n" msgstr "Länge-Null-Erweiterung (off = %llu, fsbno = %llu) in ino %llu\n" #: .././repair/dinode.c:690 #, c-format msgid "inode %llu - bad extent starting block number %llu, offset %llu\n" msgstr "Inode %llu - falsche erweiterte Startblock-Nummer %llu, Versatz %llu\n" #: .././repair/dinode.c:697 #, c-format msgid "inode %llu - bad extent last block number %llu, offset %llu\n" msgstr "Inode %llu - falsche erweiterte Endblock-Nummer %llu, Versatz %llu\n" #: .././repair/dinode.c:704 #, c-format msgid "inode %llu - bad extent overflows - start %llu, end %llu, offset %llu\n" msgstr "" "Inode %llu - falsche Erweiterungs-Überläufe - Start %llu, Ende %llu,\n" "Versatz %llu\n" #: .././repair/dinode.c:712 #, c-format msgid "" "inode %llu - extent offset too large - start %llu, count %llu, offset %llu\n" msgstr "" "Inode %llu - falsche Erweiterungs-Versatz zu groß - Start %llu,\n" "Anzahl %llu, Versatz %llu\n" #: .././repair/dinode.c:745 #, c-format msgid "" "%s fork in ino %llu claims dup extent, off - %llu, start - %llu, cnt %llu\n" msgstr "" "%s Unterelement in ino %llu beansprucht »dup«-Erweiterung, aus - %llu,\n" "Start - %llu, cnt %llu\n" #: .././repair/dinode.c:778 #, c-format msgid "%s fork in ino %llu claims free block %llu\n" msgstr "%s Unterelement in ino %llu beansprucht freien Block %llu\n" #: .././repair/dinode.c:787 #, c-format msgid "bad state in block map %llu\n" msgstr "falscher Status in Block-Karte %llu\n" #: .././repair/dinode.c:792 #, c-format msgid "%s fork in inode %llu claims metadata block %llu\n" msgstr "%s Unterelement in Inode %llu beansprucht Metadatenblock %llu\n" #: .././repair/dinode.c:800 #, c-format msgid "%s fork in %s inode %llu claims used block %llu\n" msgstr "%s Unterelement in %s Inode %llu beansprucht benutzten Block %llu\n" #: .././repair/dinode.c:806 #, c-format msgid "illegal state %d in block map %llu\n" msgstr "unerlaubter Status %d im Block-Karte %llu\n" #: .././repair/dinode.c:884 #, c-format msgid "cannot read inode (%u/%u), disk block %lld\n" msgstr "Inode (%u/%u) kann nicht gelesen werden, Plattenblock %lld\n" #: .././repair/dinode.c:995 .././repair/dinode.c:1052 #, c-format msgid "cannot read bmap block %llu\n" msgstr "»bmap«-Block %llu kann nicht gelesen werden\n" #: .././repair/dinode.c:1015 #, c-format msgid "# of bmap records in inode %llu exceeds max (%u, max - %u)\n" msgstr "" "# der »bmap«-Aufzeichnungen in Inode %llu überschreiten Maximum (%u,\n" "max - %u)\n" #: .././repair/dinode.c:1023 #, c-format msgid "" "- # of bmap records in inode %llu less than minimum (%u, min - %u), " "proceeding ...\n" msgstr "" "- # der »bmap«-Aufzeichnungen in Inode %llu weniger als das Minimum\n" "(%u, min - %u), fortsetzen ...\n" #: .././repair/dinode.c:1064 #, c-format msgid "# of bmap records in inode %llu greater than maximum (%u, max - %u)\n" msgstr "" "# der »bmap«-Aufzeichnungen in Inode %llu größer als das Maximum (%u, \n" "max - %u)\n" #: .././repair/dinode.c:1071 #, c-format msgid "" "- # of bmap records in inode %llu less than minimum (%u, min - %u), " "continuing...\n" msgstr "" "- # der »bmap«-Aufzeichnungen in Inode %llu weniger als das Minimum\n" "(%u, min - %u), fortfahren ...\n" #: .././repair/dinode.c:1088 #, c-format msgid "could not map block %llu\n" msgstr "Block %llu kann nicht kartiert werden\n" #: .././repair/dinode.c:1122 #, c-format msgid "get_bmapi() called for local inode %llu\n" msgstr "get_bmapi() für lokalen Inode %llu aufgerufen\n" #: .././repair/dinode.c:1130 #, c-format msgid "bad inode format for inode %llu\n" msgstr "falsches Inode-Format für Inode %llu\n" #: .././repair/dinode.c:1194 #, c-format msgid "bad level %d in inode %llu bmap btree root block\n" msgstr "falsche Stufe %d im Inode-%llu-»bmap btree«-Wurzelblock\n" #: .././repair/dinode.c:1199 #, c-format msgid "bad numrecs 0 in inode %llu bmap btree root block\n" msgstr "falsche numrecs 0 im Inode-%llu-»bmap btree«-Wurzelblock\n" #: .././repair/dinode.c:1208 #, c-format msgid "" "indicated size of %s btree root (%d bytes) greater than space in inode %llu %" "s fork\n" msgstr "" "angegebene Größe der »%s-btree«-Wurzel (%d Bytes) größer als Platz in Inode %" "llu %s Unterelement\n" #: .././repair/dinode.c:1247 #, c-format msgid "" "correcting key in bmbt root (was %llu, now %llu) in inode %llu %s fork\n" msgstr "" "Schlüssel in »bmbt«-Wurzel wird korrigiert (war %llu, nun %llu) in Inode\n" "%llu %s Unterelement\n" #: .././repair/dinode.c:1258 #, c-format msgid "" "bad key in bmbt root (is %llu, would reset to %llu) in inode %llu %s fork\n" msgstr "" "falscher Schlüssel in »bmbt«-Wurzel (ist %llu, könnte zu %llu\n" "zurückgesetzt werden) in Inode %llu %s Unterelement\n" #: .././repair/dinode.c:1274 #, c-format msgid "out of order bmbt root key %llu in inode %llu %s fork\n" msgstr "" "»bmbt«-Wurzel-Schlüssel %llu außer Betrieb in Inode %llu\n" "%s Unterelement\n" #: .././repair/dinode.c:1302 #, c-format msgid "bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n" msgstr "" "falscher fwd (rechts) Geschwisterzeiger (%llu gesehen könnte NULLDFSBNO\n" "sein)\n" #: .././repair/dinode.c:1305 #, c-format msgid "\tin inode %u (%s fork) bmap btree block %llu\n" msgstr "\tin Inode %u (%s-Unterelement) bmap btree Block %llu\n" #: .././repair/dinode.c:1373 #, c-format msgid "local inode %llu data fork is too large (size = %lld, max = %d)\n" msgstr "" "lokales Inode-%llu-Daten-Unterelement ist zu groß (Größe = %lld, max = %d)\n" #: .././repair/dinode.c:1381 #, c-format msgid "local inode %llu attr fork too large (size %d, max = %d)\n" msgstr "" "lokales Inode-%llu-attr-Unterelement ist zu groß (Größe = %d, max = %d)\n" #: .././repair/dinode.c:1388 #, c-format msgid "local inode %llu attr too small (size = %d, min size = %d)\n" msgstr "" "lokales Inode-%llu-attr-Unterelement ist zu klein (Größe = %d, min = %d)\n" #: .././repair/dinode.c:1411 #, c-format msgid "mismatch between format (%d) and size (%lld) in symlink ino %llu\n" msgstr "" "Ungleichheit zwischen Format (%d) und Größe (%lld) in symbolischer\n" "Verknüpfung ino %llu\n" #: .././repair/dinode.c:1417 #, c-format msgid "mismatch between format (%d) and size (%lld) in symlink inode %llu\n" msgstr "" "Ungleichheit zwischen Format (%d) und Größe (%lld) in symbolischer\n" "Verknüpfung Inode %llu\n" #: .././repair/dinode.c:1432 #, c-format msgid "bad number of extents (%d) in symlink %llu data fork\n" msgstr "" "falsche Anzahl von Ausweitungen (%d) in symbolischem Verweis %llu\n" "des Datenunterelements\n" #: .././repair/dinode.c:1445 #, c-format msgid "bad extent #%d offset (%llu) in symlink %llu data fork\n" msgstr "" "falscher Umfang #%d Versatz (%llu) in symbolischem Verweis %llu\n" "des Datenunterelements\n" #: .././repair/dinode.c:1451 #, c-format msgid "bad extent #%d count (%llu) in symlink %llu data fork\n" msgstr "" "falsche Umfang #%d Anzahl (%llu) in symbolischem Verweis %llu des\n" "Datenunterelements\n" #: .././repair/dinode.c:1507 #, c-format msgid "symlink in inode %llu too long (%lld chars)\n" msgstr "symbolischer Verweis in Inode %llu zu lang (%lld Zeichen)\n" #: .././repair/dinode.c:1540 #, c-format msgid "cannot read inode %llu, file block %d, disk block %llu\n" msgstr "" "Inode %llu kann nicht gelesen werden, Dateiblock %d, Plattenblock %llu\n" #: .././repair/dinode.c:1562 #, c-format msgid "found illegal null character in symlink inode %llu\n" msgstr "" "unerlaubtes Null-Zeichen gefunden in symbolischem Verweis zu Inode %llu\n" #: .././repair/dinode.c:1576 .././repair/dinode.c:1586 #, c-format msgid "component of symlink in inode %llu too long\n" msgstr "Bestandteil des symbolischen Verweises in Inode %llu zu lang\n" #: .././repair/dinode.c:1611 #, c-format msgid "inode %llu has bad inode type (IFMNT)\n" msgstr "Inode %llu hat falschen Inode-Typ (IFMNT)\n" #: .././repair/dinode.c:1621 #, c-format msgid "size of character device inode %llu != 0 (%lld bytes)\n" msgstr "" "Größe des Inodes %llu des zeichenorientierten Gerätes !=0 (%lld Bytes)\n" #: .././repair/dinode.c:1626 #, c-format msgid "size of block device inode %llu != 0 (%lld bytes)\n" msgstr "Größe des Inodes %llu des blockorientierten Gerätes !=0 (%lld Bytes)\n" #: .././repair/dinode.c:1631 #, c-format msgid "size of socket inode %llu != 0 (%lld bytes)\n" msgstr "Größe des Socket-Inodes %llu !=0 (%lld Bytes)\n" #: .././repair/dinode.c:1636 #, c-format msgid "size of fifo inode %llu != 0 (%lld bytes)\n" msgstr "Größe des fifo-Inodes %llu !=0 (%lld Bytes)\n" #: .././repair/dinode.c:1641 #, c-format msgid "Internal error - process_misc_ino_types, illegal type %d\n" msgstr "Interner Fehler - process_misc_ino_types, unerlaubter Typ %d\n" #: .././repair/dinode.c:1668 #, c-format msgid "size of character device inode %llu != 0 (%llu blocks)\n" msgstr "" "Größe des Inodes %llu des zeichenorientierten Gerätes !=0 (%llu Bytes)\n" #: .././repair/dinode.c:1673 #, c-format msgid "size of block device inode %llu != 0 (%llu blocks)\n" msgstr "Größe des Inodes %llu des blockorientierten Gerätes !=0 (%llu Bytes)\n" #: .././repair/dinode.c:1678 #, c-format msgid "size of socket inode %llu != 0 (%llu blocks)\n" msgstr "Größe des Socket-Inodes %llu !=0 (%llu Bytes)\n" #: .././repair/dinode.c:1683 #, c-format msgid "size of fifo inode %llu != 0 (%llu blocks)\n" msgstr "Größe des fifo-Inodes %llu !=0 (%llu Bytes)\n" #: .././repair/dinode.c:1761 #, c-format msgid "root inode %llu has bad type 0x%x\n" msgstr "Wurzel-Inode %llu hat falschen Typ 0x%x\n" #: .././repair/dinode.c:1765 msgid "resetting to directory\n" msgstr "Verzeichnis wird zurückgesetzt\n" #: .././repair/dinode.c:1769 msgid "would reset to directory\n" msgstr "Verzeichnis könnte zurückgesetzt werden\n" #: .././repair/dinode.c:1775 #, c-format msgid "user quota inode %llu has bad type 0x%x\n" msgstr "Benutzer-Quota-Inode %llu hat falschen Typ 0x%x\n" #: .././repair/dinode.c:1784 #, c-format msgid "group quota inode %llu has bad type 0x%x\n" msgstr "Gruppen-Quota-Inode %llu hat falschen Typ 0x%x\n" #: .././repair/dinode.c:1793 #, c-format msgid "realtime summary inode %llu has bad type 0x%x, " msgstr "Echtzeit-Summen-Inode %llu hat falschen Typ 0x%x, " #: .././repair/dinode.c:1796 .././repair/dinode.c:1815 msgid "resetting to regular file\n" msgstr "es wird auf normale Datei zurückgesetzt\n" #: .././repair/dinode.c:1800 .././repair/dinode.c:1819 msgid "would reset to regular file\n" msgstr "es könnte auf normale Datei zurückgesetzt werden\n" #: .././repair/dinode.c:1804 #, c-format msgid "bad # of extents (%u) for realtime summary inode %llu\n" msgstr "falsche # des Umfangs (%u) für Echtzeit-Summen-Inode %llu\n" #: .././repair/dinode.c:1812 #, c-format msgid "realtime bitmap inode %llu has bad type 0x%x, " msgstr "Echtzeit-Bitmap-Inode %llu hat falschen Typ 0x%x, " #: .././repair/dinode.c:1823 #, c-format msgid "bad # of extents (%u) for realtime bitmap inode %llu\n" msgstr "falsche # von Extents (%u) für Echtzeit-Bitmap-Inode %llu\n" #: .././repair/dinode.c:1858 #, c-format msgid "mismatch between format (%d) and size (%lld) in directory ino %llu\n" msgstr "" "Unterschied zwischen Format (%d) und Größe (%lld) im Verzeichnis ino %llu\n" #: .././repair/dinode.c:1864 #, c-format msgid "directory inode %llu has bad size %lld\n" msgstr "Verzeichnis-Inode %llu hat falsche Größe %lld\n" #: .././repair/dinode.c:1872 #, c-format msgid "bad data fork in symlink %llu\n" msgstr "falsches Daten-Unterelement in symbolischem Verweis %llu\n" #: .././repair/dinode.c:1892 #, c-format msgid "found inode %llu claiming to be a real-time file\n" msgstr "gefundener Inode %llu beansprucht, eine Echtzeit-Datei zu sein\n" #: .././repair/dinode.c:1901 #, c-format msgid "realtime bitmap inode %llu has bad size %lld (should be %lld)\n" msgstr "Echtzeit-Bitmap-Inode %llu hat falsche Größe %lld (sollte %lld sein)\n" #: .././repair/dinode.c:1911 #, c-format msgid "realtime summary inode %llu has bad size %lld (should be %d)\n" msgstr "Echtzeit-Summen-Inode %llu hat falsche Größe %lld (könnte %d sein)\n" #: .././repair/dinode.c:1939 #, c-format msgid "bad attr fork offset %d in dev inode %llu, should be %d\n" msgstr "" "falscher attr-Unterelement-Versatz %d in dev-Inode %llu, könnte %d sein\n" #: .././repair/dinode.c:1949 #, c-format msgid "bad attr fork offset %d in inode %llu, max=%d\n" msgstr "falscher attr-Unterelement-Versatz %d in Inode %llu, maximal=%d\n" #: .././repair/dinode.c:1956 #, c-format msgid "unexpected inode format %d\n" msgstr "unerwartetes Inode-Format %d\n" #: .././repair/dinode.c:1976 #, c-format msgid "correcting nblocks for inode %llu, was %llu - counted %llu\n" msgstr "nblocks für Inode %llu werden korrigiert, war %llu - gezählt %llu\n" #: .././repair/dinode.c:1982 #, c-format msgid "bad nblocks %llu for inode %llu, would reset to %llu\n" msgstr "" "falsche nblocks %llu für Inode %llu, könnte auf %llu zurückgesetzt werden\n" #: .././repair/dinode.c:1989 #, c-format msgid "too many data fork extents (%llu) in inode %llu\n" msgstr "zu großes Daten-Unterelement-Ausmaß (%llu) in Inode %llu\n" #: .././repair/dinode.c:1995 #, c-format msgid "correcting nextents for inode %llu, was %d - counted %llu\n" msgstr "nextents für Inode %llu werden korrigiert, waren %d - gezählt %llu\n" #: .././repair/dinode.c:2001 #, c-format msgid "bad nextents %d for inode %llu, would reset to %llu\n" msgstr "" "falsche nextents %d für Inode %llu, könnten auf %llu zurückgesetzt\n" "werden\n" #: .././repair/dinode.c:2008 #, c-format msgid "too many attr fork extents (%llu) in inode %llu\n" msgstr "zu großes Daten-Unterelement-Ausmaß (%llu) in Inode %llu\n" #: .././repair/dinode.c:2014 #, c-format msgid "correcting anextents for inode %llu, was %d - counted %llu\n" msgstr "anextents für Inode %llu werden korrigiert, waren %d - gezählt %llu\n" #: .././repair/dinode.c:2020 #, c-format msgid "bad anextents %d for inode %llu, would reset to %llu\n" msgstr "" "falsche anextents %d für Inode %llu, könnten auf %llu zurückgesetzt\n" "werden\n" #: .././repair/dinode.c:2075 .././repair/dinode.c:2113 #, c-format msgid "unknown format %d, ino %llu (mode = %d)\n" msgstr "unbekanntes Format %d, ino %llu (Modus = %d)\n" #: .././repair/dinode.c:2080 #, c-format msgid "bad data fork in inode %llu\n" msgstr "falsches Daten-Unterelement in Inode %llu\n" #: .././repair/dinode.c:2152 #, c-format msgid "bad attribute format %d in inode %llu, " msgstr "falsches Attribut-Format %d in Inode %llu, " #: .././repair/dinode.c:2155 msgid "resetting value\n" msgstr "Wert wird zurückgesetzt\n" #: .././repair/dinode.c:2159 msgid "would reset value\n" msgstr "Wert könnte zurückgesetzt werden\n" #: .././repair/dinode.c:2189 .././repair/attr_repair.c:977 #, c-format msgid "illegal attribute format %d, ino %llu\n" msgstr "unerlaubtes Attributs-Format %d, ino %llu\n" #: .././repair/dinode.c:2204 #, c-format msgid "bad attribute fork in inode %llu" msgstr "falsches Attribut-Unterelement in Inode %llu" #: .././repair/dinode.c:2208 msgid ", clearing attr fork\n" msgstr ", bereinige attr-Unterelement\n" #: .././repair/dinode.c:2217 msgid ", would clear attr fork\n" msgstr ", könnte attr-Unterelement bereinigen\n" #: .././repair/dinode.c:2245 #, c-format msgid "illegal attribute fmt %d, ino %llu\n" msgstr "unerlaubtes Attribut fmt %d, ino %llu\n" #: .././repair/dinode.c:2264 #, c-format msgid "problem with attribute contents in inode %llu\n" msgstr "Problem mit Attributs-Inhalt in Inode %llu\n" #: .././repair/dinode.c:2272 msgid "would clear attr fork\n" msgstr "könnte attr-Unterelement bereinigen\n" #: .././repair/dinode.c:2314 #, c-format msgid "version 2 inode %llu claims > %u links, " msgstr "Version 2 Inode %llu beansprucht > %u Verweise, " #: .././repair/dinode.c:2317 msgid "updating superblock version number\n" msgstr "Superblock-Versionsnummer wird aktualisiert\n" #: .././repair/dinode.c:2320 msgid "would update superblock version number\n" msgstr "Superblock-Versionsnummer könnte aktualisiert werden\n" #: .././repair/dinode.c:2328 #, c-format msgid "WARNING: version 2 inode %llu claims > %u links, " msgstr "WARNUNG: Version 2 Inode %llu beansprucht > %u Verweise, " #: .././repair/dinode.c:2332 #, c-format msgid "" "converting back to version 1,\n" "this may destroy %d links\n" msgstr "" "es wird zu Version 1 zurück umgewandelt,\n" "das kann %d Verweise zerstören\n" #: .././repair/dinode.c:2342 #, c-format msgid "" "would convert back to version 1,\n" "\tthis might destroy %d links\n" msgstr "" "es könnte zu Version 1 zurück umgewandelt werden,\n" "\tdas könnte %d Verweise zerstören\n" #: .././repair/dinode.c:2357 #, c-format msgid "found version 2 inode %llu, " msgstr "Version-2-Inode %llu gefunden, " #: .././repair/dinode.c:2359 msgid "converting back to version 1\n" msgstr "wird zu Version 1 zurück verwandelt\n" #: .././repair/dinode.c:2365 msgid "would convert back to version 1\n" msgstr "es könnte zu Version 1 zurück umgewandelt werden\n" #: .././repair/dinode.c:2378 #, c-format msgid "clearing obsolete nlink field in version 2 inode %llu, was %d, now 0\n" msgstr "" "überflüssiges nlink-Feld in Version-2-Inode %llu wurde bereinigt, war %d,\n" "nun 0\n" #: .././repair/dinode.c:2384 #, c-format msgid "" "would clear obsolete nlink field in version 2 inode %llu, currently %d\n" msgstr "" "überflüssiges nlink-Feld in Version-2-Inode %llu könnte bereinigt werden,\n" "aktuell %d\n" #: .././repair/dinode.c:2457 #, c-format msgid "bad magic number 0x%x on inode %llu%c" msgstr "falsche magische Nummer 0x%x auf Inode %llu%c" #: .././repair/dinode.c:2462 msgid " resetting magic number\n" msgstr " magische Nummer wird zurückgesetzt\n" #: .././repair/dinode.c:2466 msgid " would reset magic number\n" msgstr " magische Nummer würde zurückgesetzt\n" #: .././repair/dinode.c:2474 #, c-format msgid "bad version number 0x%x on inode %llu%c" msgstr "falsche Versionsnummer 0x%x auf Inode %llu%c" #: .././repair/dinode.c:2479 msgid " resetting version number\n" msgstr " Versionsnummer wird zurückgesetzt\n" #: .././repair/dinode.c:2485 msgid " would reset version number\n" msgstr " Versionsnummer könnte zurückgesetzt werden\n" #: .././repair/dinode.c:2494 #, c-format msgid "bad (negative) size %lld on inode %llu\n" msgstr "falsche (negative) Größe %lld auf Inode %llu\n" #: .././repair/dinode.c:2525 #, c-format msgid "imap claims a free inode %llu is in use, " msgstr "imap beansprucht einen freien Inode, %llu ist in Benutzung" #: .././repair/dinode.c:2527 msgid "correcting imap and clearing inode\n" msgstr "imap wird korrigiert und Inode bereinigt\n" #: .././repair/dinode.c:2531 msgid "would correct imap and clear inode\n" msgstr "imap könnte korrigiert und Inode bereinigt werden\n" #: .././repair/dinode.c:2547 #, c-format msgid "bad inode format in inode %llu\n" msgstr "falsches Inode-Format in Inode %llu\n" #: .././repair/dinode.c:2600 #, c-format msgid "bad inode type %#o inode %llu\n" msgstr "falscher Inode-Typ %#o Inode %llu\n" #: .././repair/dinode.c:2623 #, c-format msgid "bad non-zero extent size %u for non-realtime/extsize inode %llu, " msgstr "falsches Nicht-Null-Ausmaß %u für Nicht-Echtzeit/extsize Inode %llu, " #: .././repair/dinode.c:2627 msgid "resetting to zero\n" msgstr "wird auf Null zurückgesetzt\n" #: .././repair/dinode.c:2631 msgid "would reset to zero\n" msgstr "könnte auf Null zurückgesetzt werden\n" #: .././repair/dinode.c:2686 #, c-format msgid "problem with directory contents in inode %llu\n" msgstr "Problem mit Verzeichnis-Inhalt in Inode %llu\n" #: .././repair/dinode.c:2693 #, c-format msgid "problem with symbolic link in inode %llu\n" msgstr "Problem mit symbolischem Verweis in Inode %llu\n" #: .././repair/dinode.c:2790 #, c-format msgid "processing inode %d/%d\n" msgstr "Inode %d/%d wird verarbeitet\n" #: .././repair/agheader.c:35 #, c-format msgid "bad magic # 0x%x for agf %d\n" msgstr "flasche magische # 0x%x für agf %d\n" #: .././repair/agheader.c:44 #, c-format msgid "bad version # %d for agf %d\n" msgstr "falsche Version # %d für agf %d\n" #: .././repair/agheader.c:53 #, c-format msgid "bad sequence # %d for agf %d\n" msgstr "falsche Sequenz # %d für agf %d\n" #: .././repair/agheader.c:63 #, c-format msgid "bad length %d for agf %d, should be %d\n" msgstr "falsche Länge %d für agf %d, könnte %d sein\n" #: .././repair/agheader.c:76 #, c-format msgid "bad length %d for agf %d, should be %llu\n" msgstr "falsche Länge %d für agf %d, könnte %llu sein\n" #: .././repair/agheader.c:90 #, c-format msgid "flfirst %d in agf %d too large (max = %d)\n" msgstr "flfirst %d in agf %d zu groß (Maximum = %d)\n" #: .././repair/agheader.c:97 #, c-format msgid "fllast %d in agf %d too large (max = %d)\n" msgstr "fllast %d in agf %d zu groß (Maximum = %d)\n" #: .././repair/agheader.c:118 #, c-format msgid "bad magic # 0x%x for agi %d\n" msgstr "falsche magische # 0x%x für agi %d\n" #: .././repair/agheader.c:127 #, c-format msgid "bad version # %d for agi %d\n" msgstr "falsche Version # %d für agi %d\n" #: .././repair/agheader.c:136 #, c-format msgid "bad sequence # %d for agi %d\n" msgstr "falsche Sequenz # %d für agi %d\n" #: .././repair/agheader.c:146 #, c-format msgid "bad length # %d for agi %d, should be %d\n" msgstr "falsche Länge %d für agi %d, könnte %d sein\n" #: .././repair/agheader.c:159 #, c-format msgid "bad length # %d for agi %d, should be %llu\n" msgstr "falsche Länge %d für agi %d, könnte %llu sein\n" #: .././repair/agheader.c:270 #, c-format msgid "zeroing unused portion of %s superblock (AG #%u)\n" msgstr "ungenutzten Anteil des »%s«-Superblocks nullen (AG #%u)\n" #: .././repair/agheader.c:271 .././repair/agheader.c:277 msgid "primary" msgstr "primär" #: .././repair/agheader.c:271 .././repair/agheader.c:277 msgid "secondary" msgstr "sekundär" #: .././repair/agheader.c:276 #, c-format msgid "would zero unused portion of %s superblock (AG #%u)\n" msgstr "" "ungenutzter Anteil des »%s«-Superblocks sollte genullt werden (AG #%u)\n" #: .././repair/agheader.c:295 #, c-format msgid "bad flags field in superblock %d\n" msgstr "falsches Kennzeichnungsfeld im Superblock %d\n" #: .././repair/agheader.c:312 #, c-format msgid "non-null user quota inode field in superblock %d\n" msgstr "Benutzer-Quota-Inode-Feld im Superblock %d nicht Null\n" #: .././repair/agheader.c:325 #, c-format msgid "non-null group quota inode field in superblock %d\n" msgstr "Gruppen-Quota-Inode-Feld im Superblock %d nicht Null\n" #: .././repair/agheader.c:337 #, c-format msgid "non-null quota flags in superblock %d\n" msgstr "Quota-Markierungen im Superblock %d nicht Null\n" #: .././repair/agheader.c:355 #, c-format msgid "bad shared version number in superblock %d\n" msgstr "falsche geteilte Versionsnummer im Superblock %d\n" #: .././repair/agheader.c:367 #, c-format msgid "bad inode alignment field in superblock %d\n" msgstr "falsches Inode-Ausrichtungs-Feld im Superblock %d\n" #: .././repair/agheader.c:380 #, c-format msgid "bad stripe unit/width fields in superblock %d\n" msgstr "falsche Stripe-Einheit/Breite Felder in Superblock %d\n" #: .././repair/agheader.c:398 #, c-format msgid "bad log/data device sector size fields in superblock %d\n" msgstr "falsche Protokoll/Daten-Gerät-Sektorenfeldgröße im Superblock %d\n" #: .././repair/agheader.c:429 #, c-format msgid "bad on-disk superblock %d - %s\n" msgstr "falscher on-disk-Superblock %d - %s\n" #: .././repair/agheader.c:436 #, c-format msgid "primary/secondary superblock %d conflict - %s\n" msgstr "primäre/sekundärer Superblock-%d-Konflikt - %s\n" #: .././repair/dino_chunks.c:59 #, c-format msgid "cannot read agbno (%u/%u), disk block %lld\n" msgstr "agbno (%u/%u) kann nicht gelesen werden, Plattenblock %lld\n" #: .././repair/dino_chunks.c:157 #, c-format msgid "uncertain inode block %d/%d already known\n" msgstr "unsicherer Inode-Block %d/%d bereits bekannt\n" #: .././repair/dino_chunks.c:173 .././repair/dino_chunks.c:443 #: .././repair/dino_chunks.c:505 #, c-format msgid "inode block %d/%d multiply claimed, (state %d)\n" msgstr "Inode-Block %d/%d mehrfach beansprucht, (Status %d)\n" #: .././repair/dino_chunks.c:180 .././repair/dino_chunks.c:510 #, c-format msgid "inode block %d/%d bad state, (state %d)\n" msgstr "Inode-Block %d/%d Status schlecht, (Status %d)\n" #: .././repair/dino_chunks.c:450 #, c-format msgid "uncertain inode block overlap, agbno = %d, ino = %llu\n" msgstr "unsichere Inode-Block-Überschneidung, agbno = %d, ino = %llu\n" #: .././repair/dino_chunks.c:492 #, c-format msgid "uncertain inode block %llu already known\n" msgstr "unsicherer Inode-Block %llu bereits bekannt\n" #: .././repair/dino_chunks.c:628 #, c-format msgid "failed to allocate %d bytes of memory\n" msgstr "%d Bytes Speicher zu allozieren fehlgeschlagen\n" #: .././repair/dino_chunks.c:640 #, c-format msgid "cannot read inode %llu, disk block %lld, cnt %d\n" msgstr "Inode %llu kann nicht gelesen werden, Plattenblock %lld, cnt %d\n" #: .././repair/dino_chunks.c:757 .././repair/dino_chunks.c:938 #: .././repair/phase3.c:74 #, c-format msgid "bad state in block map %d\n" msgstr "falscher Status in Block-Kartierung %d\n" #: .././repair/dino_chunks.c:761 .././repair/dino_chunks.c:943 #, c-format msgid "inode block %llu multiply claimed, state was %d\n" msgstr "Inode-Block %llu mehrfach beansprucht, Status war %d\n" #: .././repair/dino_chunks.c:796 #, c-format msgid "imap claims in-use inode %llu is free, " msgstr "von imap in Benutzung beanspruchter Inode %llu ist frei, " #: .././repair/dino_chunks.c:803 msgid "correcting imap\n" msgstr "imap wird korrigiert\n" #: .././repair/dino_chunks.c:805 msgid "would correct imap\n" msgstr "imap könnte korrigiert werden\n" #: .././repair/dino_chunks.c:851 #, c-format msgid "cleared root inode %llu\n" msgstr "bereinigter Wurzel-Inode %llu\n" #: .././repair/dino_chunks.c:855 #, c-format msgid "would clear root inode %llu\n" msgstr "könnte Wurzel-Inode %llu bereinigen\n" #: .././repair/dino_chunks.c:864 #, c-format msgid "cleared realtime bitmap inode %llu\n" msgstr "geleerter Echtzeit-Bitmap-Inode %llu\n" #: .././repair/dino_chunks.c:869 #, c-format msgid "would clear realtime bitmap inode %llu\n" msgstr "würde Echtzeit-Bitmap-Inode %llu leeren\n" #: .././repair/dino_chunks.c:879 #, c-format msgid "cleared realtime summary inode %llu\n" msgstr "bereinigter Echtzeit-Zusammenfassungs-Inode %llu\n" #: .././repair/dino_chunks.c:884 #, c-format msgid "would clear realtime summary inode %llu\n" msgstr "könnte Echtzeit-Zusammenfassungs-Inode %llu bereinigen\n" #: .././repair/dino_chunks.c:890 #, c-format msgid "cleared inode %llu\n" msgstr "bereinigter Inode %llu\n" #: .././repair/dino_chunks.c:893 #, c-format msgid "would have cleared inode %llu\n" msgstr "Inode %llu könnte bereinigt worden sein\n" #: .././repair/dino_chunks.c:1099 .././repair/dino_chunks.c:1134 #: .././repair/dino_chunks.c:1248 msgid "found inodes not in the inode allocation tree\n" msgstr "Inodes wurden nicht im Inode-Allokierungs-Baum gefunden\n" #: .././repair/phase3.c:117 #, c-format msgid "cannot read agi block %lld for ag %u\n" msgstr "agi-Block %lld für ag %u kann nicht gelesen werden\n" #: .././repair/phase3.c:139 #, c-format msgid "error following ag %d unlinked list\n" msgstr "Fehler folgt ag %d unverknüpfter Liste\n" #: .././repair/phase3.c:211 msgid "Phase 3 - for each AG...\n" msgstr "Phase 3 - für jedes AG...\n" #: .././repair/phase3.c:213 msgid " - scan and clear agi unlinked lists...\n" msgstr " - agi unverknüpfte Listen werden gescannt und bereinigt...\n" #: .././repair/phase3.c:215 msgid " - scan (but don't clear) agi unlinked lists...\n" msgstr "" " - agi unverknüpfte Listen werden gescannt (aber nicht bereinigt...\n" #: .././repair/phase3.c:235 msgid " - process known inodes and perform inode discovery...\n" msgstr "" " - bekannte Inodes werden behandelt und Inode-Entdeckung wird\n" "durchgeführt...\n" #: .././repair/phase3.c:246 msgid " - process newly discovered inodes...\n" msgstr " - neu entdeckte Inodes werden behandelt...\n" #: .././repair/phase6.c:63 #, c-format msgid "malloc failed add_dotdot_update (%u bytes)\n" msgstr "malloc fehlgeschlagen add_dotdot_update (%u Bytes)\n" #: .././repair/phase6.c:174 #, c-format msgid "malloc failed in dir_hash_add (%u bytes)\n" msgstr "malloc fehlgeschlagen in dir_hash_add (%u Bytes)\n" #: .././repair/phase6.c:228 msgid "ok" msgstr "ok" #: .././repair/phase6.c:229 msgid "duplicate leaf" msgstr "doppeltes Blatt" #: .././repair/phase6.c:230 msgid "hash value mismatch" msgstr "Hash-Wert stimmt nicht überein" #: .././repair/phase6.c:231 msgid "no data entry" msgstr "kein Dateneintrag" #: .././repair/phase6.c:232 msgid "no leaf entry" msgstr "kein Blatteintrag" #: .././repair/phase6.c:233 msgid "bad stale count" msgstr "falsche Stale-Anzahl" #: .././repair/phase6.c:241 #, c-format msgid "bad hash table for directory inode %llu (%s): " msgstr "falsche Hash-Tabelle für Verzeichnis-Inode %llu (%s): " #: .././repair/phase6.c:244 msgid "rebuilding\n" msgstr "erneut bilden\n" #: .././repair/phase6.c:246 msgid "would rebuild\n" msgstr "könnte erneut bilden\n" #: .././repair/phase6.c:282 msgid "calloc failed in dir_hash_init\n" msgstr "calloc fehlgeschlagen in dir_hash_init\n" #: .././repair/phase6.c:412 msgid "ran out of disk space!\n" msgstr "lief außerhalb des Plattenplatzes!\n" #: .././repair/phase6.c:414 #, c-format msgid "xfs_trans_reserve returned %d\n" msgstr "xfs_trans_reserve zurückgegeben %d\n" #: .././repair/phase6.c:443 .././repair/phase6.c:536 #, c-format msgid "couldn't iget realtime bitmap inode -- error - %d\n" msgstr "" "iget für Echtezeit-Bitmap-Inode konnte nicht ausgeführt werden --\n" "Fehler - %d\n" #: .././repair/phase6.c:493 #, c-format msgid "couldn't allocate realtime bitmap, error = %d\n" msgstr "Echtzeit-Bitmap kann nicht alloziert werden, Fehler = %d\n" #: .././repair/phase6.c:506 #, c-format msgid "allocation of the realtime bitmap failed, error = %d\n" msgstr "Allokation des Echtzeit-Bitmaps fehlgeschlagen, Fehler = %d\n" #: .././repair/phase6.c:549 #, c-format msgid "couldn't map realtime bitmap block %llu, error = %d\n" msgstr "Echtzeit-Bitmap-Block %llu kann nicht kartiert werden, Fehler = %d\n" #: .././repair/phase6.c:562 #, c-format msgid "can't access block %llu (fsbno %llu) of realtime bitmap inode %llu\n" msgstr "" "auf Block %llu (fsbno %llu) des Echtzeit-Bitmap-Inodes %llu kann nicht\n" "zugegriffen werden.\n" #: .././repair/phase6.c:605 .././repair/phase6.c:676 #, c-format msgid "couldn't iget realtime summary inode -- error - %d\n" msgstr "" "iget für Echtezeit-Zusammenfassungs-Inode konnte nicht ausgeführt werden\n" "-- Fehler - %d\n" #: .././repair/phase6.c:618 #, c-format msgid "couldn't map realtime summary inode block %llu, error = %d\n" msgstr "" "Echtzeit-Zusammenfassungs-Inode-Block %llu kann nicht kartiert werden,\n" "Fehler = %d\n" #: .././repair/phase6.c:631 #, c-format msgid "can't access block %llu (fsbno %llu) of realtime summary inode %llu\n" msgstr "" "auf Block %llu (fsbno %llu) des Echtzeit-Zusammenfassungs-Inodes %llu\n" "kann nicht zugegriffen werden.\n" #: .././repair/phase6.c:732 #, c-format msgid "couldn't allocate realtime summary inode, error = %d\n" msgstr "" "Echtzeit-Zusammenfassungs-Inode kann nicht alloziert werden, Fehler = %d\n" #: .././repair/phase6.c:745 #, c-format msgid "allocation of the realtime summary ino failed, error = %d\n" msgstr "" "Allokation des Echtzeit-Zusammenfassungs-ino fehlgeschlagen, Fehler = %d\n" #: .././repair/phase6.c:775 #, c-format msgid "could not iget root inode -- error - %d\n" msgstr "iget für Wurzel-Inode konnte nicht ausgeführt werden -- Fehler - %d\n" #: .././repair/phase6.c:843 #, c-format msgid "%d - couldn't iget root inode to obtain %s\n" msgstr "" "%d - iget für Wurzel-Inode konnte nicht ausgeführt werden, um %s zu\n" "erhalten\n" #: .././repair/phase6.c:874 #, c-format msgid "%s inode allocation failed %d\n" msgstr "%s Inode-Allokation fehlgeschlagen %d\n" #: .././repair/phase6.c:892 #, c-format msgid "can't make %s, createname error %d\n" msgstr "%s kann nicht gemacht werden, createname-Fehler %d\n" #: .././repair/phase6.c:910 #, c-format msgid "%s directory creation failed -- bmapf error %d\n" msgstr "%s Verzeichnis erzeugen fehlgeschlagen -- bmapf Fehler %d\n" #: .././repair/phase6.c:953 #, c-format msgid "%d - couldn't iget orphanage inode\n" msgstr "%d - iget für verwaisten Inode konnte nicht ausgeführt werden\n" #: .././repair/phase6.c:966 #, c-format msgid "%d - couldn't iget disconnected inode\n" msgstr "%d - iget für getrennten Inode konnte nicht ausgeführt werden\n" #: .././repair/phase6.c:986 .././repair/phase6.c:1030 #: .././repair/phase6.c:1087 .././repair/phase6.c:1730 #, c-format msgid "space reservation failed (%d), filesystem may be out of space\n" msgstr "" "Platzreservierung fehlgeschlagen (%d), auf dem Dateisystem könnte kein\n" "Platz sein\n" #: .././repair/phase6.c:997 .././repair/phase6.c:1042 #: .././repair/phase6.c:1098 #, c-format msgid "name create failed in %s (%d), filesystem may be out of space\n" msgstr "" "Erzeugen des Namens fehlgeschlagen in %s (%d), auf dem Dateisystem\n" "könnte kein Platz sein\n" #: .././repair/phase6.c:1010 #, c-format msgid "creation of .. entry failed (%d), filesystem may be out of space\n" msgstr "" "Erzeugung von ..-Eintrag fehlgeschlagen (%d), auf dem Dateisystem könnte\n" "kein Platz sein\n" #: .././repair/phase6.c:1019 #, c-format msgid "bmap finish failed (err - %d), filesystem may be out of space\n" msgstr "" "Beenden von bmap fehlgeschlagen (err - %d), auf dem Dateisystem könnte\n" "kein Platz sein\n" #: .././repair/phase6.c:1061 #, c-format msgid "name replace op failed (%d), filesystem may be out of space\n" msgstr "" "op-Namen ersetzen fehlgeschlagen (%d), auf dem Dateisystem könnte kein\n" "Platz sein\n" #: .././repair/phase6.c:1068 .././repair/phase6.c:1108 #: .././repair/phase6.c:1753 #, c-format msgid "bmap finish failed (%d), filesystem may be out of space\n" msgstr "" "Beenden von bmap fehlgeschlagen (%d), auf dem Dateisystem könnte kein\n" "Platz sein\n" #: .././repair/phase6.c:1149 .././repair/phase6.c:1548 msgid "dir" msgstr "dir" #: .././repair/phase6.c:1158 .././repair/phase6.c:1162 #, c-format msgid "can't map block %d in %s inode %llu, xfs_bmapi returns %d, nmap = %d\n" msgstr "" "Block %d in %s Inode %llu kann nicht kartiert werden, xfs_bmapi gibt %d\n" "zurück, nmap = %d\n" #: .././repair/phase6.c:1170 .././repair/phase6.c:1173 #: .././repair/phase6.c:1626 .././repair/phase6.c:1630 #, c-format msgid "block %d in %s ino %llu doesn't exist\n" msgstr "Block %d in %s ino %llu existiert nicht\n" #: .././repair/phase6.c:1228 .././repair/phase6.c:1232 #, c-format msgid "can't map block %d in %s ino %llu, xfs_bmapi returns %d, nmap = %d\n" msgstr "" "Block %d in %s ino %llu kann nicht kartiert werden, xfs_bmapi gibt %d\n" "zurück, nmap = %d\n" #: .././repair/phase6.c:1240 .././repair/phase6.c:1244 #, c-format msgid "block %d in %s inode %llu doesn't exist\n" msgstr "Block %d in %s Inode %llu existiert nicht\n" #: .././repair/phase6.c:1267 msgid ", marking entry to be junked\n" msgstr ", Eintrag wird zum verwerfen gekennzeichnet\n" #: .././repair/phase6.c:1271 msgid ", would junk entry\n" msgstr ", Eintrag könnte verworfen werden\n" #: .././repair/phase6.c:1387 #, c-format msgid "entry \"%s\" in dir inode %llu points to non-existent inode %llu" msgstr "" "Eintrag »%s« in dir-Inode %llu zeigt auf nicht existierenden Inode %llu" #: .././repair/phase6.c:1405 #, c-format msgid "entry \"%s\" in dir inode %llu points to free inode %llu" msgstr "Eintrag »%s« in dir-Inode %llu zeigt auf freien Inode %llu" #: .././repair/phase6.c:1421 .././repair/phase6.c:2086 #: .././repair/phase6.c:2711 .././repair/phase6.c:3038 #, c-format msgid "%s (ino %llu) in root (%llu) is not a directory" msgstr "%s (ino %llu) in Wurzel (%llu) ist kein Verzeichnis" #: .././repair/phase6.c:1443 .././repair/phase6.c:2107 #: .././repair/phase6.c:2728 .././repair/phase6.c:3055 #, c-format msgid "entry \"%s\" (ino %llu) in dir %llu is a duplicate name" msgstr "Eintrag »%s« (ino %llu) in dir %llu ist ein doppelter Name" #: .././repair/phase6.c:1474 #, c-format msgid "" "entry \"%s\" in dir %llu points to an already connected dir inode %llu,\n" msgstr "" "Eintrag »%s« in dir %llu zeigt auf einen bereits verbundenen\n" "dir-Inode %llu,\n" #: .././repair/phase6.c:1483 .././repair/phase6.c:2208 #: .././repair/phase6.c:2761 .././repair/phase6.c:3086 #, c-format msgid "" "entry \"%s\" in dir ino %llu doesn't have a .. entry, will set it in ino %" "llu.\n" msgstr "" "Eintrag »%s« in dir %llu hat keinen ..-Eintrag, wird in ino %llu gesetzt.\n" #: .././repair/phase6.c:1491 #, c-format msgid "" "entry \"%s\" in dir ino %llu not consistent with .. value (%llu) in ino %" "llu,\n" msgstr "" "Eintrag »%s« in dir ino %llu nicht vollständig mit ..-Wert (%llu) in ino %" "llu,\n" #: .././repair/phase6.c:1506 .././repair/phase6.c:2232 #, c-format msgid "\twill clear entry \"%s\"\n" msgstr "\tEintrag »%s« wird bereinigt\n" #: .././repair/phase6.c:1509 .././repair/phase6.c:2235 #, c-format msgid "\twould clear entry \"%s\"\n" msgstr "\tEintrag »%s« könnte bereinigt werden\n" #: .././repair/phase6.c:1553 #, c-format msgid "cannot map block 0 of directory inode %llu\n" msgstr "Block 0 des Verzeichnis-Inodes %llu kann nicht kartiert werden\n" #: .././repair/phase6.c:1576 #, c-format msgid "bad magic # (0x%x) for dir ino %llu leaf block (bno %u fsbno %llu)\n" msgstr "" "falsche magische # (0x%x) für ino %llu Blatt-Block (bno %u fsbno %llu)\n" #: .././repair/phase6.c:1613 .././repair/phase6.c:1617 #, c-format msgid "can't map leaf block %d in dir %llu, xfs_bmapi returns %d, nmap = %d\n" msgstr "" "Blatt-Block %d in dir %llu kann nicht kartiert werden, xfs_bmapi gibt %d\n" "zurück, nmap = %d\n" #: .././repair/phase6.c:1669 #, c-format msgid "rebuilding directory inode %llu\n" msgstr "Verzeichnis-Inode %llu wird erneut erzeugt\n" #: .././repair/phase6.c:1694 #, c-format msgid "xfs_bmap_last_offset failed -- error - %d\n" msgstr "xfs_bmap_last_offset fehlgeschlagen -- Fehler - %d\n" #: .././repair/phase6.c:1701 #, c-format msgid "xfs_bunmapi failed -- error - %d\n" msgstr "xfs_bunmapi fehlgeschlagen -- Fehler - %d\n" #: .././repair/phase6.c:1743 #, c-format msgid "name create failed in ino %llu (%d), filesystem may be out of space\n" msgstr "" "Erzeugen des Namens fehlgeschlagen in ino %llu (%d), auf dem Dateisystem\n" "könnte kein Platz sein\n" #: .././repair/phase6.c:1808 #, c-format msgid "shrink_inode failed inode %llu block %u\n" msgstr "shrink_inode fehlgeschlagen Inode %llu Block %u\n" #: .././repair/phase6.c:1889 #, c-format msgid "realloc failed in longform_dir2_entry_check_data (%u bytes)\n" msgstr "realloc fehlgeschlagen in longform_dir2_entry_check_data (%u Bytes)\n" #: .././repair/phase6.c:1946 #, c-format msgid "empty data block %u in directory inode %llu: " msgstr "leerer Datenblock %u in Verzeichnis-Inode %llu: " #: .././repair/phase6.c:1949 #, c-format msgid "corrupt block %u in directory inode %llu: " msgstr "beschädigter Block %u in Verzeichnis-Inode %llu: " #: .././repair/phase6.c:1953 msgid "junking block\n" msgstr "Block wird weggeworfen\n" #: .././repair/phase6.c:1956 msgid "would junk block\n" msgstr "Block könnte weggeworfen werden\n" #: .././repair/phase6.c:1979 #, c-format msgid "bad directory block magic # %#x for directory inode %llu block %d: " msgstr "" "falscher Verzeichnisblock magische # %#x für Verzeichnis-Inode %llu Block %d: " #: .././repair/phase6.c:1983 #, c-format msgid "fixing magic # to %#x\n" msgstr "magische # wird auf %#x fixiert\n" #: .././repair/phase6.c:1987 #, c-format msgid "would fix magic # to %#x\n" msgstr "magische # würde auf %#x fixiert\n" #: .././repair/phase6.c:2007 #, c-format msgid "directory inode %llu block %u has consecutive free entries: " msgstr "" "Verzeichnis-Inode %llu Block %u hat aufeinander folgende freie Einträge: " #: .././repair/phase6.c:2011 msgid "joining together\n" msgstr "wird zusammengeführt\n" #: .././repair/phase6.c:2020 msgid "would join together\n" msgstr "könnte zusammengeführt werden\n" #: .././repair/phase6.c:2051 #, c-format msgid "entry \"%s\" in directory inode %llu points to non-existent inode %llu" msgstr "" "Eintrag »%s« in Verzeichnis-Inode %llu zeigt auf nicht existierenden\n" "Inode %llu" #: .././repair/phase6.c:2068 #, c-format msgid "entry \"%s\" in directory inode %llu points to free inode %llu" msgstr "Eintrag »%s« in Verzeichnis-Inode %llu zeigt auf freien Inode %llu" #: .././repair/phase6.c:2138 #, c-format msgid "entry \"%s\" (ino %llu) in dir %llu is not in the the first block" msgstr "Eintrag »%s« (ino %llu) in dir %llu ist nicht im ersten Block" #: .././repair/phase6.c:2164 #, c-format msgid "entry \"%s\" in dir %llu is not the first entry" msgstr "Eintrag »%s« in dir %llu ist nicht der erste Eintrag" #: .././repair/phase6.c:2200 #, c-format msgid "" "entry \"%s\" in dir %llu points to an already connected directory inode %" "llu\n" msgstr "" "Eintrag »%s« in dir %llu zeigt auf einen bereits verbundenen Verzeichnis-" "Inode %llu\n" #: .././repair/phase6.c:2219 #, c-format msgid "" "entry \"%s\" in dir inode %llu inconsistent with .. value (%llu) in ino %" "llu\n" msgstr "" "Eintrag »%s« in dir %llu stimmt nicht mit ..-Wert (%llu) in ino %llu überein\n" #: .././repair/phase6.c:2289 .././repair/phase6.c:2367 #, c-format msgid "leaf block %u for directory inode %llu bad header\n" msgstr "Blattblock %u für Verzeichnis-Inode %llu hat falsche Kopfzeilen\n" #: .././repair/phase6.c:2307 #, c-format msgid "leaf block %u for directory inode %llu bad tail\n" msgstr "Blatt-Block %u für Verzeichnis-Inode %llu hat falsches Ende\n" #: .././repair/phase6.c:2346 #, c-format msgid "can't read leaf block %u for directory inode %llu\n" msgstr "Blatt-Block %u für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/phase6.c:2357 #, c-format msgid "unknown magic number %#x for block %u in directory inode %llu\n" msgstr "" "unbekannte Magische Nummer %#x für Block %u in Verzeichnis-Inode %llu\n" #: .././repair/phase6.c:2392 #, c-format msgid "can't read freespace block %u for directory inode %llu\n" msgstr "" "Block %u mit freiem Platz für Verzeichnis-Inode %llu konnte nicht gelesen\n" "werden\n" #: .././repair/phase6.c:2404 #, c-format msgid "free block %u for directory inode %llu bad header\n" msgstr "freier Block %u für Verzeichnis-Inode %llu hat falschen Kopf\n" #: .././repair/phase6.c:2417 #, c-format msgid "free block %u entry %i for directory ino %llu bad\n" msgstr "freier Block %u Eintrag %i für Verzeichnis-ino %llu falsch\n" #: .././repair/phase6.c:2426 #, c-format msgid "free block %u for directory inode %llu bad nused\n" msgstr "freier Block %u für Verzeichnis-Inode %llu falsch nused\n" #: .././repair/phase6.c:2437 #, c-format msgid "missing freetab entry %u for directory inode %llu\n" msgstr "fehlender freetab-Eintrag %u für Verzeichnis-Inode %llu\n" #: .././repair/phase6.c:2478 #, c-format msgid "malloc failed in longform_dir2_entry_check (%u bytes)\n" msgstr "malloc fehlgeschlagen in longform_dir2_entry_check (%u Bytes)\n" #: .././repair/phase6.c:2508 #, c-format msgid "realloc failed in longform_dir2_entry_check (%u bytes)\n" msgstr "realloc fehlgeschlagen in longform_dir2_entry_check (%u Bytes)\n" #: .././repair/phase6.c:2514 #, c-format msgid "can't read data block %u for directory inode %llu\n" msgstr "Datenblock %u für Verzeichnis-Inode %llu kann nicht gelesen werden\n" #: .././repair/phase6.c:2619 #, c-format msgid "shortform dir inode %llu has null data entries \n" msgstr "Kurzform dir-Inode %llu hat Null-Daten-Einträge \n" #: .././repair/phase6.c:2686 #, c-format msgid "entry \"%s\" in shortform dir %llu references non-existent ino %llu" msgstr "" "Eintrag »%s« in Kurzform dir-Inode %llu bezieht sich auf nicht\n" "existierenden ino %llu" #: .././repair/phase6.c:2699 #, c-format msgid "entry \"%s\" in shortform dir inode %llu points to free inode %llu" msgstr "" "Eintrag »%s« in Kurzform dir-Inode %llu bezieht sich auf einen freien\n" "Inode %llu" #: .././repair/phase6.c:2752 #, c-format msgid "entry \"%s\" in dir %llu references already connected dir ino %llu,\n" msgstr "" "Eintrag »%s« in dir %llu bezieht sich auf einen bereits verbundenen\n" "dir ino %llu\n" #: .././repair/phase6.c:2769 #, c-format msgid "" "entry \"%s\" in dir %llu not consistent with .. value (%llu) in dir ino %llu" msgstr "" "Eintrag »%s« in dir %llu nicht übereinstimmend mit ..-Wert (%llu) in\n" "dir ino %llu" #: .././repair/phase6.c:2811 .././repair/phase6.c:3139 msgid "junking entry\n" msgstr "Eintrag wird verworfen\n" #: .././repair/phase6.c:2815 .././repair/phase6.c:3143 msgid "would junk entry\n" msgstr "Eintrag könnte verworfen werden\n" #: .././repair/phase6.c:2854 .././repair/phase6.c:3198 #, c-format msgid "setting size to %lld bytes to reflect junked entries\n" msgstr "" "Größe wird auf %lld Bytes gesetzt um verworfene Einträge\n" "widerzuspiegeln\n" #: .././repair/phase6.c:2905 #, c-format msgid "would set .. in sf dir inode %llu to %llu\n" msgstr ".. könnte in sf dir-Inode %llu auf %llu gesetzt werden\n" #: .././repair/phase6.c:2908 #, c-format msgid "setting .. in sf dir inode %llu to %llu\n" msgstr ".. wird in sf dir-Inode %llu auf %llu gesetzt\n" #: .././repair/phase6.c:3011 #, c-format msgid "" "entry \"%s\" in shortform directory %llu references non-existent inode %llu" msgstr "" "Eintrag »%s« in Kurzform-Verzeichnis %llu bezieht sich auf nicht\n" "existierenden Inode %llu" #: .././repair/phase6.c:3025 #, c-format msgid "" "entry \"%s\" in shortform directory inode %llu points to free inode %llu" msgstr "" "Eintrag »%s« in Kurzform-Verzeichnis-Inode %llu zeigt auf freien\n" "Inode %llu" #: .././repair/phase6.c:3076 #, c-format msgid "" "entry \"%s\" in directory inode %llu references already connected inode %" "llu,\n" msgstr "" "Eintrag »%s« in Verzeichnis-Inode %llu bezieht sich auf bereits verbundenen " "Inode %llu,\n" #: .././repair/phase6.c:3096 #, c-format msgid "" "entry \"%s\" in directory inode %llu not consistent with .. value (%llu) in " "inode %llu,\n" msgstr "" "Eintrag »%s« in Verzeichnis-Inode %llu nicht übereinstimmen mit ..-Wert (%" "llu) in Inode %llu,\n" #: .././repair/phase6.c:3167 #, c-format msgid "would fix i8count in inode %llu\n" msgstr "i8count in Inode %llu könnte repariert werden\n" #: .././repair/phase6.c:3179 #, c-format msgid "fixing i8count in inode %llu\n" msgstr "i8count in Inode %llu wird repariert\n" #: .././repair/phase6.c:3354 msgid "missing root directory .. entry, cannot fix in V1 dir filesystem\n" msgstr "" "fehlender Wurzelverzeichnis-..-Eintrag, kann nicht in V1 dir-Dateisystem\n" "behoben werden\n" #: .././repair/phase6.c:3360 #, c-format msgid "" "%d bad entries found in dir inode %llu, cannot fix in V1 dir filesystem\n" msgstr "" "%d falsche Einträge in dir-Inode %llu gefunden, kann nicht in V1\n" "dir-Dateisystem behoben werden\n" #: .././repair/phase6.c:3367 #, c-format msgid "missing \".\" entry in dir ino %llu, cannot in fix V1 dir filesystem\n" msgstr "" "fehlender ».«-Eintrag in dir ino %llu, kann nicht in V1 dir-Dateisystem\n" "behoben werden\n" #: .././repair/phase6.c:3386 msgid "recreating root directory .. entry\n" msgstr "..-Eintrag des Wurzel-Verzeichnisses wird neu erzeugt\n" #: .././repair/phase6.c:3405 #, c-format msgid "can't make \"..\" entry in root inode %llu, createname error %d\n" msgstr "" "»..«-Eintrag im Wurzel-Inode %llu kann nicht erstellt werden, createname-" "Fehler %d\n" #: .././repair/phase6.c:3417 msgid "would recreate root directory .. entry\n" msgstr "..-Eintrag des Wurzel-Verzeichnisses könnte neu erzeugt werden\n" #: .././repair/phase6.c:3440 #, c-format msgid "would create missing \".\" entry in dir ino %llu\n" msgstr "fehlender ».«-Eintrag in dir ino %llu könnte erzeugt werden\n" #: .././repair/phase6.c:3446 #, c-format msgid "creating missing \".\" entry in dir ino %llu\n" msgstr "fehlender ».«-Eintrag in dir ino %llu wird erzeugt\n" #: .././repair/phase6.c:3470 #, c-format msgid "can't make \".\" entry in dir ino %llu, createname error %d\n" msgstr "" "».«-Eintrag in dir ino %llu kann nicht erzeugt werden createname-Fehler %d\n" #: .././repair/phase6.c:3560 #, c-format msgid "disconnected dir inode %llu, " msgstr "nicht verbundener dir-Inode %llu, " #: .././repair/phase6.c:3562 #, c-format msgid "disconnected inode %llu, " msgstr "nicht verbundener Inode %llu, " #: .././repair/phase6.c:3564 msgid "cannot fix in V1 dir filesystem\n" msgstr "kann nicht in V1 dir-Dateisystem behoben werden\n" #: .././repair/phase6.c:3568 #, c-format msgid "moving to %s\n" msgstr "gehe zu %s\n" #: .././repair/phase6.c:3571 #, c-format msgid "would move to %s\n" msgstr "könnte zu %s gehen\n" #: .././repair/phase6.c:3662 msgid "Phase 6 - check inode connectivity...\n" msgstr "Phase 6 - Inode-Verbindbarkeit wird geprüft...\n" #: .././repair/phase6.c:3681 msgid "" "need to reinitialize root directory, but not supported on V1 dir filesystem\n" msgstr "" "Neuinitialisierung des Wurzelverzeichnisses nötig, aber nicht auf\n" "V1 dir-Dateisystem unterstützt\n" #: .././repair/phase6.c:3684 msgid "reinitializing root directory\n" msgstr "Wurzel-Verzeichnis wird neu initialisiert\n" #: .././repair/phase6.c:3689 msgid "would reinitialize root directory\n" msgstr "Wurzel-Verzeichnis könnte neu initialisiert werden\n" #: .././repair/phase6.c:3695 msgid "reinitializing realtime bitmap inode\n" msgstr "Echtzeit-Bitmap-Inode wird neu initialisiert\n" #: .././repair/phase6.c:3699 msgid "would reinitialize realtime bitmap inode\n" msgstr "Echtzeit-Bitmap-Inode könnte neu initialisiert werden\n" #: .././repair/phase6.c:3705 msgid "reinitializing realtime summary inode\n" msgstr "Echtzeit-Zusammenfassung wird neu initialisiert\n" #: .././repair/phase6.c:3709 msgid "would reinitialize realtime summary inode\n" msgstr "Echtzeit-Zusammenfassung könnte neu initialisiert werden\n" #: .././repair/phase6.c:3715 msgid " - resetting contents of realtime bitmap and summary inodes\n" msgstr "" " - Inhalte der Echtzeit-Bitmaps und Zusammenfassungs-Inodes werden " "zurückgesetzt\n" #: .././repair/phase6.c:3718 .././repair/phase6.c:3723 msgid "Warning: realtime bitmap may be inconsistent\n" msgstr "Warnung: Echtzeit-Bitmap kann unvollständig sein\n" #: .././repair/phase6.c:3729 msgid " - traversing filesystem ...\n" msgstr " - Dateisystem wird durchquert ...\n" #: .././repair/phase6.c:3752 msgid " - traversal finished ...\n" msgstr " - durchqueren beendet ...\n" #: .././repair/phase6.c:3753 #, c-format msgid " - moving disconnected inodes to %s ...\n" msgstr " - nicht verbundene Inodes werden nach %s verschoben ...\n" #: .././repair/xfs_repair.c:89 #, c-format msgid "" "Usage: %s [options] device\n" "\n" "Options:\n" " -f The device is a file\n" " -L Force log zeroing. Do this as a last resort.\n" " -l logdev Specifies the device where the external log resides.\n" " -m maxmem Maximum amount of memory to be used in megabytes.\n" " -n No modify mode, just checks the filesystem for damage.\n" " -P Disables prefetching.\n" " -r rtdev Specifies the device where the realtime section resides.\n" " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" " -t interval Reporting interval in minutes.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n" msgstr "" "Aufruf: %s [Optionen] Gerät\n" "\n" "Optionen:\n" " -f Das Gerät ist eine Datei\n" " -L Protokoll auf Null setzen erzwingen. Tun Sie dies als\n" " letzten Ausweg.\n" " -l logdev Gibt das Gerät an, auf dem das externe Protokoll liegt.\n" " -m maxmem Maximaler Wert von Speicher zum benutzen in Megabyte.\n" " -n Unveränderlicher Modus, prüft das Dateisystem nur auf\n" " Schäden.\n" " -P Vorher holen abgeschaltet.\n" " -r rtdev Gibt das Gerät an, auf dem der Echtzeitbereich liegt.\n" " -v Ausführliche Ausgabe.\n" " -c subopts Dateisystem-Parameter ändern - xfs_admin benutzen.\n" " -o subopts Standardverhalten überschreiben, bezogen auf Handbuchseite.\n" " -t interval Berichtsintervall in Minuten.\n" " -d Gefährliche Reparatur.\n" " -V Version anzeigen und beenden.\n" #: .././repair/xfs_repair.c:115 msgid "no error" msgstr "kein Fehler" #: .././repair/xfs_repair.c:116 msgid "bad magic number" msgstr "falsche Magische Nummer" #: .././repair/xfs_repair.c:117 msgid "bad blocksize field" msgstr "falsches Blockgrößen-Feld" #: .././repair/xfs_repair.c:118 msgid "bad blocksize log field" msgstr "falsches Blockgrößen-Protokoll-Feld" #: .././repair/xfs_repair.c:119 msgid "bad or unsupported version" msgstr "falsche oder nicht unterstützte Version" #: .././repair/xfs_repair.c:121 msgid "filesystem mkfs-in-progress bit set" msgstr "mkfs-in-progress-Bit des Dateisystems gesetzt" #: .././repair/xfs_repair.c:123 msgid "inconsistent filesystem geometry information" msgstr "unvollständige Information über die Geometrie des Dateisystems" #: .././repair/xfs_repair.c:125 msgid "bad inode size or inconsistent with number of inodes/block" msgstr "falsche Inode-Größe oder unvollständig mit Anzahl der Inodes/Block" #: .././repair/xfs_repair.c:126 msgid "bad sector size" msgstr "falsche Bereichsgröße" #: .././repair/xfs_repair.c:128 msgid "AGF geometry info conflicts with filesystem geometry" msgstr "AGF-Geometrie-Info hat einen Konflikt mit der Dateisystem-Geometrie" #: .././repair/xfs_repair.c:130 msgid "AGI geometry info conflicts with filesystem geometry" msgstr "AGI-Geometrie-Info hat einen Konflikt mit der Dateisystem-Geometrie" #: .././repair/xfs_repair.c:132 msgid "AG superblock geometry info conflicts with filesystem geometry" msgstr "" "AG-Superblock-Geometrie-Info hat einen Konflikt mit der\n" "Dateisystem-Geometrie" #: .././repair/xfs_repair.c:133 msgid "attempted to perform I/O beyond EOF" msgstr "versucht ein I/O jenseits von EOF auszuführen" #: .././repair/xfs_repair.c:135 msgid "inconsistent filesystem geometry in realtime filesystem component" msgstr "" "unvollständige Dateisystem-Geometrie in Echtzeit-Dateisystem-Komponente" #: .././repair/xfs_repair.c:137 msgid "maximum indicated percentage of inodes > 100%" msgstr "maximal angezeigte Prozentzahl der Inodes > 100%" #: .././repair/xfs_repair.c:139 msgid "inconsistent inode alignment value" msgstr "uneinheitlicher Inode-Ausrichtungswert" #: .././repair/xfs_repair.c:141 msgid "not enough secondary superblocks with matching geometry" msgstr "nicht genug sekundäre Superblöcke mit passender Geometrie" #: .././repair/xfs_repair.c:143 msgid "bad stripe unit in superblock" msgstr "falsche Stripe-Einheit in Superblock" #: .././repair/xfs_repair.c:145 msgid "bad stripe width in superblock" msgstr "falsche Stripe-Breite in Superblock" #: .././repair/xfs_repair.c:147 msgid "bad shared version number in superblock" msgstr "falsche verteilte Versionsnummer im Superblock" #: .././repair/xfs_repair.c:152 #, c-format msgid "bad error code - %d\n" msgstr "falscher Fehler-Code - %d\n" #: .././repair/xfs_repair.c:160 #, c-format msgid "-%c %s option cannot have a value\n" msgstr "-%c %s-Option kann keinen Wert haben\n" #: .././repair/xfs_repair.c:256 msgid "-o bhash option cannot be used with -m option\n" msgstr "-o bhash-Option kann nicht mit der -m-Option benutzt werden\n" #: .././repair/xfs_repair.c:305 msgid "-m option cannot be used with -o bhash option\n" msgstr "-m-Option kann nicht mit der -o bhash-Option benutzt werden\n" #: .././repair/xfs_repair.c:347 #, c-format msgid "" "\n" "fatal error -- " msgstr "" "\n" "schwerwiegender Fehler -- " #: .././repair/xfs_repair.c:455 #, c-format msgid "sb root inode value %llu %sinconsistent with calculated value %lu\n" msgstr "sb-Wurzel-Inode-Wert %llu %suneinheitlich mit berechnetem Wert %lu\n" #: .././repair/xfs_repair.c:462 #, c-format msgid "resetting superblock root inode pointer to %lu\n" msgstr "Superblock-Wurzel-Inode-Zeiger wird auf %lu zurückgesetzt\n" #: .././repair/xfs_repair.c:466 #, c-format msgid "would reset superblock root inode pointer to %lu\n" msgstr "Superblock-Wurzel-Inode-Zeiger könnte auf %lu zurückgesetzt werden\n" #: .././repair/xfs_repair.c:478 #, c-format msgid "" "sb realtime bitmap inode %llu %sinconsistent with calculated value %lu\n" msgstr "" "sb-Echtzeit-Bitmap-Inode %llu %suneinheitlich mit berechnetem Wert %lu\n" #: .././repair/xfs_repair.c:485 #, c-format msgid "resetting superblock realtime bitmap ino pointer to %lu\n" msgstr "Superblock-Echtzeit-Bitmap-ino-Zeiger wird auf %lu zurückgesetzt\n" #: .././repair/xfs_repair.c:489 #, c-format msgid "would reset superblock realtime bitmap ino pointer to %lu\n" msgstr "" "Superblock-Echtzeit-Bitmap-ino-Zeiger könnte auf %lu zurückgesetzt werden\n" #: .././repair/xfs_repair.c:501 #, c-format msgid "" "sb realtime summary inode %llu %sinconsistent with calculated value %lu\n" msgstr "" "sb-Echtzeit-Zusammenfassungs-Inode %llu %suneinheitlich mit berechnetem\n" "Wert %lu\n" #: .././repair/xfs_repair.c:508 #, c-format msgid "resetting superblock realtime summary ino pointer to %lu\n" msgstr "" "Superblock-Echtzeit-Zusammenfassungs-ino-Zeiger wird auf %lu zurückgesetzt\n" #: .././repair/xfs_repair.c:512 #, c-format msgid "would reset superblock realtime summary ino pointer to %lu\n" msgstr "" "Superblock-Echtzeit-Zusammenfassungs-ino-Zeiger könnte auf %lu\n" "zurückgesetzt werden\n" #: .././repair/xfs_repair.c:560 msgid "" "Primary superblock would have been modified.\n" "Cannot proceed further in no_modify mode.\n" "Exiting now.\n" msgstr "" "Primärer Superblock könnte verändert worden sein.\n" "Es kann nicht im no_modify.Modus fortgefahren werden.\n" "Es wird nun beendet.\n" #: .././repair/xfs_repair.c:576 #, c-format msgid "%s: cannot repair this filesystem. Sorry.\n" msgstr "%s: Dieses Dateisystem kann nicht repariert werden. Entschuldigung.\n" #: .././repair/xfs_repair.c:601 #, c-format msgid " - reporting progress in intervals of %s\n" msgstr " - Berichts-Prozess in Abständen von %s\n" #: .././repair/xfs_repair.c:647 #, c-format msgid "" " - max_mem = %lu, icount = %llu, imem = %llu, dblock = %llu, dmem = %" "llu\n" msgstr "" " - max_mem = %lu, icount = %llu, imem = %llu, dblock = %llu, dmem = %" "llu\n" #: .././repair/xfs_repair.c:660 #, c-format msgid "" "Required memory for repair is greater that the maximum specified with the -m " "option. Please increase it to at least %lu.\n" msgstr "" "Benötigter Speicher für die Reparatur ist größer als das mit der\n" "-m-Option angegebene Maximum. Bitte erhöhen Sie es auf mindestens %lu.\n" #: .././repair/xfs_repair.c:678 #, c-format msgid " - block cache size set to %d entries\n" msgstr " - Block-Zwischenspeichergröße ist auf %d Einträge gesetzt\n" #: .././repair/xfs_repair.c:702 msgid "Found unsupported filesystem features. Exiting now.\n" msgstr "" "Es wurden nicht unterstützte Dateisystemmerkmale gefunden. Es wird nun\n" "beendet.\n" #: .././repair/xfs_repair.c:720 #, c-format msgid "No modify flag set, skipping phase 5\n" msgstr "Kein Veränderungskennzeichen gesetzt, Phase 5 wird übersprungen\n" #: .././repair/xfs_repair.c:734 msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" msgstr "" "Inode-Allokations-btrees sind zu beschädigt, Phasen 6 und 7 werden\n" "übersprungen\n" #: .././repair/xfs_repair.c:740 msgid "Warning: no quota inodes were found. Quotas disabled.\n" msgstr "" "Warnung: Keine Quota-Inodes wurden gefunden. Quota ausgeschaltet\n" #: .././repair/xfs_repair.c:743 msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" msgstr "" "Warnung: Keine Quota-Inodes wurden gefunden. Quota könnte ausgeschaltet\n" "sein\n" #: .././repair/xfs_repair.c:748 msgid "Warning: quota inodes were cleared. Quotas disabled.\n" msgstr "" "Warnung: Quota-Inodes wurden bereinigt. Quota ausgeschaltet\n" #: .././repair/xfs_repair.c:751 msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" msgstr "" "Warnung: Quota-Inodes könnten bereinigt werden. Quota könnte\n" "ausgeschaltet sein\n" #: .././repair/xfs_repair.c:757 msgid "" "Warning: user quota information was cleared.\n" "User quotas can not be enforced until limit information is recreated.\n" msgstr "" "Warnung: Benutzer-Quota-Information wurde bereinigt.\n" "Benutzer-Quota können nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:761 msgid "" "Warning: user quota information would be cleared.\n" "User quotas could not be enforced until limit information was recreated.\n" msgstr "" "Warnung: Benutzer-Quota-Information könnte bereinigt werden.\n" "Benutzer-Quota kann nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:769 msgid "" "Warning: group quota information was cleared.\n" "Group quotas can not be enforced until limit information is recreated.\n" msgstr "" "Warnung: Gruppen-Quota-Information wurde bereinigt.\n" "Gruppen-Quota kann nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:773 msgid "" "Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n" msgstr "" "Warnung: Gruppen-Quota-Information könnte bereinigt werden.\n" "Gruppen-Quota kann nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:781 msgid "" "Warning: project quota information was cleared.\n" "Project quotas can not be enforced until limit information is recreated.\n" msgstr "" "Warnung: Projekt-Quota-Information wurde bereinigt.\n" "Projekt-Quota kann nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:785 msgid "" "Warning: project quota information would be cleared.\n" "Project quotas could not be enforced until limit information was recreated.\n" msgstr "" "Warnung: Projekt-Quota-Information könnte bereinigt werden.\n" "Projekt-Quota kann nicht erzwungen werden bis die\n" "Beschränkungsinformation neu erzeugt wurde.\n" #: .././repair/xfs_repair.c:796 msgid "No modify flag set, skipping filesystem flush and exiting.\n" msgstr "" "Kein Änderungskennzeichen gesetzt, Leeren des Dateisystems wird\n" "übersprungen und es wird beendet\n" #: .././repair/xfs_repair.c:815 msgid "Note - quota info will be regenerated on next quota mount.\n" msgstr "" "Anmerkung - Quota-Information wird beim nächsten Einhängen des Quotas neu\n" "erzeugt\n" #: .././repair/xfs_repair.c:823 #, c-format msgid "" "Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n" msgstr "" "Beachten Sie - Stripe-Einheit (%d) und -Beite (%d) Felder wurden\n" "zurückgesetzt. Bitte setzen Sie mit mount -o sunit=,swidth=\n" #: .././repair/xfs_repair.c:846 msgid "done\n" msgstr "erledigt\n" #: .././repair/attr_repair.c:106 msgid "" "entry contains illegal value in attribute named SGI_ACL_FILE or " "SGI_ACL_DEFAULT\n" msgstr "" "Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_ACL_FILE\n" "oder SGI_ACL_DEFAULT\n" #: .././repair/attr_repair.c:128 msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" msgstr "Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_MAC_LABEL\n" #: .././repair/attr_repair.c:134 msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" msgstr "Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_CAP_FILE\n" #: .././repair/attr_repair.c:173 #, c-format msgid "there are no attributes in the fork for inode %llu\n" msgstr "es sind keine Attribute im Unterelement für Inode %llu\n" #: .././repair/attr_repair.c:181 #, c-format msgid "would junk the attribute fork since count is 0 for inode %llu\n" msgstr "Attributs-Fork würde weggeworfen seit Anzahl für Inode %llu 0 ist\n" #: .././repair/attr_repair.c:201 msgid "zero length name entry in attribute fork," msgstr "Namenseintrag mit Länge Null in Attribut-Abspaltung," #: .././repair/attr_repair.c:204 .././repair/attr_repair.c:224 #, c-format msgid " truncating attributes for inode %llu to %d\n" msgstr "Attribute für Inode %llu auf %d kürzen\n" #: .././repair/attr_repair.c:209 .././repair/attr_repair.c:230 #, c-format msgid " would truncate attributes for inode %llu to %d\n" msgstr "Attribute für Inode %llu könnten auf %d gekürzt werden\n" #: .././repair/attr_repair.c:221 msgid "name or value attribute lengths are too large,\n" msgstr "Name oder Länge des Attributswerts sind zu lang,\n" #: .././repair/attr_repair.c:243 msgid "entry contains illegal character in shortform attribute name\n" msgstr "" "Eintrag enthält unerlaubtes Zeichen in der Kurzform des Attributsnamens\n" #: .././repair/attr_repair.c:249 msgid "entry has INCOMPLETE flag on in shortform attribute\n" msgstr "Eintrag hat INCOMPLETE-Markierung in der Attributs-Kurzform\n" #: .././repair/attr_repair.c:266 #, c-format msgid "removing attribute entry %d for inode %llu\n" msgstr "Attributseintrag %d für Inode %llu wird entfernt\n" #: .././repair/attr_repair.c:278 #, c-format msgid "would remove attribute entry %d for inode %llu\n" msgstr "Attributs-Eintrag %d für Inode %llu könnte entfernt werden\n" #: .././repair/attr_repair.c:292 #, c-format msgid "" "would have corrected attribute entry count in inode %llu from %d to %d\n" msgstr "" "Anzahl der Attributs-Einträge könnte in Inode %llu von %d auf %d\n" "korrigiert worden sein\n" #: .././repair/attr_repair.c:296 #, c-format msgid "corrected attribute entry count in inode %llu, was %d, now %d\n" msgstr "" "Korrigierte Anzahl der Attributs-Einträge in Inode %llu war %d,\n" "ist nun %d\n" #: .././repair/attr_repair.c:307 #, c-format msgid "would have corrected attribute totsize in inode %llu from %d to %d\n" msgstr "" "Anzahl der Attributs-Gesamtgröße könnte in Inode %llu von %d auf %d\n" "korrigiert worden sein\n" #: .././repair/attr_repair.c:312 #, c-format msgid "corrected attribute entry totsize in inode %llu, was %d, now %d\n" msgstr "" "Korrigierte Gesamtgröße der Attributs-Einträge in Inode %llu war %d,\n" "ist nun %d\n" #: .././repair/attr_repair.c:342 #, c-format msgid "remote block for attributes of inode %llu is missing\n" msgstr "entfernt liegender Block für Attribute des Inodes %llu fehlt\n" #: .././repair/attr_repair.c:350 #, c-format msgid "can't read remote block for attributes of inode %llu\n" msgstr "" "entfernt liegender Block für Attribute des Inodes %llu kann nicht\n" "gelesen werden\n" #: .././repair/attr_repair.c:394 #, c-format msgid "" "attribute entry %d in attr block %u, inode %llu has bad name (namelen = %d)\n" msgstr "" "Attributs-Eintrag #%d in »attr«-Block %u, Inode %llu hat ungültigen\n" "Namen (namelen = %d)\n" #: .././repair/attr_repair.c:411 #, c-format msgid "bad hashvalue for attribute entry %d in attr block %u, inode %llu\n" msgstr "" "falscher Hash-Wert für Attributs-Eintrag %d in »attr«-Block %u,\n" "Inode %llu\n" #: .././repair/attr_repair.c:420 #, c-format msgid "" "bad security value for attribute entry %d in attr block %u, inode %llu\n" msgstr "" "falscher Sicherheitswert für Attributs-Eintrag %d in »attr«-Block %u in\n" "Inode %llu\n" #: .././repair/attr_repair.c:453 #, c-format msgid "inconsistent remote attribute entry %d in attr block %u, ino %llu\n" msgstr "" "Unvollständiger entfernt liegender Attributs-Eintrag %d in\n" "»attr«-Block %u, ino %llu\n" #: .././repair/attr_repair.c:463 #, c-format msgid "cannot malloc enough for remotevalue attribute for inode %llu\n" msgstr "malloc nicht ausreichend für remotevalue-Attribut für Inode %llu\n" #: .././repair/attr_repair.c:465 msgid "SKIPPING this remote attribute\n" msgstr "ÜBERSPRINGE dieses entfernt liegende Attribut\n" #: .././repair/attr_repair.c:470 #, c-format msgid "remote attribute get failed for entry %d, inode %llu\n" msgstr "" "das Abholen des entfernt liegenden Attributs scheiterte für Eintrag %d,\n" "Inode %llu\n" #: .././repair/attr_repair.c:476 #, c-format msgid "remote attribute value check failed for entry %d, inode %llu\n" msgstr "" "das Prüfen des entfernt liegenden Attributs-Wertes scheiterte für\n" "Eintrag %d, Inode %llu\n" #: .././repair/attr_repair.c:513 #, c-format msgid "bad attribute count %d in attr block %u, inode %llu\n" msgstr "falsche Attributs-Anzahl %d in »attr«-Block %u, Inode %llu\n" #: .././repair/attr_repair.c:528 #, c-format msgid "bad attribute nameidx %d in attr block %u, inode %llu\n" msgstr "falsches Attribut nameidx %d in »attr«-Block %u, Inode %llu\n" #: .././repair/attr_repair.c:537 #, c-format msgid "attribute entry #%d in attr block %u, inode %llu is INCOMPLETE\n" msgstr "" "Attributs-Eintrag #%d in »attr«-Block %u, Inode %llu ist UNVOLLSTÄNDIG\n" #: .././repair/attr_repair.c:548 #, c-format msgid "" "attribute entry %d in attr block %u, inode %llu claims already used space\n" msgstr "" "Attributs-Eintrag #%d in »attr«-Block %u, Inode %llu erhebt Anspruch auf\n" "benutzten Speicher\n" #: .././repair/attr_repair.c:571 #, c-format msgid "attribute entry %d in attr block %u, inode %llu claims used space\n" msgstr "" "Attributs-Eintrag %d in »attr«-Block %u, Inode %llu erhebt Anspruch auf\n" "benutzten Speicher\n" #: .././repair/attr_repair.c:596 #, c-format msgid "" "- resetting first used heap value from %d to %d in block %u of attribute " "fork of inode %llu\n" msgstr "" "- zuerst benutzter Heap-Wert wird von %d auf %d zurückgesetzt in Block %u\n" "des Attributs-Forks von Inode %llu\n" #: .././repair/attr_repair.c:604 #, c-format msgid "" "- would reset first used value from %d to %d in block %u of attribute fork " "of inode %llu\n" msgstr "" "- zuerst genutzter Wert könnte von %d auf %d zurückgesetzt werden im\n" "Block %u des Attribut-Unterelements von Inode %llu\n" #: .././repair/attr_repair.c:614 #, c-format msgid "" "- resetting usedbytes cnt from %d to %d in block %u of attribute fork of " "inode %llu\n" msgstr "" "- usedbytes cnt wird von %d auf %d zurückgesetzt in Block %u des\n" "Attributs-Forks von Inode %llu\n" #: .././repair/attr_repair.c:622 #, c-format msgid "" "- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %" "llu\n" msgstr "" "- usedbytes cnt würde von %d auf %d zurückgesetzt in Block %u des\n" "Attributs-Forks von Inode %llu\n" #: .././repair/attr_repair.c:671 #, c-format msgid "can't map block %u for attribute fork for inode %llu\n" msgstr "" "Block %u kann nicht für Erstellung eines Unterelements des Inodes %llu\n" "kartiert werden\n" #: .././repair/attr_repair.c:679 #, c-format msgid "" "can't read file block %u (fsbno %llu) for attribute fork of inode %llu\n" msgstr "" "Datei-Block %u (fsbno %llu) für Erstellung des Subattributs des Inodes\n" "%llu kann nicht gelesen werden\n" #: .././repair/attr_repair.c:689 #, c-format msgid "bad attribute leaf magic %#x for inode %llu\n" msgstr "falsches Attributsblatt magische %#x für Inode %llu\n" #: .././repair/attr_repair.c:720 #, c-format msgid "" "bad sibling back pointer for block %u in attribute fork for inode %llu\n" msgstr "" "falscher Geschwister-Rückwärtszeiger für Block %u in Attributs-Fork für\n" "Inode %llu\n" #: .././repair/attr_repair.c:747 #, c-format msgid "bad hash path in attribute fork for inode %llu\n" msgstr "schlechter Hash-Pfad in Subattribut für Inode %llu\n" #: .././repair/attr_repair.c:846 #, c-format msgid "block 0 of inode %llu attribute fork is missing\n" msgstr "Block 0 des Subattributs von Inode %llu fehlt\n" #: .././repair/attr_repair.c:852 #, c-format msgid "agno of attribute fork of inode %llu out of regular partition\n" msgstr "" "agno des Subattributs des Inodes %llu außerhalb der regulären Partition\n" #: .././repair/attr_repair.c:860 #, c-format msgid "can't read block 0 of inode %llu attribute fork\n" msgstr "Block 0 des Subattributs von Inode %llu kann nicht gelesen werden\n" #: .././repair/attr_repair.c:874 #, c-format msgid "clearing forw/back pointers in block 0 for attributes in inode %llu\n" msgstr "" "Vorwärts-/Rückwärtszeiger im Block 0 für Attribute des Inodes %llu wird\n" "bereinigt\n" #: .././repair/attr_repair.c:880 #, c-format msgid "" "would clear forw/back pointers in block 0 for attributes in inode %llu\n" msgstr "" "Vorwärts-/Rückwärtszeiger im Block 0 für Attribute des Inodes %llu\n" "könnte bereinigt werden\n" #: .././repair/attr_repair.c:910 #, c-format msgid "bad attribute leaf magic # %#x for dir ino %llu\n" msgstr "falsches Attributsblatt magische # %#x für dir ino %llu\n" #: .././repair/attr_repair.c:1000 msgid "cannot malloc enough for ACL attribute\n" msgstr "nicht genug malloc für ACL-Attribut möglich\n" #: .././repair/attr_repair.c:1001 msgid "SKIPPING this ACL\n" msgstr "ÜBERSPRINGE dieses ACL\n" #: .././repair/prefetch.c:473 msgid "prefetch corruption\n" msgstr "Voraufrufbeschädigung\n" #: .././repair/prefetch.c:628 .././repair/prefetch.c:724 #, c-format msgid "failed to create prefetch thread: %s\n" msgstr "Erzeugung des Voraufruf-Threads fehlgeschlagen: %s\n" #: .././repair/prefetch.c:762 msgid "failed to initialize prefetch mutex\n" msgstr "initialisieren des Voraufruf-Mutex fehlgeschlagen\n" #: .././repair/prefetch.c:764 .././repair/prefetch.c:766 msgid "failed to initialize prefetch cond var\n" msgstr "initialisieren der Voraufruf-cond var fehlgeschlagen\n" #: .././rtcp/xfs_rtcp.c:30 #, c-format msgid "%s [-e extsize] [-p] source target\n" msgstr "%s [-e extsize] [-p] Quelle Ziel\n" #: .././rtcp/xfs_rtcp.c:71 #, c-format msgid "%s: must specify files to copy\n" msgstr "%s: Dateien zum Kopieren müssen angegeben werden\n" #: .././rtcp/xfs_rtcp.c:86 #, c-format msgid "%s: stat64 of %s failed\n" msgstr "%s: stat64 von %s fehlgeschlagen\n" #: .././rtcp/xfs_rtcp.c:93 #, c-format msgid "%s: final argument is not directory\n" msgstr "%s: letztes Argument ist kein Verzeichnis\n" #: .././rtcp/xfs_rtcp.c:140 #, c-format msgid "%s: failed stat64 on %s: %s\n" msgstr "%s: stat64 auf %s fehlgeschlagen: %s\n" #: .././rtcp/xfs_rtcp.c:161 #, c-format msgid "%s: %s filesystem has no realtime partition\n" msgstr "%s: %s-Dateisystem hat keine Echtzeit-Partition\n" #: .././rtcp/xfs_rtcp.c:182 .././rtcp/xfs_rtcp.c:210 #, c-format msgid "%s: open of %s failed: %s\n" msgstr "%s: Öffnen auf %s fehlgeschlagen: %s\n" #: .././rtcp/xfs_rtcp.c:199 #, c-format msgid "%s: set attributes on %s failed: %s\n" msgstr "%s: Setzen von Attributen auf %s fehlgeschlagen: %s\n" #: .././rtcp/xfs_rtcp.c:217 #, c-format msgid "%s: get attributes of %s failed: %s\n" msgstr "%s: Erhalten von Attributen auf %s fehlgeschlagen: %s\n" #: .././rtcp/xfs_rtcp.c:227 .././rtcp/xfs_rtcp.c:262 #, c-format msgid "%s: %s is not a realtime file.\n" msgstr "%s: %s ist keine Echtzeit-Datei.\n" #: .././rtcp/xfs_rtcp.c:236 #, c-format msgid "%s: %s file extent size is %d, instead of %d.\n" msgstr "%s: %s Dateiumfanggröße ist %d anstelle von %d.\n" #: .././rtcp/xfs_rtcp.c:248 .././rtcp/xfs_rtcp.c:271 #, c-format msgid "%s: open of %s source failed: %s\n" msgstr "%s: Öffnen von %s-Quelle fehlgeschlagen:%s\n" #: .././rtcp/xfs_rtcp.c:285 #, c-format msgid "%s: couldn't get direct I/O information: %s\n" msgstr "%s: direkte I/O-Information kann nicht erlangt werden: %s\n" #: .././rtcp/xfs_rtcp.c:295 #, c-format msgid "%s: extent size %d not a multiple of %d.\n" msgstr "%s: Umfanggröße %d ist kein Vielfaches von %d.\n" #: .././rtcp/xfs_rtcp.c:309 #, c-format msgid "The size of %s is not a multiple of %d.\n" msgstr "Die Größe von %s ist kein Vielfaches von %d.\n" #: .././rtcp/xfs_rtcp.c:312 #, c-format msgid "%s will be padded to %lld bytes.\n" msgstr "%s wird auf %lld Bytes aufgefüllt.\n" #: .././rtcp/xfs_rtcp.c:318 #, c-format msgid "" "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" msgstr "" "Benutzen Sie die -p-Option um %s auf eine Größe aufzufüllen, die ein\n" "Vielfaches von %d Bytes ist.\n" #: .././rtcp/xfs_rtcp.c:360 #, c-format msgid "%s: write error: %s\n" msgstr "%s: Schreibfehler: %s\n" #: .././rtcp/xfs_rtcp.c:388 #, c-format msgid "%s: could not open %s: %s\n" msgstr "%s: %s kann nicht geöffnet werden: %s\n" xfsprogs-3.1.9ubuntu2/po/pl.po0000664000000000000000000153704312062210562013216 0ustar # Polish translation for xfsprogs. # This file is distributed under the same license as the xfsprogs package. # Jakub Bogusz , 2006-2012. # msgid "" msgstr "" "Project-Id-Version: xfsprogs 3.1.8\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-03-04 06:24+0100\n" "PO-Revision-Date: 2012-03-04 07:30+0100\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: .././rtcp/xfs_rtcp.c:30 #, c-format msgid "%s [-e extsize] [-p] source target\n" msgstr "%s [-e rozm_fragmentu] [-p] źródło cel\n" #: .././rtcp/xfs_rtcp.c:55 .././repair/xfs_repair.c:317 .././quota/init.c:131 #: .././mkfs/xfs_mkfs.c:1623 .././logprint/logprint.c:196 .././io/init.c:183 #: .././growfs/xfs_growfs.c:182 .././fsr/xfs_fsr.c:302 #: .././estimate/xfs_estimate.c:141 .././db/init.c:93 .././copy/xfs_copy.c:543 #, c-format msgid "%s version %s\n" msgstr "%s wersja %s\n" #: .././rtcp/xfs_rtcp.c:69 #, c-format msgid "%s: must specify files to copy\n" msgstr "%s: trzeba podać pliki do skopiowania\n" #: .././rtcp/xfs_rtcp.c:84 #, c-format msgid "%s: stat64 of %s failed\n" msgstr "%s: stat64 na %s nie powiodło się\n" #: .././rtcp/xfs_rtcp.c:91 #, c-format msgid "%s: final argument is not directory\n" msgstr "%s: ostatni argument nie jest katalogiem\n" #: .././rtcp/xfs_rtcp.c:138 #, c-format msgid "%s: failed stat64 on %s: %s\n" msgstr "%s: nie udało się wykonać stat64 na %s: %s\n" #: .././rtcp/xfs_rtcp.c:159 #, c-format msgid "%s: %s filesystem has no realtime partition\n" msgstr "%s: system plików %s nie ma partycji realtime\n" #: .././rtcp/xfs_rtcp.c:180 .././rtcp/xfs_rtcp.c:208 #, c-format msgid "%s: open of %s failed: %s\n" msgstr "%s: otwarcie %s nie powiodło się: %s\n" #: .././rtcp/xfs_rtcp.c:197 #, c-format msgid "%s: set attributes on %s failed: %s\n" msgstr "%s: ustawienie atrybutów dla %s nie powiodło się: %s\n" #: .././rtcp/xfs_rtcp.c:215 #, c-format msgid "%s: get attributes of %s failed: %s\n" msgstr "%s: pobranie atrybutów %s nie powiodło się: %s\n" #: .././rtcp/xfs_rtcp.c:225 .././rtcp/xfs_rtcp.c:260 #, c-format msgid "%s: %s is not a realtime file.\n" msgstr "%s: %s nie jest plikiem realtime.\n" #: .././rtcp/xfs_rtcp.c:234 #, c-format msgid "%s: %s file extent size is %d, instead of %d.\n" msgstr "%s: plik %s ma rozmiar ekstentu %d zamiast %d.\n" #: .././rtcp/xfs_rtcp.c:246 .././rtcp/xfs_rtcp.c:269 #, c-format msgid "%s: open of %s source failed: %s\n" msgstr "%s: otwarcie źródła %s nie powiodło się: %s\n" #: .././rtcp/xfs_rtcp.c:283 #, c-format msgid "%s: couldn't get direct I/O information: %s\n" msgstr "%s: nie udało się uzyskać informacji o bezpośrednim we/wy: %s\n" #: .././rtcp/xfs_rtcp.c:293 #, c-format msgid "%s: extent size %d not a multiple of %d.\n" msgstr "%s: rozmiar ekstentu %d nie jest wielokrotnością %d.\n" #: .././rtcp/xfs_rtcp.c:307 #, c-format msgid "The size of %s is not a multiple of %d.\n" msgstr "Rozmiar %s nie jest wielokrotnością %d.\n" #: .././rtcp/xfs_rtcp.c:310 #, c-format msgid "%s will be padded to %lld bytes.\n" msgstr "%s: zostanie dopełniony do %lld bajtów.\n" #: .././rtcp/xfs_rtcp.c:316 #, c-format msgid "Use the -p option to pad %s to a size which is a multiple of %d bytes.\n" msgstr "Można użyć opcji -p do dopełnienia %s do rozmiaru będącego wielokrotnością %d bajtów.\n" #: .././rtcp/xfs_rtcp.c:358 #, c-format msgid "%s: write error: %s\n" msgstr "%s: błąd zapisu: %s\n" #: .././rtcp/xfs_rtcp.c:386 #, c-format msgid "%s: could not open %s: %s\n" msgstr "%s: nie udało się otworzyć %s: %s\n" #: .././repair/xfs_repair.c:81 #, c-format msgid "" "Usage: %s [options] device\n" "\n" "Options:\n" " -f The device is a file\n" " -L Force log zeroing. Do this as a last resort.\n" " -l logdev Specifies the device where the external log resides.\n" " -m maxmem Maximum amount of memory to be used in megabytes.\n" " -n No modify mode, just checks the filesystem for damage.\n" " -P Disables prefetching.\n" " -r rtdev Specifies the device where the realtime section resides.\n" " -v Verbose output.\n" " -c subopts Change filesystem parameters - use xfs_admin.\n" " -o subopts Override default behaviour, refer to man page.\n" " -t interval Reporting interval in minutes.\n" " -d Repair dangerously.\n" " -V Reports version and exits.\n" msgstr "" "Składnia: %s [opcje] urządzenie\n" "\n" "Opcje:\n" " -f Urządzenie jest plikiem\n" " -L Wymuszenie wyzerowania logu. Wykonywać tylko w ostateczności.\n" " -l urz_logu Określenie urządzenia z zewnętrznym logiem.\n" " -m maks_pam Maksymalna ilość pamięci do użycia w megabajtach.\n" " -n Tryb bez modyfikacji, tylko sprawdzenie systemu plików.\n" " -P Wyłączenie prefetch.\n" " -r urz_rt Określenie urządzenia z sekcją realtime.\n" " -v Szczegółowe wyjście.\n" " -c podopcje Zmiana parametrów systemu plików przy użyciu xfs_admina.\n" " -o podopcje Zmiana domyślnego zachowania, więcej na stronie manuala.\n" " -t czas Okres informowania o postępach w minutach.\n" " -d Naprawianie w sposób niebezpieczny.\n" " -V Wypisanie informacji o wersji i zakończenie.\n" #: .././repair/xfs_repair.c:107 msgid "no error" msgstr "brak błędu" #: .././repair/xfs_repair.c:108 msgid "bad magic number" msgstr "błędna liczba magiczna" #: .././repair/xfs_repair.c:109 msgid "bad blocksize field" msgstr "błędne pole blocksize" #: .././repair/xfs_repair.c:110 msgid "bad blocksize log field" msgstr "błędne pole logu blocksize" #: .././repair/xfs_repair.c:111 msgid "bad or unsupported version" msgstr "błędna lub nie obsługiwana wersja" #: .././repair/xfs_repair.c:113 msgid "filesystem mkfs-in-progress bit set" msgstr "ustawiony bit mkfs-in-progress systemu plików" #: .././repair/xfs_repair.c:115 msgid "inconsistent filesystem geometry information" msgstr "niespójne informacje o geometrii systemu plików" #: .././repair/xfs_repair.c:117 msgid "bad inode size or inconsistent with number of inodes/block" msgstr "błędny rozmiar i-węzła lub niespójność z liczbą i-węzłów/blok" #: .././repair/xfs_repair.c:118 msgid "bad sector size" msgstr "błędny rozmiar sektora" #: .././repair/xfs_repair.c:120 msgid "AGF geometry info conflicts with filesystem geometry" msgstr "informacje o geometrii AGF są w konflikcie z geometrią systemu plików" #: .././repair/xfs_repair.c:122 msgid "AGI geometry info conflicts with filesystem geometry" msgstr "informacje o geometrii AGI są w konflikcie z geometrią systemu plików" #: .././repair/xfs_repair.c:124 msgid "AG superblock geometry info conflicts with filesystem geometry" msgstr "informacje o geometrii superbloku AG są w konflikcie z geometrią systemu plików" #: .././repair/xfs_repair.c:125 msgid "attempted to perform I/O beyond EOF" msgstr "próbowano wykonać operację we/wy poza końcem pliku" #: .././repair/xfs_repair.c:127 msgid "inconsistent filesystem geometry in realtime filesystem component" msgstr "niespójna geometria systemu plików w składniku realtime" #: .././repair/xfs_repair.c:129 msgid "maximum indicated percentage of inodes > 100%" msgstr "określono maksymalny procent i-węzłów > 100%" #: .././repair/xfs_repair.c:131 msgid "inconsistent inode alignment value" msgstr "niespójna wartość wyrównania i-węzła" #: .././repair/xfs_repair.c:133 msgid "not enough secondary superblocks with matching geometry" msgstr "za mało zapasowych superbloków o pasującej geometrii" #: .././repair/xfs_repair.c:135 msgid "bad stripe unit in superblock" msgstr "błędna jednostka pasa w superbloku" #: .././repair/xfs_repair.c:137 msgid "bad stripe width in superblock" msgstr "błędna szerokość pasa w superbloku" #: .././repair/xfs_repair.c:139 msgid "bad shared version number in superblock" msgstr "błędny numer wersji współdzielenia w superbloku" #: .././repair/xfs_repair.c:144 #, c-format msgid "bad error code - %d\n" msgstr "błędny kod błędu - %d\n" #: .././repair/xfs_repair.c:152 #, c-format msgid "-%c %s option cannot have a value\n" msgstr "opcja -%c %s nie przyjmuje wartości\n" #: .././repair/xfs_repair.c:162 .././mkfs/xfs_mkfs.c:2801 #, c-format msgid "option respecified\n" msgstr "ponownie podana opcja\n" #: .././repair/xfs_repair.c:169 .././mkfs/xfs_mkfs.c:2810 #, c-format msgid "unknown option -%c %s\n" msgstr "nieznana opcja -%c %s\n" #: .././repair/xfs_repair.c:248 msgid "-o bhash option cannot be used with -m option\n" msgstr "opcja -o bhash nie może być użyta wraz z opcją -m\n" #: .././repair/xfs_repair.c:300 msgid "-m option cannot be used with -o bhash option\n" msgstr "opcja -m nie może być użyta wraz z opcją -o bhash\n" #: .././repair/xfs_repair.c:342 #, c-format msgid "" "\n" "fatal error -- " msgstr "" "\n" "błąd krytyczny - " #: .././repair/xfs_repair.c:454 #, c-format msgid "sb root inode value % %sinconsistent with calculated value %u\n" msgstr "wartość i-węzła głównego superbloku % %sniespójna z obliczoną wartością %u\n" #: .././repair/xfs_repair.c:461 #, c-format msgid "resetting superblock root inode pointer to %u\n" msgstr "przestawiono wskaźnik i-węzła głównego superbloku na %u\n" #: .././repair/xfs_repair.c:465 #, c-format msgid "would reset superblock root inode pointer to %u\n" msgstr "wskaźnik i-węzła głównego superbloku zostałby przestawiony na %u\n" #: .././repair/xfs_repair.c:477 #, c-format msgid "sb realtime bitmap inode % %sinconsistent with calculated value %u\n" msgstr "i-węzeł bitmapy realtime superbloku % %sniespójny z obliczoną wartością %u\n" #: .././repair/xfs_repair.c:484 #, c-format msgid "resetting superblock realtime bitmap ino pointer to %u\n" msgstr "przestawiono wskaźnik i-węzła bitmapy realtime superbloku na %u\n" #: .././repair/xfs_repair.c:488 #, c-format msgid "would reset superblock realtime bitmap ino pointer to %u\n" msgstr "wskaźnik i-węzła bitmapy realtime superbloku zostałby przestawiony na %u\n" #: .././repair/xfs_repair.c:500 #, c-format msgid "sb realtime summary inode % %sinconsistent with calculated value %u\n" msgstr "i-węzeł opisu realtime superbloku % %sniespójny z obliczoną wartością %u\n" #: .././repair/xfs_repair.c:507 #, c-format msgid "resetting superblock realtime summary ino pointer to %u\n" msgstr "przestawiono wskaźnik i-węzła opisu realtime superbloku na %u\n" #: .././repair/xfs_repair.c:511 #, c-format msgid "would reset superblock realtime summary ino pointer to %u\n" msgstr "wskaźnik i-węzła opisu realtime superbloku zostałby przestawiony na %u\n" #: .././repair/xfs_repair.c:554 msgid "" "Primary superblock would have been modified.\n" "Cannot proceed further in no_modify mode.\n" "Exiting now.\n" msgstr "" "Główny superblok zostałby zmodyfikowany.\n" "Nie można kontynuować w trybie bez modyfikacji.\n" "Zakończono.\n" #: .././repair/xfs_repair.c:577 msgid "" "Cannot get host filesystem geometry.\n" "Repair may fail if there is a sector size mismatch between\n" "the image and the host filesystem.\n" msgstr "" "Nie można pobrać geometrii systemu plików hosta.\n" "Naprawienie może się nie powieść, jeśli istnieje niespójność rozmiaru\n" "sektora między obrazem a systemem plików hosta.\n" #: .././repair/xfs_repair.c:589 msgid "" "Sector size on host filesystem larger than image sector size.\n" "Cannot turn off direct IO, so exiting.\n" msgstr "" "Rozmiar sektora na systemie plików hosta większy niż rozmiar sektora obrazu.\n" "Nie można wyłączyć bezpośredniego we/wy - zakończono działanie.\n" #: .././repair/xfs_repair.c:599 #, c-format msgid "%s: cannot repair this filesystem. Sorry.\n" msgstr "%s: niestety nie można naprawić tego systemu plików.\n" #: .././repair/xfs_repair.c:624 #, c-format msgid " - reporting progress in intervals of %s\n" msgstr " - informowanie o postępie w odstępach %s\n" #: .././repair/xfs_repair.c:671 #, c-format msgid " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" msgstr " - max_mem = %lu, icount = %, imem = %, dblock = %, dmem = %\n" #: .././repair/xfs_repair.c:684 #, c-format msgid "" "Required memory for repair is greater that the maximum specified\n" "with the -m option. Please increase it to at least %lu.\n" msgstr "" "Pamięć wymagana do naprawy przekracza maksimum określone opcją -m.\n" "Proszę ją zwiększyć do co najmniej %lu.\n" #: .././repair/xfs_repair.c:689 #, c-format msgid "" "Not enough RAM available for repair to enable prefetching.\n" "This will be _slow_.\n" "You need at least %luMB RAM to run with prefetching enabled.\n" msgstr "" "Zbyt mało dostępnej pamięci RAM, żeby naprawiać z włączonym prefetch.\n" "To będzie _wolne_.\n" "Do włączenia prefetch potrzeba przynajmniej %luMB RAM.\n" #: .././repair/xfs_repair.c:707 #, c-format msgid " - block cache size set to %d entries\n" msgstr " - rozmiar bufora bloku ustawiony na %d wpisów\n" #: .././repair/xfs_repair.c:736 msgid "Found unsupported filesystem features. Exiting now.\n" msgstr "Znaleziono nie obsługiwane cechy systemu plików. Zakończono.\n" #: .././repair/xfs_repair.c:754 #, c-format msgid "No modify flag set, skipping phase 5\n" msgstr "Ustawiono flagę braku modyfikacji, pominięto fazę 5\n" #: .././repair/xfs_repair.c:773 msgid "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n" msgstr "B-drzewa alokacji i-węzłów są zbyt uszkodzone, pominięto fazy 6 i 7\n" #: .././repair/xfs_repair.c:779 msgid "Warning: no quota inodes were found. Quotas disabled.\n" msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity wyłączone.\n" #: .././repair/xfs_repair.c:782 msgid "Warning: no quota inodes were found. Quotas would be disabled.\n" msgstr "Uwaga: nie znaleziono i-węzłów limitów (quot). Limity zostałyby wyłączone.\n" #: .././repair/xfs_repair.c:787 msgid "Warning: quota inodes were cleared. Quotas disabled.\n" msgstr "Uwaga: i-węzły limitów (quot) były wyczyszczone. Limity wyłączone.\n" #: .././repair/xfs_repair.c:790 msgid "Warning: quota inodes would be cleared. Quotas would be disabled.\n" msgstr "Uwaga: i-węzły limitów (quot) zostałyby wyczyszczone. Limity zostałyby wyłączone.\n" #: .././repair/xfs_repair.c:796 msgid "" "Warning: user quota information was cleared.\n" "User quotas can not be enforced until limit information is recreated.\n" msgstr "" "Uwaga: informacje o limitach użytkowników były wyczyszczone.\n" "Limity użytkowników nie mogą być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:800 msgid "" "Warning: user quota information would be cleared.\n" "User quotas could not be enforced until limit information was recreated.\n" msgstr "" "Uwaga: informacje o limitach użytkowników zostałyby wyczyszczone.\n" "Limity użytkowników nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:808 msgid "" "Warning: group quota information was cleared.\n" "Group quotas can not be enforced until limit information is recreated.\n" msgstr "" "Uwaga: informacje o limitach grup były wyczyszczone.\n" "Limity grup nie mogą być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:812 msgid "" "Warning: group quota information would be cleared.\n" "Group quotas could not be enforced until limit information was recreated.\n" msgstr "" "Uwaga: informacje o limitach grup zostałyby wyczyszczone.\n" "Limity grup nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:820 msgid "" "Warning: project quota information was cleared.\n" "Project quotas can not be enforced until limit information is recreated.\n" msgstr "" "Uwaga: informacje o limitach projektów były wyczyszczone.\n" "Limity projektów nie mogą być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:824 msgid "" "Warning: project quota information would be cleared.\n" "Project quotas could not be enforced until limit information was recreated.\n" msgstr "" "Uwaga: informacje o limitach projektów zostałyby wyczyszczone.\n" "Limity projektów nie mogłyby być wymuszone do czasu odtworzenia informacji.\n" #: .././repair/xfs_repair.c:835 msgid "No modify flag set, skipping filesystem flush and exiting.\n" msgstr "Flaga braku modyfikacji ustawiona, pominięto zrzucanie systemu plików, zakończono.\n" #: .././repair/xfs_repair.c:849 .././repair/phase5.c:1360 msgid "couldn't get superblock\n" msgstr "nie udało się pobrać superbloku\n" #: .././repair/xfs_repair.c:854 msgid "Note - quota info will be regenerated on next quota mount.\n" msgstr "Uwaga - informacje o limitach zostaną ponownie wygenerowane przy następnym montowaniu.\n" #: .././repair/xfs_repair.c:862 #, c-format msgid "" "Note - stripe unit (%d) and width (%d) fields have been reset.\n" "Please set with mount -o sunit=,swidth=\n" msgstr "" "Uwaga - pola jednostki pasa (%d) i szerokości pasa (%d) zostały przestawione.\n" "Proszę ustawić przy użyciu mount -o sunit=,swidth=\n" #: .././repair/xfs_repair.c:885 msgid "done\n" msgstr "gotowe\n" #: .././repair/avl64.c:1032 .././repair/avl.c:1011 #, c-format msgid "avl_insert: Warning! duplicate range [%llu,%llu]\n" msgstr "avl_insert: Uwaga! powtórzony przedział [%llu,%llu]\n" #: .././repair/avl64.c:1227 .././repair/avl.c:1206 #, c-format msgid "Command [fpdir] : " msgstr "Polecenie [fpdir] : " #: .././repair/avl64.c:1236 .././repair/avl.c:1215 #, c-format msgid "end of range ? " msgstr "koniec przedziału? " #: .././repair/avl64.c:1247 .././repair/avl.c:1226 #, c-format msgid "Cannot find %d\n" msgstr "Nie można odnaleźć %d\n" #: .././repair/avl64.c:1260 .././repair/avl.c:1239 #, c-format msgid "size of range ? " msgstr "rozmiar przedziału? " #: .././repair/avl64.c:1271 .././repair/avl.c:1250 #, c-format msgid "End of range ? " msgstr "Koniec przedziału? " #: .././repair/avl64.c:1275 .././repair/avl.c:1254 #, c-format msgid "checklen 0/1 ? " msgstr "checklen 0/1 ? " #: .././repair/avl64.c:1282 .././repair/avl.c:1261 #, c-format msgid "Found something\n" msgstr "Znaleziono coś\n" #: .././repair/phase7.c:43 #, c-format msgid "resetting inode % nlinks from %u to %u\n" msgstr "przestawiono nlinks i-węzła % z %u na %u\n" #: .././repair/phase7.c:49 #, c-format msgid "nlinks %u will overflow v1 ino, ino % will be converted to version 2\n" msgstr "nlinks %u przepełni i-węzeł v1, i-węzeł % będzie skonwertowany do wersji 2\n" #: .././repair/phase7.c:56 #, c-format msgid "would have reset inode % nlinks from %u to %u\n" msgstr "nlinks i-węzła % zostałoby przestawione z %u na %u\n" #: .././repair/phase7.c:85 .././repair/phase6.c:3267 .././repair/phase6.c:3271 #, c-format msgid "couldn't map inode %, err = %d\n" msgstr "nie udało się odwzorować i-węzła %, błąd = %d\n" #: .././repair/phase7.c:89 #, c-format msgid "couldn't map inode %, err = %d, can't compare link counts\n" msgstr "nie udało się odwzorować i-węzła %, błąd %d, nie można porównać liczby dowiązań\n" #: .././repair/phase7.c:128 msgid "Phase 7 - verify and correct link counts...\n" msgstr "Faza 7 - sprawdzanie i poprawianie liczby dowiązań...\n" #: .././repair/phase7.c:130 msgid "Phase 7 - verify link counts...\n" msgstr "Faza 7 - sprawdzanie liczby dowiązań...\n" #: .././repair/threads.c:90 #, c-format msgid "cannot create worker threads, error = [%d] %s\n" msgstr "nie można utworzyć wątków pracujących, błąd: [%d] %s\n" #: .././repair/threads.c:108 #, c-format msgid "cannot allocate worker item, error = [%d] %s\n" msgstr "nie można przydzielić elementu pracującego, błąd: [%d] %s\n" #: .././repair/prefetch.c:465 msgid "prefetch corruption\n" msgstr "uszkodzenie prefetch\n" #: .././repair/prefetch.c:611 .././repair/prefetch.c:711 #, c-format msgid "failed to create prefetch thread: %s\n" msgstr "nie udało się utworzyć wątku prefetch: %s\n" #: .././repair/prefetch.c:748 msgid "failed to initialize prefetch mutex\n" msgstr "nie udało się zainicjować muteksu prefetch\n" #: .././repair/prefetch.c:750 .././repair/prefetch.c:752 msgid "failed to initialize prefetch cond var\n" msgstr "nie udało się zainicjować zmiennej warunkowej prefetch\n" #: .././repair/phase5.c:211 msgid "could not set up btree block array\n" msgstr "nie udało się utworzyć tablicy bloków b-drzewa\n" #: .././repair/phase5.c:223 msgid "error - not enough free space in filesystem\n" msgstr "błąd - za mało wolnego miejsca w systemie plików\n" #: .././repair/phase5.c:438 #, c-format msgid "can't rebuild fs trees -- not enough free space on ag %u\n" msgstr "nie można przebudować drzew systemu plików - za mało wolnego miejsca w ag %u\n" #: .././repair/phase5.c:462 #, c-format msgid "ag %u - not enough free space to build freespace btrees\n" msgstr "ag %u - za mało wolnego miejsca na przebudowanie b-drzew wolnego miejsca\n" #: .././repair/phase5.c:497 #, c-format msgid "not enough free blocks left to describe all free blocks in AG %u\n" msgstr "za mało wolnych bloków na opisanie wszystkich wolnych bloków w AG %u\n" #: .././repair/phase5.c:1310 #, c-format msgid "lost %d blocks in ag %u\n" msgstr "utracono %d bloków w ag %u\n" #: .././repair/phase5.c:1313 #, c-format msgid "thought we were going to lose %d blocks in ag %u, actually lost %d\n" msgstr "przewidywano utracenie %d bloków w ag %u, a utracono %d\n" #: .././repair/phase5.c:1409 .././repair/phase3.c:76 .././repair/phase4.c:125 #: .././repair/phase6.c:3624 #, c-format msgid " - agno = %d\n" msgstr " - agno = %d\n" #: .././repair/phase5.c:1432 #, c-format msgid "unable to rebuild AG %u. Not enough free space in on-disk AG.\n" msgstr "nie udało się przebudować AG %u. Za mało wolnego miejsca w AG na dysku.\n" #: .././repair/phase5.c:1467 #, c-format msgid "unable to rebuild AG %u. No free space.\n" msgstr "nie udało się przebudować AG %u. Brak wolnego miejsca.\n" #: .././repair/phase5.c:1494 #, c-format msgid "lost %d blocks in agno %d, sorry.\n" msgstr "niestety utracono %d bloków w agno %d.\n" #: .././repair/phase5.c:1563 msgid "Phase 5 - rebuild AG headers and trees...\n" msgstr "Faza 5 - przebudowywanie nagłówków i drzew AG...\n" #: .././repair/phase5.c:1593 msgid "cannot alloc sb_icount_ag buffers\n" msgstr "nie można przydzielić buforów sb_icount_ag\n" #: .././repair/phase5.c:1597 msgid "cannot alloc sb_ifree_ag buffers\n" msgstr "nie można przydzielić buforów sb_ifree_ag\n" #: .././repair/phase5.c:1601 msgid "cannot alloc sb_fdblocks_ag buffers\n" msgstr "nie można przydzielić buforów sb_fdblocks_ag\n" #: .././repair/phase5.c:1620 msgid " - generate realtime summary info and bitmap...\n" msgstr " - generowanie opisu i bitmapy realtime...\n" #: .././repair/phase5.c:1625 msgid " - reset superblock...\n" msgstr " - przestawianie superbloku...\n" #: .././repair/agheader.c:35 #, c-format msgid "bad magic # 0x%x for agf %d\n" msgstr "błędna liczba magiczna 0x%x dla agf %d\n" #: .././repair/agheader.c:44 #, c-format msgid "bad version # %d for agf %d\n" msgstr "błędny numer wersji %d dla agf %d\n" #: .././repair/agheader.c:53 #, c-format msgid "bad sequence # %d for agf %d\n" msgstr "błędny numer sekwencji %d dla agf %d\n" #: .././repair/agheader.c:63 #, c-format msgid "bad length %d for agf %d, should be %d\n" msgstr "błędna długość %d dla agf %d, powinno być %d\n" #: .././repair/agheader.c:76 #, c-format msgid "bad length %d for agf %d, should be %\n" msgstr "błędna długość %d dla agf %d, powinno być %\n" #: .././repair/agheader.c:90 #, c-format msgid "flfirst %d in agf %d too large (max = %zu)\n" msgstr "flfirst %d w agf %d zbyt duże (maksimum = %zu)\n" #: .././repair/agheader.c:98 #, c-format msgid "fllast %d in agf %d too large (max = %zu)\n" msgstr "fllast %d w agf %d zbyt duże (maksimum = %zu)\n" #: .././repair/agheader.c:120 #, c-format msgid "bad magic # 0x%x for agi %d\n" msgstr "błędna liczba magiczna 0x%x dla agi %d\n" #: .././repair/agheader.c:129 #, c-format msgid "bad version # %d for agi %d\n" msgstr "błędny numer wersji %d dla agi %d\n" #: .././repair/agheader.c:138 #, c-format msgid "bad sequence # %d for agi %d\n" msgstr "błędny numer sekwencji %d dla agi %d\n" #: .././repair/agheader.c:148 #, c-format msgid "bad length # %d for agi %d, should be %d\n" msgstr "błędna długość %d dla agi %d, powinno być %d\n" #: .././repair/agheader.c:161 #, c-format msgid "bad length # %d for agi %d, should be %\n" msgstr "błędna długość %d dla agi %d, powinno być %\n" #: .././repair/agheader.c:271 #, c-format msgid "zeroing unused portion of %s superblock (AG #%u)\n" msgstr "zerowanie nieużywanej części superbloku %s (AG #%u)\n" #: .././repair/agheader.c:272 .././repair/agheader.c:278 msgid "primary" msgstr "głównego" #: .././repair/agheader.c:272 .././repair/agheader.c:278 msgid "secondary" msgstr "zapasowego" #: .././repair/agheader.c:277 #, c-format msgid "would zero unused portion of %s superblock (AG #%u)\n" msgstr "nieużywana część superbloku %s (AG #%u) zostałaby wyzerowana\n" #: .././repair/agheader.c:296 #, c-format msgid "bad flags field in superblock %d\n" msgstr "błędne pole flag w superbloku %d\n" #: .././repair/agheader.c:313 #, c-format msgid "non-null user quota inode field in superblock %d\n" msgstr "niezerowe pole i-węzła limitów użytkowników w superbloku %d\n" #: .././repair/agheader.c:326 #, c-format msgid "non-null group quota inode field in superblock %d\n" msgstr "niezerowe pole i-węzła limitów grup w superbloku %d\n" #: .././repair/agheader.c:338 #, c-format msgid "non-null quota flags in superblock %d\n" msgstr "niezerowe flagi limitów w superbloku %d\n" #: .././repair/agheader.c:356 #, c-format msgid "bad shared version number in superblock %d\n" msgstr "błędny numer wersji dzielonej w superbloku %d\n" #: .././repair/agheader.c:368 #, c-format msgid "bad inode alignment field in superblock %d\n" msgstr "błędne pole wyrównania i-węzłów w superbloku %d\n" #: .././repair/agheader.c:381 #, c-format msgid "bad stripe unit/width fields in superblock %d\n" msgstr "błędne pola jednostki/szerokości pasa w superbloku %d\n" #: .././repair/agheader.c:399 #, c-format msgid "bad log/data device sector size fields in superblock %d\n" msgstr "błędne pola rozmiaru sektora urządzenia logu/danych w superbloku %d\n" #: .././repair/agheader.c:430 #, c-format msgid "bad on-disk superblock %d - %s\n" msgstr "błędny superblok %d na dysku - %s\n" #: .././repair/agheader.c:437 #, c-format msgid "primary/secondary superblock %d conflict - %s\n" msgstr "konflikt głównego/zapasowego superbloku %d - %s\n" #: .././repair/versions.c:73 #, c-format msgid "bogus quota flags 0x%x set in superblock" msgstr "niepoprawne flagi limitów 0x%x ustawione w superbloku" #: .././repair/versions.c:86 msgid ", bogus flags will be cleared\n" msgstr ", błędne flagi zostaną wyczyszczone\n" #: .././repair/versions.c:88 msgid ", bogus flags would be cleared\n" msgstr ", błędne flagi zostałyby wyczyszczone\n" #: .././repair/versions.c:141 msgid "This filesystem has uninitialized extent flags.\n" msgstr "Ten system plików ma niezainicjowane flagi ekstentów.\n" #: .././repair/versions.c:149 msgid "This filesystem is marked shared.\n" msgstr "Ten system plików jest oznaczony jako współdzielony.\n" #: .././repair/versions.c:155 msgid "" "This filesystem uses feature(s) not yet supported in this release.\n" "Please run a more recent version of xfs_repair.\n" msgstr "" "Ten system plików używa możliwości jeszcze nie obsługiwanych w tym wydaniu.\n" "Proszę uruchomić nowszą wersję xfs_repair.\n" #: .././repair/versions.c:161 #, c-format msgid "WARNING: unknown superblock version %d\n" msgstr "UWAGA: nieznana wersja superbloku %d\n" #: .././repair/versions.c:164 msgid "This filesystem contains features not understood by this program.\n" msgstr "Ten system plików zawiera cechę nie rozumianą przez ten program.\n" #: .././repair/versions.c:172 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twill be downgraded. This may cause loss of filesystem meta-data\n" msgstr "" "UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" "\tsuperblok ma ustawione bity cech. Superblok zostanie zdegradowany.\n" "\tMoże to spowodować utratę metadanych systemu plików.\n" #: .././repair/versions.c:177 msgid "" "WARNING: you have disallowed superblock-feature-bits-allowed\n" "\tbut this superblock has feature bits. The superblock\n" "\twould be downgraded. This might cause loss of filesystem\n" "\tmeta-data.\n" msgstr "" "UWAGA: zabroniono superblock-feature-bits-allowed, ale ten\n" "\tsuperblok ma ustawione bity cech. Superblok zostałby zdegradowany.\n" "\tMogłoby to spowodować utratę metadanych systemu plików.\n" #: .././repair/versions.c:191 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attributes will be removed.\n" msgstr "" "UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" "\tatrybuty. System plików zostanie zdegradowany, a wszystkie\n" "\tatrybuty usunięte.\n" #: .././repair/versions.c:196 msgid "" "WARNING: you have disallowed attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attributes would be removed.\n" msgstr "" "UWAGA: zabroniono używania atrybutów, ale ten system plików zawiera\n" "\tatrybuty. System plików zostałby zdegradowany, a wszystkie\n" "\tatrybuty usunięte.\n" #: .././repair/versions.c:209 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem will be downgraded and\n" "\tall attr2 attributes will be removed.\n" msgstr "" "UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" "\tzawiera atrybuty. System plików zostanie zdegradowany, a wszystkie\n" "\tatrybuty attr2 usunięte.\n" #: .././repair/versions.c:214 msgid "" "WARNING: you have disallowed attr2 attributes but this filesystem\n" "\thas attributes. The filesystem would be downgraded and\n" "\tall attr2 attributes would be removed.\n" msgstr "" "UWAGA: zabroniono używania atrybutów attr2, ale ten system plików\n" "\tzawiera atrybuty. System plików zostałby zdegradowany, a wszystkie\n" "\tatrybuty attr2 usunięte.\n" #: .././repair/versions.c:227 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem will be downgraded and\n" "\tall version 2 inodes will be converted to version 1 inodes.\n" "\tThis may cause some hard links to files to be destroyed\n" msgstr "" "UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" "\tzawiera i-węzły w wersji 2. System plików zostanie zdegradowany,\n" "\ta wszystkie i-węzły w wersji 2 zostaną przekonwertowane do wersji 1.\n" "\tMoże to spowodować zniszczenie niektórych twardych dowiązań do\n" "\tplików.\n" #: .././repair/versions.c:233 msgid "" "WARNING: you have disallowed version 2 inodes but this filesystem\n" "\thas version 2 inodes. The filesystem would be downgraded and\n" "\tall version 2 inodes would be converted to version 1 inodes.\n" "\tThis might cause some hard links to files to be destroyed\n" msgstr "" "UWAGA: zabroniono używania i-węzłów w wersji 2, ale ten system plików\n" "\tzawiera i-węzły w wersji 2. System plików zostałby zdegradowany,\n" "\ta wszystkie i-węzły w wersji 2 zostałyby przekonwertowane do\n" "\twersji 1. Mogłoby to spowodować zniszczenie niektórych twardych\n" "\tdowiązań do plików.\n" #: .././repair/versions.c:247 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem will be downgraded and\n" "\tall quota information will be removed.\n" msgstr "" "UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" "\tzawiera limity. System plików zostanie zdegradowany, a wszystkie\n" "\tinformacje o limitach usunięte.\n" #: .././repair/versions.c:252 msgid "" "WARNING: you have disallowed quotas but this filesystem\n" "\thas quotas. The filesystem would be downgraded and\n" "\tall quota information would be removed.\n" msgstr "" "UWAGA: zabroniono używania limitów (quot), ale ten system plików\n" "\tzawiera limity. System plików zostałby zdegradowany, a wszystkie\n" "\tinformacje o limitach usunięte.\n" #: .././repair/versions.c:276 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem will be downgraded.\n" "\tThis will permanently degrade the performance of this filesystem.\n" msgstr "" "UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" "\tzawiera wyrównane i-węzły. System plików zostanie zdegradowany.\n" "\tTrwale zdegraduje to wydajność tego systemu plików.\n" #: .././repair/versions.c:281 msgid "" "WARNING: you have disallowed aligned inodes but this filesystem\n" "\thas aligned inodes. The filesystem would be downgraded.\n" "\tThis would permanently degrade the performance of this filesystem.\n" msgstr "" "UWAGA: zabroniono używania wyrównanych i-węzłów, ale ten system plików\n" "\tzawiera wyrównane i-węzły. System plików zostałby zdegradowany.\n" "\tTrwale zdegradowałoby to wydajność tego systemu plików.\n" #: .././repair/init.c:47 #, c-format msgid "getrlimit(RLIMIT_FSIZE) failed!\n" msgstr "getrlimit(RLIMIT_FSIZE) nie powiodło się!\n" #: .././repair/init.c:55 #, c-format msgid "setrlimit failed - current: %lld, max: %lld\n" msgstr "setrlimit nie powiodło się - bieżący: %lld, max: %lld\n" #: .././repair/init.c:102 msgid "couldn't initialize XFS library\n" msgstr "nie udało się zainicjować biblioteki XFS\n" #: .././repair/phase1.c:28 msgid "Sorry, could not find valid secondary superblock\n" msgstr "Niestety nie znaleziono poprawnego zapasowego superbloku\n" #: .././repair/phase1.c:29 msgid "Exiting now.\n" msgstr "Zakończono.\n" #: .././repair/phase1.c:40 #, c-format msgid "could not allocate ag header buffer (%d bytes)\n" msgstr "nie udało się przydzielić bufora nagłówka ag (%d bajtów)\n" #: .././repair/phase1.c:58 msgid "Phase 1 - find and verify superblock...\n" msgstr "Faza 1 - szukanie i sprawdzanie superbloku...\n" #: .././repair/phase1.c:74 msgid "error reading primary superblock\n" msgstr "błąd podczas odczytu głównego superbloku\n" #: .././repair/phase1.c:80 #, c-format msgid "bad primary superblock - %s !!!\n" msgstr "błędny główny superblok - %s!!!\n" #: .././repair/phase1.c:87 #, c-format msgid "couldn't verify primary superblock - %s !!!\n" msgstr "nie udało się sprawdzić głównego superbloku - %s!!!\n" #: .././repair/phase1.c:105 msgid "superblock has a features2 mismatch, correcting\n" msgstr "superblok ma niepasujące features2, poprawianie\n" #: .././repair/phase1.c:122 #, c-format msgid "Enabling lazy-counters\n" msgstr "Włączanie leniwych liczników\n" #: .././repair/phase1.c:127 #, c-format msgid "Disabling lazy-counters\n" msgstr "Wyłączanie leniwych liczników\n" #: .././repair/phase1.c:130 #, c-format msgid "Lazy-counters are already %s\n" msgstr "Leniwe liczniki już są %s\n" #: .././repair/phase1.c:131 msgid "enabled" msgstr "włączone" #: .././repair/phase1.c:131 msgid "disabled" msgstr "wyłączone" #: .././repair/phase1.c:138 msgid "writing modified primary superblock\n" msgstr "zapisano zmodyfikowany główny superblok\n" #: .././repair/phase1.c:141 msgid "would write modified primary superblock\n" msgstr "zmodyfikowany główny superblok zostałby zapisany\n" #: .././repair/incore.c:230 #, c-format msgid "couldn't allocate realtime block map, size = %\n" msgstr "nie udało się przydzielić mapy bloków realtime, size = %\n" #: .././repair/incore.c:295 msgid "couldn't allocate block map btree roots\n" msgstr "nie udało się przydzielić korzeni b-drzewa mapy bloków\n" #: .././repair/incore.c:299 msgid "couldn't allocate block map locks\n" msgstr "nie udało się przydzielić blokad mapy bloków\n" #: .././repair/dino_chunks.c:58 #, c-format msgid "cannot read agbno (%u/%u), disk block %\n" msgstr "nie można odczytać agbno (%u/%u), blok dysku %\n" #: .././repair/dino_chunks.c:149 #, c-format msgid "uncertain inode block %d/%d already known\n" msgstr "niepewny blok i-węzła %d/%d już znany\n" #: .././repair/dino_chunks.c:165 .././repair/dino_chunks.c:437 #: .././repair/dino_chunks.c:496 #, c-format msgid "inode block %d/%d multiply claimed, (state %d)\n" msgstr "blok i-węzła %d/%d już przypisany (stan %d)\n" #: .././repair/dino_chunks.c:172 .././repair/dino_chunks.c:501 #, c-format msgid "inode block %d/%d bad state, (state %d)\n" msgstr "blok i-węzła (%d/%d) w błędnym stanie (stan %d)\n" #: .././repair/dino_chunks.c:444 #, c-format msgid "uncertain inode block overlap, agbno = %d, ino = %\n" msgstr "niepewny blok i-węzła pokrywa się, agbno = %d, i-węzeł %\n" #: .././repair/dino_chunks.c:483 #, c-format msgid "uncertain inode block % already known\n" msgstr "niepewny blok i-węzła % już znany\n" #: .././repair/dino_chunks.c:620 #, c-format msgid "failed to allocate %zd bytes of memory\n" msgstr "nie udało się przydzielić %zd bajtów pamięci\n" #: .././repair/dino_chunks.c:631 #, c-format msgid "cannot read inode %, disk block %, cnt %d\n" msgstr "nie można odczytać i-węzła %, blok dysku %, cnt %d\n" #: .././repair/dino_chunks.c:747 .././repair/dino_chunks.c:922 #, c-format msgid "bad state in block map %d\n" msgstr "błędny stan w mapie bloku %d\n" #: .././repair/dino_chunks.c:751 .././repair/dino_chunks.c:928 #, c-format msgid "inode block % multiply claimed, state was %d\n" msgstr "blok i-węzła % wielokrotnie przydzielony, stan był %d\n" #: .././repair/dino_chunks.c:788 #, c-format msgid "imap claims in-use inode % is free, " msgstr "imap twierdzi, że używany i-węzeł % jest wolny, " #: .././repair/dino_chunks.c:793 msgid "correcting imap\n" msgstr "poprawiono imap\n" #: .././repair/dino_chunks.c:795 msgid "would correct imap\n" msgstr "imap zostałoby poprawione\n" #: .././repair/dino_chunks.c:841 #, c-format msgid "cleared root inode %\n" msgstr "wyczyszczono główny i-węzeł %\n" #: .././repair/dino_chunks.c:845 #, c-format msgid "would clear root inode %\n" msgstr "główny węzeł % zostałby wyczyszczony\n" #: .././repair/dino_chunks.c:853 #, c-format msgid "cleared realtime bitmap inode %\n" msgstr "wyczyszczono i-węzeł bitmapy realtime %\n" #: .././repair/dino_chunks.c:857 #, c-format msgid "would clear realtime bitmap inode %\n" msgstr "i-węzeł bitmapy realtime % zostałby wyczyszczony\n" #: .././repair/dino_chunks.c:865 #, c-format msgid "cleared realtime summary inode %\n" msgstr "wyczyszczono i-węzeł opisu realtime %\n" #: .././repair/dino_chunks.c:869 #, c-format msgid "would clear realtime summary inode %\n" msgstr "i-węzeł opisu realtime % zostałby wyczyszczony\n" #: .././repair/dino_chunks.c:873 #, c-format msgid "cleared inode %\n" msgstr "wyczyszczono i-węzeł %\n" #: .././repair/dino_chunks.c:876 #, c-format msgid "would have cleared inode %\n" msgstr "i-węzeł % zostałby wyczyszczony\n" #: .././repair/dino_chunks.c:1083 .././repair/dino_chunks.c:1118 #: .././repair/dino_chunks.c:1232 msgid "found inodes not in the inode allocation tree\n" msgstr "znaleziono i-węzły nieobecne w drzewie alokacji i-węzłów\n" #: .././repair/dinode.c:46 #, c-format msgid "clearing inode % attributes\n" msgstr "wyczyszczono atrybuty i-węzła %\n" #: .././repair/dinode.c:49 #, c-format msgid "would have cleared inode % attributes\n" msgstr "atrybuty i-węzła % zostałyby wyczyszczone\n" #: .././repair/dinode.c:424 #, c-format msgid "inode % - bad rt extent start block number %, offset %\n" msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu rt %, offset %\n" #: .././repair/dinode.c:432 #, c-format msgid "inode % - bad rt extent last block number %, offset %\n" msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu rt %, offset %\n" #: .././repair/dinode.c:440 #, c-format msgid "inode % - bad rt extent overflows - start %, end %, offset %\n" msgstr "i-węzeł % - błędne przepełnienie ekstentu rt - początek %, koniec %, offset %\n" #: .././repair/dinode.c:457 #, c-format msgid "malformed rt inode extent [% %] (fs rtext size = %u)\n" msgstr "zniekształcony ekstent i-węzła rt [% %] (rozmiar fs rtext = %u)\n" #: .././repair/dinode.c:478 #, c-format msgid "data fork in rt ino % claims dup rt extent,off - %, start - %, count %\n" msgstr "gałąź danych w i-węźle rt % odwołuje się do powtórzonego ekstentu rt, offset %, początek %, liczba %\n" #: .././repair/dinode.c:497 #, c-format msgid "bad state in rt block map %\n" msgstr "błędny stan w mapie bloku rt %\n" #: .././repair/dinode.c:503 #, c-format msgid "data fork in rt inode % found metadata block % in rt bmap\n" msgstr "gałąź danych w i-węźle rt % - znaleziono blok metadanych % w bmapie rt\n" #: .././repair/dinode.c:511 #, c-format msgid "data fork in rt inode % claims used rt block %\n" msgstr "gałąź danych w i-węźle rt % odwołuje się do używanego bloku rt %\n" #: .././repair/dinode.c:517 #, c-format msgid "illegal state %d in rt block map %\n" msgstr "niedozwolony stan %d w mapie bloku rt %\n" #: .././repair/dinode.c:568 .././repair/dinode.c:1135 .././repair/scan.c:184 #: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 #: .././db/bmap.c:216 msgid "data" msgstr "danych" #: .././repair/dinode.c:570 .././repair/dinode.c:1137 .././repair/scan.c:186 #: .././db/check.c:2130 .././db/check.c:2142 .././db/check.c:2169 #: .././db/bmap.c:216 msgid "attr" msgstr "atrybutów" #: .././repair/dinode.c:573 msgid "real-time" msgstr "realtime" #: .././repair/dinode.c:575 msgid "regular" msgstr "zwykłym" #: .././repair/dinode.c:585 #, c-format msgid "bmap rec out of order, inode % entry %d [o s c] [% % %], %d [% % %]\n" msgstr "rekord bmap uszkodzony, i-węzeł % wpis %d [o s c] [% % %], %d [% % %]\n" #: .././repair/dinode.c:601 #, c-format msgid "zero length extent (off = %, fsbno = %) in ino %\n" msgstr "ekstent zerowej długości (off = %, fsbno = %) w i-węźle %\n" #: .././repair/dinode.c:632 #, c-format msgid "inode % - bad extent starting block number %, offset %\n" msgstr "i-węzeł % - błędny numer bloku początkowego ekstentu %, offset %\n" #: .././repair/dinode.c:640 #, c-format msgid "inode % - bad extent last block number %, offset %\n" msgstr "i-węzeł % - błędny numer bloku końcowego ekstentu %, offset %\n" #: .././repair/dinode.c:648 #, c-format msgid "inode % - bad extent overflows - start %, end %, offset %\n" msgstr "i-węzeł % - błędne przepełnienie ekstentu - początek %, koniec %, offset %\n" #: .././repair/dinode.c:658 #, c-format msgid "inode % - extent offset too large - start %, count %, offset %\n" msgstr "i-węzeł % - offset ekstentu zbyt duży - początek %, liczba %, offset %\n" #: .././repair/dinode.c:678 #, c-format msgid "" "Fatal error: inode % - blkmap_set_ext(): %s\n" "\t%s fork, off - %, start - %, cnt %\n" msgstr "" "Błąd krytyczny: i-węzeł % - blkmap_set_ext(): %s\n" "\tgałąź %s, offset %, początek %, liczba %\n" #: .././repair/dinode.c:709 #, c-format msgid "%s fork in ino % claims dup extent, off - %, start - %, cnt %\n" msgstr "gałąź %s w i-węźle % odwołuje się do powtórzonego ekstentu, offset %, początek %, liczba %\n" #: .././repair/dinode.c:728 #, c-format msgid "%s fork in ino % claims free block %\n" msgstr "gałąź %s w i-węźle % odwołuje się do wolnego bloku %\n" #: .././repair/dinode.c:736 #, c-format msgid "bad state in block map %\n" msgstr "błędny stan w mapie bloku %\n" #: .././repair/dinode.c:742 #, c-format msgid "%s fork in inode % claims metadata block %\n" msgstr "gałąź %s w i-węźle % odwołuje się do bloku metadanych %\n" #: .././repair/dinode.c:750 #, c-format msgid "%s fork in %s inode % claims used block %\n" msgstr "gałąź %s w i-węźle %s % odwołuje się do używanego bloku %\n" #: .././repair/dinode.c:756 #, c-format msgid "illegal state %d in block map %\n" msgstr "niedozwolony stan %d w mapie bloku %\n" #: .././repair/dinode.c:769 #, c-format msgid "correcting nextents for inode %\n" msgstr "poprawiono nextents dla i-węzła %\n" #: .././repair/dinode.c:841 #, c-format msgid "cannot read inode (%u/%u), disk block %\n" msgstr "nie można odczytać i-węzła (%u/%u), blok dysku %\n" #: .././repair/dinode.c:952 .././repair/dinode.c:1009 #, c-format msgid "cannot read bmap block %\n" msgstr "nie można odczytać bloku bmap %\n" #: .././repair/dinode.c:973 #, c-format msgid "# of bmap records in inode % exceeds max (%u, max - %u)\n" msgstr "liczba rekordów bmap w i-węźle % przekracza maksimum (%u, maksimum %u)\n" #: .././repair/dinode.c:981 #, c-format msgid "- # of bmap records in inode % less than minimum (%u, min - %u), proceeding ...\n" msgstr "- liczba rekordów bmap w i-węźle % mniejsza niż minimum (%u, minimum %u), kontynuacja...\n" #: .././repair/dinode.c:1023 #, c-format msgid "# of bmap records in inode % greater than maximum (%u, max - %u)\n" msgstr "liczba rekordów bmap w i-węźle % większa niż maksimum (%u, maksimum %u)\n" #: .././repair/dinode.c:1030 #, c-format msgid "- # of bmap records in inode % less than minimum (%u, min - %u), continuing...\n" msgstr "- liczba rekordów bmap w i-węźle % mniejsza niż minimum (%u, minimum %u), kontynuacja...\n" #: .././repair/dinode.c:1046 #, c-format msgid "could not map block %\n" msgstr "nie udało się odwzorować bloku %\n" #: .././repair/dinode.c:1080 #, c-format msgid "get_bmapi() called for local inode %\n" msgstr "get_bmapi() wywołano dla lokalnego i-węzła %\n" #: .././repair/dinode.c:1088 #, c-format msgid "bad inode format for inode %\n" msgstr "błędny format i-węzła dla i-węzła %\n" #: .././repair/dinode.c:1152 #, c-format msgid "bad level %d in inode % bmap btree root block\n" msgstr "błędny poziom %d w bloku głównym bmap btree i-węzła %\n" #: .././repair/dinode.c:1158 #, c-format msgid "bad numrecs 0 in inode % bmap btree root block\n" msgstr "błędne numrecs 0 w bloku głównym bmap btree i-węzła %\n" #: .././repair/dinode.c:1167 #, c-format msgid "indicated size of %s btree root (%d bytes) greater than space in inode % %s fork\n" msgstr "oznaczony rozmiar korzenia b-drzewa %s (%d bajtów) większy niż miejsce w i-węźle % gałęzi %s\n" #: .././repair/dinode.c:1187 .././repair/scan.c:406 #, c-format msgid "bad bmap btree ptr 0x%llx in ino %\n" msgstr "błędny wskaźnik bmap btree 0x%llx w i-węźle %\n" #: .././repair/dinode.c:1206 #, c-format msgid "correcting key in bmbt root (was %llu, now %) in inode % %s fork\n" msgstr "poprawiono klucz w korzeniu bmbt (był %llu, jest %) w i-węźle % gałęzi %s\n" #: .././repair/dinode.c:1218 #, c-format msgid "bad key in bmbt root (is %llu, would reset to %) in inode % %s fork\n" msgstr "błędny klucz w korzeniu bmbt (jest %llu, zostałby przestawiony na %) w i-węźle % gałęzi %s\n" #: .././repair/dinode.c:1235 #, c-format msgid "out of order bmbt root key % in inode % %s fork\n" msgstr "niepoprawny klucz korzenia bmbt % w i-węźle % gałęzi %s\n" #: .././repair/dinode.c:1252 #, c-format msgid "extent count for ino % %s fork too low (%) for file format\n" msgstr "i-węzeł %: liczba ekstentów dla odgałęzienia %s zbyt mała (%) dla formatu pliku\n" #: .././repair/dinode.c:1263 #, c-format msgid "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" msgstr "błędny wskaźnik fwd (prawy) (widziano %, powinno być NULLDFSBNO)\n" #: .././repair/dinode.c:1266 #, c-format msgid "\tin inode % (%s fork) bmap btree block %\n" msgstr "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" #: .././repair/dinode.c:1339 #, c-format msgid "local inode % data fork is too large (size = %lld, max = %d)\n" msgstr "gałąź danych lokalnego i-węzła % zbyt duża (rozmiar = %lld, maksimum = %d)\n" #: .././repair/dinode.c:1347 #, c-format msgid "local inode % attr fork too large (size %d, max = %d)\n" msgstr "gałąź atrybutów lokalnego i-węzła % zbyt duża (rozmiar %d, maksimum = %d)\n" #: .././repair/dinode.c:1354 #, c-format msgid "local inode % attr too small (size = %d, min size = %zd)\n" msgstr "gałąź atrybutów lokalnego i-węzła % zbyt mała (rozmiar = %d, minimum = %zd)\n" #: .././repair/dinode.c:1378 #, c-format msgid "mismatch between format (%d) and size (%) in symlink ino %\n" msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" #: .././repair/dinode.c:1385 #, c-format msgid "mismatch between format (%d) and size (%) in symlink inode %\n" msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle dowiązania symbolicznego %\n" #: .././repair/dinode.c:1400 #, c-format msgid "bad number of extents (%d) in symlink % data fork\n" msgstr "błędna liczba ekstentów (%d) w gałęzi danych dowiązania symbolicznego %\n" #: .././repair/dinode.c:1413 #, c-format msgid "bad extent #%d offset (%) in symlink % data fork\n" msgstr "błędny offset ekstentu %d (%) w gałęzi danych dowiązania symbolicznego %\n" #: .././repair/dinode.c:1419 #, c-format msgid "bad extent #%d count (%) in symlink % data fork\n" msgstr "błędna liczba ekstentów #%d (%) w gałęzi danych dowiązania symbolicznego %\n" #: .././repair/dinode.c:1474 #, c-format msgid "symlink in inode % too long (%llu chars)\n" msgstr "dowiązanie symboliczne w i-węźle % zbyt długie (%llu znaków)\n" #: .././repair/dinode.c:1507 #, c-format msgid "cannot read inode %, file block %d, disk block %\n" msgstr "nie można odczytać i-węzła %, blok pliku %d, blok dysku %\n" #: .././repair/dinode.c:1529 #, c-format msgid "found illegal null character in symlink inode %\n" msgstr "znaleziono niedozwolony znak null w i-węźle dowiązania symbolicznego %\n" #: .././repair/dinode.c:1543 .././repair/dinode.c:1553 #, c-format msgid "component of symlink in inode % too long\n" msgstr "składnik dowiązania symbolicznego w i-węźle % zbyt długi\n" #: .././repair/dinode.c:1579 #, c-format msgid "inode % has bad inode type (IFMNT)\n" msgstr "i-węzeł % ma błędny typ i-węzła (IFMNT)\n" #: .././repair/dinode.c:1590 #, c-format msgid "size of character device inode % != 0 (% bytes)\n" msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bajtów)\n" #: .././repair/dinode.c:1595 #, c-format msgid "size of block device inode % != 0 (% bytes)\n" msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bajtów)\n" #: .././repair/dinode.c:1600 #, c-format msgid "size of socket inode % != 0 (% bytes)\n" msgstr "rozmiar i-węzła gniazda % != 0 (% bajtów)\n" #: .././repair/dinode.c:1605 #, c-format msgid "size of fifo inode % != 0 (% bytes)\n" msgstr "rozmiar i-węzła potoku % != 0 (% bajtów)\n" #: .././repair/dinode.c:1609 #, c-format msgid "Internal error - process_misc_ino_types, illegal type %d\n" msgstr "Błąd wewnętrzny - process_misc_ino_types, niedozwolony typ %d\n" #: .././repair/dinode.c:1636 #, c-format msgid "size of character device inode % != 0 (% blocks)\n" msgstr "rozmiar i-węzła urządzenia znakowego % != 0 (% bloków)\n" #: .././repair/dinode.c:1641 #, c-format msgid "size of block device inode % != 0 (% blocks)\n" msgstr "rozmiar i-węzła urządzenia blokowego % != 0 (% bloków)\n" #: .././repair/dinode.c:1646 #, c-format msgid "size of socket inode % != 0 (% blocks)\n" msgstr "rozmiar i-węzła gniazda % != 0 (% bloków)\n" #: .././repair/dinode.c:1651 #, c-format msgid "size of fifo inode % != 0 (% blocks)\n" msgstr "rozmiar i-węzła potoku % != 0 (% bloków)\n" #: .././repair/dinode.c:1729 #, c-format msgid "root inode % has bad type 0x%x\n" msgstr "i-węzeł główny % ma błędny typ 0x%x\n" #: .././repair/dinode.c:1733 msgid "resetting to directory\n" msgstr "przestawiono na katalog\n" #: .././repair/dinode.c:1737 msgid "would reset to directory\n" msgstr "zostałby przestawiony na katalog\n" #: .././repair/dinode.c:1743 #, c-format msgid "user quota inode % has bad type 0x%x\n" msgstr "i-węzeł limitu użytkownika % ma błędny typ 0x%x\n" #: .././repair/dinode.c:1752 #, c-format msgid "group quota inode % has bad type 0x%x\n" msgstr "i-węzeł limitu grupy % ma błędny typ 0x%x\n" #: .././repair/dinode.c:1762 #, c-format msgid "realtime summary inode % has bad type 0x%x, " msgstr "i-węzeł opisu realtime % ma błędny typ 0x%x, " #: .././repair/dinode.c:1765 .././repair/dinode.c:1786 msgid "resetting to regular file\n" msgstr "przestawiono na zwykły plik\n" #: .././repair/dinode.c:1769 .././repair/dinode.c:1790 msgid "would reset to regular file\n" msgstr "zostałby przestawiony na zwykły plik\n" #: .././repair/dinode.c:1774 #, c-format msgid "bad # of extents (%u) for realtime summary inode %\n" msgstr "błędna liczba ekstentów (%u) dla i-węzłą opisu realtime %\n" #: .././repair/dinode.c:1783 #, c-format msgid "realtime bitmap inode % has bad type 0x%x, " msgstr "i-węzeł bitmapy realtime % ma błędny typ 0x%x, " #: .././repair/dinode.c:1795 #, c-format msgid "bad # of extents (%u) for realtime bitmap inode %\n" msgstr "błędna liczba ekstentów (%u) dla i-węzłą bitmapy realtime %\n" #: .././repair/dinode.c:1830 #, c-format msgid "mismatch between format (%d) and size (%) in directory ino %\n" msgstr "niezgodność między formatem (%d) a rozmiarem (%) w i-węźle katalogu %\n" #: .././repair/dinode.c:1836 #, c-format msgid "directory inode % has bad size %\n" msgstr "i-węzeł katalogu % ma błędny rozmiar %\n" #: .././repair/dinode.c:1844 #, c-format msgid "bad data fork in symlink %\n" msgstr "błędna gałąź danych w dowiązaniu symbolicznym %\n" #: .././repair/dinode.c:1865 #, c-format msgid "found inode % claiming to be a real-time file\n" msgstr "znaleziono i-węzeł % twierdzący, że należy do pliku realtime\n" #: .././repair/dinode.c:1874 #, c-format msgid "realtime bitmap inode % has bad size % (should be %)\n" msgstr "i-węzeł bitmapy realtime % ma błędny rozmiar % (powinien być %)\n" #: .././repair/dinode.c:1885 #, c-format msgid "realtime summary inode % has bad size % (should be %d)\n" msgstr "i-węzeł opisu realtime % ma błędny rozmiar % (powinien być %d)\n" #: .././repair/dinode.c:1913 #, c-format msgid "bad attr fork offset %d in dev inode %, should be %d\n" msgstr "błędny offset gałęzi atrybutów %d w i-węźle urządzenia %, powinien być %d\n" #: .././repair/dinode.c:1924 #, c-format msgid "bad attr fork offset %d in inode %, max=%d\n" msgstr "błędny offset gałęzi atrybutów %d w i-węźle %, maksimum=%d\n" #: .././repair/dinode.c:1931 #, c-format msgid "unexpected inode format %d\n" msgstr "nieoczekiwany format i-węzła %d\n" #: .././repair/dinode.c:1952 #, c-format msgid "correcting nblocks for inode %, was %llu - counted %\n" msgstr "poprawiono nblocks dla i-węzła % - było %llu, naliczono %\n" #: .././repair/dinode.c:1959 #, c-format msgid "bad nblocks %llu for inode %, would reset to %\n" msgstr "błędne nblocks %llu dla i-węzła %, zostałoby przestawione na %\n" #: .././repair/dinode.c:1967 #, c-format msgid "too many data fork extents (%) in inode %\n" msgstr "zbyt dużo ekstentów gałęzi danych (%) w i-węźle %\n" #: .././repair/dinode.c:1974 #, c-format msgid "correcting nextents for inode %, was %d - counted %\n" msgstr "poprawiono nextents dla i-węzła % - było %d, naliczono %\n" #: .././repair/dinode.c:1982 #, c-format msgid "bad nextents %d for inode %, would reset to %\n" msgstr "błędne nextents %d dla i-węzła %, zostałoby przestawione na %\n" #: .././repair/dinode.c:1990 #, c-format msgid "too many attr fork extents (%) in inode %\n" msgstr "zbyt dużo ekstentów gałęzi atrybutów (%) w i-węźle %\n" #: .././repair/dinode.c:1997 #, c-format msgid "correcting anextents for inode %, was %d - counted %\n" msgstr "poprawiono anextents dla i-węzła % - było %d, naliczono %\n" #: .././repair/dinode.c:2004 #, c-format msgid "bad anextents %d for inode %, would reset to %\n" msgstr "błędne anextents %d dla i-węzła %, zostałoby przestawione na %\n" #: .././repair/dinode.c:2016 #, c-format msgid "nblocks (%) smaller than nextents for inode %\n" msgstr "nblocks (%) mniejsze niż nextents dla i-węzła %\n" #: .././repair/dinode.c:2069 .././repair/dinode.c:2107 #, c-format msgid "unknown format %d, ino % (mode = %d)\n" msgstr "nieznany format %d, i-węzeł % (tryb = %d)\n" #: .././repair/dinode.c:2074 #, c-format msgid "bad data fork in inode %\n" msgstr "błędna gałąź danych w i-węźle %\n" #: .././repair/dinode.c:2145 #, c-format msgid "bad attribute format %d in inode %, " msgstr "błędny format atrybutów %d w i-węźle %, " #: .././repair/dinode.c:2148 msgid "resetting value\n" msgstr "przestawiono wartość\n" #: .././repair/dinode.c:2152 msgid "would reset value\n" msgstr "wartość zostałaby przestawiona\n" #: .././repair/dinode.c:2182 .././repair/attr_repair.c:994 #, c-format msgid "illegal attribute format %d, ino %\n" msgstr "niedozwolony format atrybutu %d, i-węzeł %\n" #: .././repair/dinode.c:2197 #, c-format msgid "bad attribute fork in inode %" msgstr "błędna gałąź atrybutów w i-węźle %" #: .././repair/dinode.c:2201 msgid ", clearing attr fork\n" msgstr ", wyczyszczono gałąź atrybutów\n" #: .././repair/dinode.c:2210 msgid ", would clear attr fork\n" msgstr ", gałąź atrybutów zostałaby wyczyszczona\n" #: .././repair/dinode.c:2238 #, c-format msgid "illegal attribute fmt %d, ino %\n" msgstr "niedozwolony format atrybutów %d, i-węzeł %\n" #: .././repair/dinode.c:2258 #, c-format msgid "problem with attribute contents in inode %\n" msgstr "problem z zawartością atrybutu w i-węźle %\n" #: .././repair/dinode.c:2266 msgid "would clear attr fork\n" msgstr "gałąź atrybutów zostałaby wyczyszczona\n" #: .././repair/dinode.c:2309 #, c-format msgid "version 2 inode % claims > %u links, " msgstr "i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " #: .././repair/dinode.c:2313 msgid "updating superblock version number\n" msgstr "uaktualniono numer wersji superbloku\n" #: .././repair/dinode.c:2316 msgid "would update superblock version number\n" msgstr "numer wersji superbloku zostałby uaktualniony\n" #: .././repair/dinode.c:2324 #, c-format msgid "WARNING: version 2 inode % claims > %u links, " msgstr "UWAGA: i-węzeł % w wersji 2 odwołuje się do > %u dowiązań, " #: .././repair/dinode.c:2327 #, c-format msgid "" "converting back to version 1,\n" "this may destroy %d links\n" msgstr "" "przekształcanie z powrotem do wersji 1,\n" "może to zniszczyć %d dowiązań\n" #: .././repair/dinode.c:2337 #, c-format msgid "" "would convert back to version 1,\n" "\tthis might destroy %d links\n" msgstr "" "zostałby przekształcony z powrotem do wersji 1,\n" "\tco mogłoby zniszczyć %d dowiązań\n" #: .././repair/dinode.c:2352 #, c-format msgid "found version 2 inode %, " msgstr "znaleziono i-węzeł % w wersji 2, " #: .././repair/dinode.c:2354 msgid "converting back to version 1\n" msgstr "przekształcono z powrotem do wersji 1\n" #: .././repair/dinode.c:2360 msgid "would convert back to version 1\n" msgstr "zostałby przekształcony z powrotem do wersji 1\n" #: .././repair/dinode.c:2374 #, c-format msgid "clearing obsolete nlink field in version 2 inode %, was %d, now 0\n" msgstr "wyczyszczono przestarzałe pole nlink w i-węźle % w wersji 2 - było %d, jest 0\n" #: .././repair/dinode.c:2380 #, c-format msgid "would clear obsolete nlink field in version 2 inode %, currently %d\n" msgstr "przestarzałe pole nlink w i-węźle % w wersji 2 zostałoby wyczyszczone, aktualnie %d\n" #: .././repair/dinode.c:2449 #, c-format msgid "bad magic number 0x%x on inode %%c" msgstr "błędna liczba magiczna 0x%x w i-węźle %%c" #: .././repair/dinode.c:2454 msgid " resetting magic number\n" msgstr " przestawiono liczbę magiczną\n" #: .././repair/dinode.c:2458 msgid " would reset magic number\n" msgstr " liczba magiczna zostałaby przestawiona\n" #: .././repair/dinode.c:2466 #, c-format msgid "bad version number 0x%x on inode %%c" msgstr "błędny numer wersji 0x%x w i-węźle %%c" #: .././repair/dinode.c:2471 msgid " resetting version number\n" msgstr " przestawiono numer wersji\n" #: .././repair/dinode.c:2475 msgid " would reset version number\n" msgstr " numer wersji zostałby przestawiony\n" #: .././repair/dinode.c:2485 #, c-format msgid "bad (negative) size % on inode %\n" msgstr "błędny (ujemny) rozmiar % w i-węźle %\n" #: .././repair/dinode.c:2518 #, c-format msgid "imap claims a free inode % is in use, " msgstr "imap odwołuje się do wolnego bloku %, który jest w użyciu, " #: .././repair/dinode.c:2520 msgid "correcting imap and clearing inode\n" msgstr "poprawiono imap i wyczyszczono i-węzeł\n" #: .././repair/dinode.c:2524 msgid "would correct imap and clear inode\n" msgstr "poprawiono by imap i wyczyszczono by i-węzeł\n" #: .././repair/dinode.c:2541 #, c-format msgid "bad inode format in inode %\n" msgstr "błędny format i-węzła w i-węźle %\n" #: .././repair/dinode.c:2557 #, c-format msgid "Bad flags set in inode %\n" msgstr "Błędne flagi ustawione w i-węźle %\n" #: .././repair/dinode.c:2568 #, c-format msgid "inode % has RT flag set but there is no RT device\n" msgstr "i-węzeł % ma ustawioną flagę RT, ale nie ma urządzenia RT\n" #: .././repair/dinode.c:2580 #, c-format msgid "inode % not rt bitmap\n" msgstr "i-węzeł % nie jest bitmapą rt\n" #: .././repair/dinode.c:2594 #, c-format msgid "directory flags set on non-directory inode %\n" msgstr "flagi katalogu ustawione dla nie będącego katalogiem i-węzła %\n" #: .././repair/dinode.c:2608 #, c-format msgid "file flags set on non-file inode %\n" msgstr "flagi pliku ustawione dla nie będącego plikiem i-węzła %\n" #: .././repair/dinode.c:2617 msgid ", fixing bad flags.\n" msgstr ", poprawiono błędne flagi.\n" #: .././repair/dinode.c:2621 msgid ", would fix bad flags.\n" msgstr ", poprawionoby błędne flagi.\n" #: .././repair/dinode.c:2672 #, c-format msgid "bad inode type %#o inode %\n" msgstr "błędny typ i-węzła %#o w i-węźle %\n" #: .././repair/dinode.c:2696 #, c-format msgid "bad non-zero extent size %u for non-realtime/extsize inode %, " msgstr "błędny niezerowy rozmiar ekstentu %u dla extsize i-węzła nie-realtime %, " #: .././repair/dinode.c:2699 msgid "resetting to zero\n" msgstr "przestawiono na zero\n" #: .././repair/dinode.c:2703 msgid "would reset to zero\n" msgstr "zostałby przestawiony na zero\n" #: .././repair/dinode.c:2759 #, c-format msgid "problem with directory contents in inode %\n" msgstr "problem z zawartością katalogu w i-węźle %\n" #: .././repair/dinode.c:2767 #, c-format msgid "problem with symbolic link in inode %\n" msgstr "problem z dowiązaniem symbolicznym w i-węźle %\n" #: .././repair/dinode.c:2862 #, c-format msgid "processing inode %d/%d\n" msgstr "analiza i-węzła %d/%d\n" #: .././repair/sb.c:100 msgid "" "\n" "attempting to find secondary superblock...\n" msgstr "" "\n" "próba odnalezienia zapasowego superbloku...\n" #: .././repair/sb.c:105 msgid "error finding secondary superblock -- failed to memalign buffer\n" msgstr "błąd podczas szukania zapasowego superbloku - nie udało się memalign bufora\n" #: .././repair/sb.c:142 msgid "found candidate secondary superblock...\n" msgstr "znaleziono potencjalny zapasowy superblok...\n" #: .././repair/sb.c:154 msgid "verified secondary superblock...\n" msgstr "sprawdzono zapasowy superblok...\n" #: .././repair/sb.c:159 msgid "unable to verify superblock, continuing...\n" msgstr "nie udało się sprawdzić superbloku, kontynuacja...\n" #: .././repair/sb.c:457 msgid "failed to memalign superblock buffer\n" msgstr "nie udało się wykonać memalign dla bufora superbloku\n" #: .././repair/sb.c:464 msgid "couldn't seek to offset 0 in filesystem\n" msgstr "nie udało się wykonać seek na offset 0 w systemie plików\n" #: .././repair/sb.c:472 msgid "primary superblock write failed!\n" msgstr "zapis głównego superbloku nie powiódł się!\n" #: .././repair/sb.c:490 #, c-format msgid "error reading superblock %u -- failed to memalign buffer\n" msgstr "błąd podczas odczytu superbloku %u - nie udało się wykonać memalign dla bufora\n" #: .././repair/sb.c:500 #, c-format msgid "error reading superblock %u -- seek to offset % failed\n" msgstr "błąd podczas odczytu superbloku %u - seek na offset % nie powiódł się\n" #: .././repair/sb.c:508 #, c-format msgid "superblock read failed, offset %, size %d, ag %u, rval %d\n" msgstr "odczyt superbloku nie powiódł się, offset %, rozmiar %d, ag %u, rval %d\n" #: .././repair/sb.c:554 msgid "couldn't malloc geometry structure\n" msgstr "nie udało się przydzielić struktury geometrii\n" #: .././repair/sb.c:706 msgid "calloc failed in verify_set_primary_sb\n" msgstr "calloc nie powiodło się w verify_set_primary_sb\n" #: .././repair/sb.c:777 msgid "" "Only two AGs detected and they do not match - cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" "Wykryto tylko dwie AG i nie zgadzają się - nie można sprawdzić poprawności geometrii systemu plików.\n" "Proszę użyć opcji -o force_geometry, aby kontynuować.\n" #: .././repair/sb.c:793 msgid "" "Only one AG detected - cannot validate filesystem geometry.\n" "Use the -o force_geometry option to proceed.\n" msgstr "" "Wykryto tylko dwie AG - nie można sprawdzić poprawności geometrii systemu plików.\n" "Proszę użyć opcji -o force_geometry, aby kontynuować.\n" #: .././repair/sb.c:808 msgid "Not enough matching superblocks - cannot proceed.\n" msgstr "Za mało pasujących superbloków - nie można kontynuować.\n" #: .././repair/sb.c:823 msgid "could not read superblock\n" msgstr "nie udało się odczytać superbloku\n" #: .././repair/phase3.c:45 #, c-format msgid "cannot read agi block % for ag %u\n" msgstr "nie można odczytać bloku agi % dla ag %u\n" #: .././repair/phase3.c:127 msgid "Phase 3 - for each AG...\n" msgstr "Faza 3 - dla każdej AG...\n" #: .././repair/phase3.c:129 msgid " - scan and clear agi unlinked lists...\n" msgstr " - przeszukiwanie i czyszczenie odłączonych list agi...\n" #: .././repair/phase3.c:131 msgid " - scan (but don't clear) agi unlinked lists...\n" msgstr " - przeszukiwanie (ale nie czyszczenie) odłączonych list agi...\n" #: .././repair/phase3.c:151 msgid " - process known inodes and perform inode discovery...\n" msgstr " - przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów...\n" #: .././repair/phase3.c:162 msgid " - process newly discovered inodes...\n" msgstr " - przetwarzanie nowo rozpoznanych i-węzłów...\n" #: .././repair/scan.c:90 .././repair/scan.c:135 #, c-format msgid "can't read btree block %d/%d\n" msgstr "nie można odczytać bloku b-drzewa %d/%d\n" #: .././repair/scan.c:197 #, c-format msgid "bad magic # %#x in inode % (%s fork) bmbt block %\n" msgstr "błędna liczba magiczna %#x w i-węźle % (gałąź %s) blok bmbt %\n" #: .././repair/scan.c:203 #, c-format msgid "expected level %d got %d in inode %, (%s fork) bmbt block %\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %, (gałęzi %s) blok bmbt %\n" #: .././repair/scan.c:223 #, c-format msgid "" "bad fwd (right) sibling pointer (saw % parent block says %)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" "błędny wskaźnik w przód (prawy) (widziano %, blok nadrzędny mówi %)\n" "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" #: .././repair/scan.c:233 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu parent block says %)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" "błędny wskaźnik wstecz (lewy) (widziano %llu, blok nadrzędny mówi %)\n" "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" #: .././repair/scan.c:248 #, c-format msgid "" "bad back (left) sibling pointer (saw %llu should be NULL (0))\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" "błędny wskaźnik wstecz (lewy) (widziano %llu, powinien być NULL (0))\n" "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" #: .././repair/scan.c:289 #, c-format msgid "inode 0x%bmap block 0x% claimed, state is %d\n" msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" #: .././repair/scan.c:296 #, c-format msgid "inode 0x% bmap block 0x% claimed, state is %d\n" msgstr "i-węzeł 0x% blok bmap 0x% przypisany, stan to %d\n" #: .././repair/scan.c:311 #, c-format msgid "bad state %d, inode % bmap block 0x%\n" msgstr "błędny stan %d, i-węzeł % blok bmap 0x%\n" #: .././repair/scan.c:338 .././repair/scan.c:389 #, c-format msgid "inode % bad # of bmap records (%u, min - %u, max - %u)\n" msgstr "błędna liczba rekordów bmap w i-węźle % (%u, minimum - %u, maksimum - %u)\n" #: .././repair/scan.c:368 #, c-format msgid "out-of-order bmap key (file offset) in inode %, %s fork, fsbno %\n" msgstr "uszkodzony klucz bmap (offset pliku) w i-węźle %, gałęzi %s, fsbno %\n" #: .././repair/scan.c:433 #, c-format msgid "" "correcting bt key (was %llu, now %) in inode %\n" "\t\t%s fork, btree block %\n" msgstr "" "poprawiono klucz bt (było %llu, jest %) w i-węźle %\n" "\t\tgałąź %s, blok b-drzewa %\n" #: .././repair/scan.c:445 #, c-format msgid "" "bad btree key (is %llu, should be %) in inode %\n" "\t\t%s fork, btree block %\n" msgstr "" "błędny klucz b-drzewa (jest %llu, powinno być %) w i-węźle %\n" "\t\tgałąź %s, blok b-drzewa %\n" #: .././repair/scan.c:463 #, c-format msgid "" "bad fwd (right) sibling pointer (saw % should be NULLDFSBNO)\n" "\tin inode % (%s fork) bmap btree block %\n" msgstr "" "błędny wskaźnik w przód (prawy) (widziano %, powinien być NULLDFSBNO)\n" "\tw i-węźle % (gałęzi %s) bloku bmap btree %\n" #: .././repair/scan.c:537 #, c-format msgid "bad magic # %#x in bt%s block %d/%d\n" msgstr "błędna liczba magiczna %#x w bloku bt%s %d/%d\n" #: .././repair/scan.c:555 #, c-format msgid "expected level %d got %d in bt%s block %d/%d\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku bt%s %d/%d\n" #: .././repair/scan.c:569 #, c-format msgid "%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "blok b-drzewa wolnego miejsca %s przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" #: .././repair/scan.c:589 .././repair/scan.c:688 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n" msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bt%s, blok %u/%u\n" #: .././repair/scan.c:607 #, c-format msgid "invalid start block %u in record %u of %s btree block %u/%u\n" msgstr "błędny blok początkowy %u w rekordzie %u bloku b-drzewa %s %u/%u\n" #: .././repair/scan.c:613 #, c-format msgid "invalid length %u in record %u of %s btree block %u/%u\n" msgstr "błędna długość %u w rekordzie %u bloku b-drzewa %s %u/%u\n" #: .././repair/scan.c:621 .././db/check.c:4315 #, c-format msgid "out-of-order bno btree record %d (%u %u) block %u/%u\n" msgstr "rekord b-drzewa bno poza kolejnością: %d (%u %u), blok %u/%u\n" #: .././repair/scan.c:633 .././db/check.c:4392 #, c-format msgid "out-of-order cnt btree record %d (%u %u) block %u/%u\n" msgstr "rekord b-drzewa cnt poza kolejnością: %d (%u %u), blok %u/%u\n" #: .././repair/scan.c:658 #, c-format msgid "block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n" msgstr "blok (%d,%d-%d) wielokrotnie przypisany do drzewa miejsca %s, stan - %d\n" #: .././repair/scan.c:755 #, c-format msgid "badly aligned inode rec (starting inode = %)\n" msgstr "błędnie wyrównany rekord i-węzła (początkowy i-węzeł = %)\n" #: .././repair/scan.c:771 #, c-format msgid "bad starting inode # (% (0x%x 0x%x)) in ino rec, skipping rec\n" msgstr "błędny numer początkowego i-węzła (% (0x%x 0x%x)) w rekordzie i-węzła, pominięto rekord\n" #: .././repair/scan.c:779 #, c-format msgid "bad ending inode # (% (0x%x 0x%zx)) in ino rec, skipping rec\n" msgstr "błędny numer końcowego i-węzła (% (0x%x 0x%zx)) w rekordzie i-węzła, pominięto rekord\n" #: .././repair/scan.c:804 #, c-format msgid "inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n" msgstr "część i-węzła odwołuje się do używanego bloku, blok inobt - agno %d, bno %d, inopb %d\n" #: .././repair/scan.c:826 #, c-format msgid "inode rec for ino % (%d/%d) overlaps existing rec (start %d/%d)\n" msgstr "rekord i-węzła dla i-węzła % (%d/%d) nachodzi na istniejący rekord (początek %d/%d)\n" #: .././repair/scan.c:873 #, c-format msgid "ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n" msgstr "niezgodność ir_freecount/free, porcja i-węzłów %d/%u, freecount %d nfree %d\n" #: .././repair/scan.c:919 #, c-format msgid "bad magic # %#x in inobt block %d/%d\n" msgstr "błędna liczba magiczna %#x w bloku inobt %d/%d\n" #: .././repair/scan.c:927 #, c-format msgid "expected level %d got %d in inobt block %d/%d\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %d/%d\n" #: .././repair/scan.c:949 #, c-format msgid "inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n" msgstr "blok b-drzewa i-węzłów przypisany (stan %d), agno %d, bno %d, podejrzany %d\n" #: .././repair/scan.c:972 #, c-format msgid "dubious inode btree block header %d/%d\n" msgstr "wątpliwy nagłówek bloku b-drzewa i-węzłów %d/%d\n" #: .././repair/scan.c:1065 #, c-format msgid "can't read agfl block for ag %d\n" msgstr "nie można odczytać bloku agfl dla ag %d\n" #: .././repair/scan.c:1076 #, c-format msgid "bad agbno %u in agfl, agno %d\n" msgstr "błędne agbno %u w agfl, agno %d\n" #: .././repair/scan.c:1085 #, c-format msgid "freeblk count %d != flcount %d in ag %d\n" msgstr "liczba freeblk %d != flcount %d w ag %d\n" #: .././repair/scan.c:1107 #, c-format msgid "bad agbno %u for btbno root, agno %d\n" msgstr "błędne agbno %u dla głównego btbno, agno %d\n" #: .././repair/scan.c:1116 #, c-format msgid "bad agbno %u for btbcnt root, agno %d\n" msgstr "błędne agbno %u dla głównego btbcnt, agno %d\n" #: .././repair/scan.c:1121 .././db/check.c:4033 #, c-format msgid "agf_freeblks %u, counted %u in ag %u\n" msgstr "agf_freeblks %u, naliczono %u w ag %u\n" #: .././repair/scan.c:1126 .././db/check.c:4040 #, c-format msgid "agf_longest %u, counted %u in ag %u\n" msgstr "agf_longest %u, naliczono %u w ag %u\n" #: .././repair/scan.c:1132 #, c-format msgid "agf_btreeblks %u, counted % in ag %u\n" msgstr "agf_btreeblks %u, naliczono % w ag %u\n" #: .././repair/scan.c:1151 #, c-format msgid "bad agbno %u for inobt root, agno %d\n" msgstr "błędne agbno %u dla głównego inobt, agno %d\n" #: .././repair/scan.c:1156 .././db/check.c:4056 #, c-format msgid "agi_count %u, counted %u in ag %u\n" msgstr "agi_count %u, naliczono %u w ag %u\n" #: .././repair/scan.c:1161 .././db/check.c:4063 #, c-format msgid "agi_freecount %u, counted %u in ag %u\n" msgstr "agi_freecount %u, naliczono %u w ag %u\n" #: .././repair/scan.c:1170 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%)\n" msgstr "niedowiązany kubełek agi %d to %u w ag %u (i-węzeł=%)\n" #: .././repair/scan.c:1201 #, c-format msgid "can't get root superblock for ag %d\n" msgstr "nie można uzyskać głównego superbloku dla ag %d\n" #: .././repair/scan.c:1207 msgid "can't allocate memory for superblock\n" msgstr "nie można przydzielić pamięci dla superbloku\n" #: .././repair/scan.c:1217 #, c-format msgid "can't read agf block for ag %d\n" msgstr "nie można odczytać bloku agf dla ag %d\n" #: .././repair/scan.c:1228 #, c-format msgid "can't read agi block for ag %d\n" msgstr "nie można odczytać bloku agi dla ag %d\n" #: .././repair/scan.c:1252 #, c-format msgid "reset bad sb for ag %d\n" msgstr "przestawiono błędny superbloku dla ag %d\n" #: .././repair/scan.c:1255 #, c-format msgid "would reset bad sb for ag %d\n" msgstr "błędny superblok dla ag %d zostałby przestawiony\n" #: .././repair/scan.c:1260 #, c-format msgid "reset bad agf for ag %d\n" msgstr "przestawiono błędne agf dla ag %d\n" #: .././repair/scan.c:1263 #, c-format msgid "would reset bad agf for ag %d\n" msgstr "błędne agf dla ag %d zostałoby przestawione\n" #: .././repair/scan.c:1268 #, c-format msgid "reset bad agi for ag %d\n" msgstr "przestawiono błędne agi dla ag %d\n" #: .././repair/scan.c:1271 #, c-format msgid "would reset bad agi for ag %d\n" msgstr "błędna agi dla ag %d zostałoby przestawione\n" #: .././repair/scan.c:1281 #, c-format msgid "bad uncorrected agheader %d, skipping ag...\n" msgstr "błędny nie poprawiony agheader %d, pominięto ag...\n" #: .././repair/scan.c:1340 msgid "no memory for ag header counts\n" msgstr "brak pamięci na liczniki nagłówków ag\n" #: .././repair/scan.c:1363 #, c-format msgid "sb_icount %, counted %\n" msgstr "sb_icount %, naliczono %\n" #: .././repair/scan.c:1368 #, c-format msgid "sb_ifree %, counted %\n" msgstr "sb_ifree %, naliczono %\n" #: .././repair/scan.c:1373 #, c-format msgid "sb_fdblocks %, counted %\n" msgstr "sb_fdblocks %, naliczono %\n" #: .././repair/incore_ext.c:135 .././repair/incore_ext.c:562 msgid "couldn't allocate new extent descriptor.\n" msgstr "nie udało się przydzielić nowego deskryptora ekstentu.\n" #: .././repair/incore_ext.c:232 msgid "duplicate bno extent range\n" msgstr "powtórzony przedział ekstentów bno\n" #: .././repair/incore_ext.c:369 msgid ": duplicate bno extent range\n" msgstr ": powtórzony przedział ekstentów bno\n" #: .././repair/incore_ext.c:644 .././repair/incore_ext.c:699 msgid "duplicate extent range\n" msgstr "powtórzony przedział ekstentów\n" #: .././repair/incore_ext.c:752 .././repair/incore_ext.c:756 msgid "couldn't malloc dup extent tree descriptor table\n" msgstr "nie udało się przydzielić tablicy deskryptorów drzewa powtórzonych ekstentów\n" #: .././repair/incore_ext.c:761 msgid "couldn't malloc free by-bno extent tree descriptor table\n" msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bno\n" #: .././repair/incore_ext.c:766 msgid "couldn't malloc free by-bcnt extent tree descriptor table\n" msgstr "nie udało się przydzielić tablicy deskryptorów drzewa wolnych ekstentów wg bcnt\n" #: .././repair/incore_ext.c:772 msgid "couldn't malloc bno extent tree descriptor\n" msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bno\n" #: .././repair/incore_ext.c:776 msgid "couldn't malloc bcnt extent tree descriptor\n" msgstr "nie udało się przydzielić deskryptora drzewa ekstentów wg bcnt\n" #: .././repair/incore_ext.c:787 msgid "couldn't malloc dup rt extent tree descriptor\n" msgstr "nie udało się przydzielić deskryptora drzewa powtórzonych ekstentów rt\n" #: .././repair/bmap.c:53 #, c-format msgid "" "Number of extents requested in blkmap_alloc (%d) overflows 32 bits.\n" "If this is not a corruption, then you will need a 64 bit system\n" "to repair this filesystem.\n" msgstr "" "Liczba ekstentów żądanych w blkmap_alloc (%d) przepełnia 32 bity.\n" "Jeśli nie jest to efekt uszkodzenia, do naprawy tego systemu plików\n" "niezbędny jest system 64-bitowy.\n" #: .././repair/bmap.c:66 #, c-format msgid "malloc failed in blkmap_alloc (%zu bytes)\n" msgstr "malloc nie powiodło się w blkmap_alloc (%zu bajtów)\n" #: .././repair/bmap.c:173 #, c-format msgid "blkmap_getn malloc failed (% bytes)\n" msgstr "malloc w blkmap_getn nie powiodło się (% bajtów)\n" #: .././repair/bmap.c:253 #, c-format msgid "" "Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n" "You need a 64 bit system to repair this filesystem.\n" msgstr "" "Liczba ekstentów żądanych w blkmap_grow (%d) przepełnia 32 bity.\n" "Do naprawy tego systemu plików niezbędny jest system 64-bitowy.\n" #: .././repair/bmap.c:261 #, c-format msgid "" "Number of extents requested in blkmap_grow (%d) overflowed the\n" "maximum number of supported extents (%d).\n" msgstr "" "Liczba ekstentów żądanych w blkmap_grow (%d) przepełniła maksymalną\n" "liczbę obsługiwanych ekstentów (%d).\n" #: .././repair/bmap.c:269 msgid "realloc failed in blkmap_grow\n" msgstr "realloc nie powiodło się w blkmap_grow\n" #: .././repair/attr_repair.c:105 msgid "entry contains illegal value in attribute named SGI_ACL_FILE or SGI_ACL_DEFAULT\n" msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_ACL_FILE lub SGI_ACL_DEFAULT\n" #: .././repair/attr_repair.c:127 msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_MAC_LABEL\n" #: .././repair/attr_repair.c:133 msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" msgstr "wpis zawiera niedozwoloną wartość w atrybucie SGI_CAP_FILE\n" #: .././repair/attr_repair.c:172 #, c-format msgid "there are no attributes in the fork for inode %\n" msgstr "nie ma atrybutów w gałęzi dla i-węzła %\n" #: .././repair/attr_repair.c:180 #, c-format msgid "would junk the attribute fork since count is 0 for inode %\n" msgstr "gałąź atrybutów zostałaby usunięta ponieważ licznik wynosi 0 dla i-węzła %\n" #: .././repair/attr_repair.c:200 msgid "zero length name entry in attribute fork," msgstr "wpis nazwy zerowej długości w gałęzi atrybutów," #: .././repair/attr_repair.c:203 .././repair/attr_repair.c:223 #, c-format msgid " truncating attributes for inode % to %d\n" msgstr " ucięto atrybuty dla i-węzła % do %d\n" #: .././repair/attr_repair.c:208 .././repair/attr_repair.c:229 #, c-format msgid " would truncate attributes for inode % to %d\n" msgstr " atrybuty dla i-węzła % zostałyby ucięte do %d\n" #: .././repair/attr_repair.c:220 msgid "name or value attribute lengths are too large,\n" msgstr "długości nazwy lub wartości atrybutów są zbyt duże,\n" #: .././repair/attr_repair.c:242 msgid "entry contains illegal character in shortform attribute name\n" msgstr "wpis zawiera niedozwolony znak w nazwie atrybutu krótkiego\n" #: .././repair/attr_repair.c:248 msgid "entry has INCOMPLETE flag on in shortform attribute\n" msgstr "wpis ma flagę NIEPEŁNY w atrybucie krótkim\n" #: .././repair/attr_repair.c:265 #, c-format msgid "removing attribute entry %d for inode %\n" msgstr "usunięto wpis atrybutu %d dla i-węzła %\n" #: .././repair/attr_repair.c:277 #, c-format msgid "would remove attribute entry %d for inode %\n" msgstr "wpis atrybutu %d dla i-węzła % zostałby usunięty\n" #: .././repair/attr_repair.c:292 #, c-format msgid "would have corrected attribute entry count in inode % from %d to %d\n" msgstr "liczba wpisów atrybutów w i-węźle % zostałaby poprawiona z %d na %d\n" #: .././repair/attr_repair.c:296 #, c-format msgid "corrected attribute entry count in inode %, was %d, now %d\n" msgstr "poprawiono liczbę wpisów atrybutów w i-węźle % - było %d, jest %d\n" #: .././repair/attr_repair.c:307 #, c-format msgid "would have corrected attribute totsize in inode % from %d to %d\n" msgstr "totsize atrybutów w i-węźle % zostałby poprawiony z %d na %d\n" #: .././repair/attr_repair.c:312 #, c-format msgid "corrected attribute entry totsize in inode %, was %d, now %d\n" msgstr "poprawiono totsize wpisu atrybutów w i-węźle % - było %d, jest %d\n" #: .././repair/attr_repair.c:342 #, c-format msgid "remote block for attributes of inode % is missing\n" msgstr "brak odległego bloku dla atrybutów i-węzła %\n" #: .././repair/attr_repair.c:350 #, c-format msgid "can't read remote block for attributes of inode %\n" msgstr "nie można odczytać odległego bloku dla atrybutów i-węzła %\n" #: .././repair/attr_repair.c:388 #, c-format msgid "attribute entry %d in attr block %u, inode % has bad name (namelen = %d)\n" msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % ma błędną nazwę (namelen = %d)\n" #: .././repair/attr_repair.c:405 #, c-format msgid "bad hashvalue for attribute entry %d in attr block %u, inode %\n" msgstr "błędna wartość hasza dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" #: .././repair/attr_repair.c:415 #, c-format msgid "bad security value for attribute entry %d in attr block %u, inode %\n" msgstr "błędna wartość bezpieczeństwa dla wpisu atrybutu %d w bloku atrybutów %u, i-węźle %\n" #: .././repair/attr_repair.c:448 #, c-format msgid "inconsistent remote attribute entry %d in attr block %u, ino %\n" msgstr "niespójny wpis odległego atrybutu %d w bloku atrybutów %u, i-węźle %\n" #: .././repair/attr_repair.c:458 #, c-format msgid "cannot malloc enough for remotevalue attribute for inode %\n" msgstr "nie można przydzielić wystarczająco dużo dla atrybutu remotevalue dla i-węzła %\n" #: .././repair/attr_repair.c:460 msgid "SKIPPING this remote attribute\n" msgstr "POMINIĘTO ten atrybut odległy\n" #: .././repair/attr_repair.c:466 #, c-format msgid "remote attribute get failed for entry %d, inode %\n" msgstr "pobranie odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" #: .././repair/attr_repair.c:473 #, c-format msgid "remote attribute value check failed for entry %d, inode %\n" msgstr "sprawdzenie wartości odległego atrybutu nie powiodło się dla wpisu %d, i-węzła %\n" #: .././repair/attr_repair.c:510 #, c-format msgid "bad attribute count %d in attr block %u, inode %\n" msgstr "błędna liczba atrybutów %d w bloku atrybutów %u, i-węźle %\n" #: .././repair/attr_repair.c:525 #, c-format msgid "bad attribute nameidx %d in attr block %u, inode %\n" msgstr "błędny nameidx atrybutu %d w bloku atrybutów %u, i-węźle %\n" #: .././repair/attr_repair.c:534 #, c-format msgid "attribute entry #%d in attr block %u, inode % is INCOMPLETE\n" msgstr "wpis atrybutu #%d w bloku atrybutów %u, i-węźle % jest NIEPEŁNY\n" #: .././repair/attr_repair.c:545 #, c-format msgid "attribute entry %d in attr block %u, inode % claims already used space\n" msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do już użytego miejsca\n" #: .././repair/attr_repair.c:568 #, c-format msgid "attribute entry %d in attr block %u, inode % claims used space\n" msgstr "wpis atrybutu %d w bloku atrybutów %u, i-węźle % odwołuje się do używanego miejsca\n" #: .././repair/attr_repair.c:592 #, c-format msgid "- resetting first used heap value from %d to %d in block %u of attribute fork of inode %\n" msgstr "- przestawiono pierwszą używaną wartość sterty z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" #: .././repair/attr_repair.c:600 #, c-format msgid "- would reset first used value from %d to %d in block %u of attribute fork of inode %\n" msgstr "- pierwsza używana wartość zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" #: .././repair/attr_repair.c:610 #, c-format msgid "- resetting usedbytes cnt from %d to %d in block %u of attribute fork of inode %\n" msgstr "- przestawiono liczbę użytych bajtów z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" #: .././repair/attr_repair.c:618 #, c-format msgid "- would reset usedbytes cnt from %d to %d in block %u of attribute fork of %\n" msgstr "- liczba użytych bajtów zostałaby przestawiona z %d na %d w bloku %u gałęzi atrybutów i-węzła %\n" #: .././repair/attr_repair.c:670 #, c-format msgid "can't map block %u for attribute fork for inode %\n" msgstr "nie można odwzorować bloku %u dla gałęzi atrybutów dla i-węzła %\n" #: .././repair/attr_repair.c:679 #, c-format msgid "can't read file block %u (fsbno %) for attribute fork of inode %\n" msgstr "nie można odczytać bloku pliku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" #: .././repair/attr_repair.c:689 #, c-format msgid "bad attribute leaf magic %#x for inode %\n" msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła %\n" #: .././repair/attr_repair.c:720 #, c-format msgid "bad sibling back pointer for block %u in attribute fork for inode %\n" msgstr "błędny wskaźnik wsteczny dla bloku %u w gałęzi atrybutów dla i-węzła %\n" #: .././repair/attr_repair.c:747 #, c-format msgid "bad hash path in attribute fork for inode %\n" msgstr "błędna ścieżka hasza w gałęzi atrybutów dla i-węzła %\n" #: .././repair/attr_repair.c:846 #, c-format msgid "block 0 of inode % attribute fork is missing\n" msgstr "brak bloku 0 i-węzła % gałęzi atrybutów\n" #: .././repair/attr_repair.c:853 #, c-format msgid "agno of attribute fork of inode % out of regular partition\n" msgstr "agno gałęzi atrybutów i-węzła % spoza zwykłej partycji\n" #: .././repair/attr_repair.c:861 #, c-format msgid "can't read block 0 of inode % attribute fork\n" msgstr "nie można odczytać bloku 0 i-węzła % gałęzi atrybutów\n" #: .././repair/attr_repair.c:876 #, c-format msgid "clearing forw/back pointers in block 0 for attributes in inode %\n" msgstr "wyczyszczono wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle %\n" #: .././repair/attr_repair.c:883 #, c-format msgid "would clear forw/back pointers in block 0 for attributes in inode %\n" msgstr "wskaźniki forw/back w bloku 0 dla atrybutów w i-węźle % zostałyby wyczyszczone\n" #: .././repair/attr_repair.c:913 #, c-format msgid "bad attribute leaf magic # %#x for dir ino %\n" msgstr "błędna liczba magiczna liścia atrybutu %#x dla i-węzła katalogu %\n" #: .././repair/attr_repair.c:938 #, c-format msgid "Too many ACL entries, count %d\n" msgstr "Za dużo wpisów ACL, liczba %d\n" #: .././repair/attr_repair.c:947 msgid "cannot malloc enough for ACL attribute\n" msgstr "nie można wykonać wystarczającego malloc dla atrybutu ACL\n" #: .././repair/attr_repair.c:948 msgid "SKIPPING this ACL\n" msgstr "POMINIĘTO ten ACL\n" #: .././repair/incore_ino.c:47 msgid "could not allocate nlink array\n" msgstr "Nie udało się przydzielić tablicy nlink\n" #: .././repair/incore_ino.c:233 msgid "inode map malloc failed\n" msgstr "przydzielenie mapy i-węzłów nie powiodło się\n" #: .././repair/incore_ino.c:340 msgid "add_aginode_uncertain - duplicate inode range\n" msgstr "add_aginode_uncertain - powtórzony przedział i-węzłów\n" #: .././repair/incore_ino.c:435 msgid "add_inode - duplicate inode range\n" msgstr "add_inode - powtórzony przedział i-węzłów\n" #: .././repair/incore_ino.c:529 #, c-format msgid "good inode list is --\n" msgstr "lista dobrych i-węzłów to:\n" #: .././repair/incore_ino.c:532 #, c-format msgid "uncertain inode list is --\n" msgstr "lista niepewnych i-węzłów to:\n" #: .././repair/incore_ino.c:537 #, c-format msgid "agno %d -- no inodes\n" msgstr "agno %d - brak i-węzłów\n" #: .././repair/incore_ino.c:541 #, c-format msgid "agno %d\n" msgstr "agno %d\n" #: .././repair/incore_ino.c:545 #, c-format msgid "\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n" msgstr "\tptr = %lx, start = 0x%x, wolne = 0x%llx, potwierdzone = 0x%llx\n" #: .././repair/incore_ino.c:596 msgid "couldn't malloc parent list table\n" msgstr "nie udało się przydzielić tablicy listy rodziców\n" #: .././repair/incore_ino.c:607 .././repair/incore_ino.c:653 msgid "couldn't memalign pentries table\n" msgstr "nie udało się memalign na tablicy pentries\n" #: .././repair/incore_ino.c:711 msgid "could not malloc inode extra data\n" msgstr "nie udało się przydzielić dodatkowych danych i-węzła\n" #: .././repair/incore_ino.c:777 msgid "couldn't malloc inode tree descriptor table\n" msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów\n" #: .././repair/incore_ino.c:781 msgid "couldn't malloc uncertain ino tree descriptor table\n" msgstr "nie udało się przydzielić tablicy deskryptorów drzewa i-węzłów niepewnych\n" #: .././repair/incore_ino.c:786 msgid "couldn't malloc inode tree descriptor\n" msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów\n" #: .././repair/incore_ino.c:790 msgid "couldn't malloc uncertain ino tree descriptor\n" msgstr "nie udało się przydzielić deskryptora drzewa i-węzłów niepewnych\n" #: .././repair/incore_ino.c:798 msgid "couldn't malloc uncertain inode cache area\n" msgstr "nie udało się przydzielić obszaru pamięci podręcznej i-węzłów niepewnych\n" #: .././repair/dir.c:152 #, c-format msgid "invalid inode number % in directory %\n" msgstr "błędny numer i-węzła % w katalogu %\n" #: .././repair/dir.c:157 #, c-format msgid "entry in shortform dir % references rt bitmap inode %\n" msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła bitmapy rt %\n" #: .././repair/dir.c:162 #, c-format msgid "entry in shortform dir % references rt summary inode %\n" msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła opisu rt %\n" #: .././repair/dir.c:167 #, c-format msgid "entry in shortform dir % references user quota inode %\n" msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła limitu użytkownika %\n" #: .././repair/dir.c:172 #, c-format msgid "entry in shortform dir % references group quota inode %\n" msgstr "wpis w krótkim katalogu % odwołuje się do i-węzła limitu grupy %\n" #: .././repair/dir.c:193 #, c-format msgid "entry references free inode % in shortform directory %\n" msgstr "wpis odwołuje się do wolnego i-węzła % w krótkim katalogu %\n" #: .././repair/dir.c:212 #, c-format msgid "entry references non-existent inode % in shortform dir %\n" msgstr "wpis odwołuje się do nie istniejącego i-węzła % w krótkim katalogu %\n" #: .././repair/dir.c:236 .././repair/dir2.c:995 #, c-format msgid "zero length entry in shortform dir %, resetting to %d\n" msgstr "wpis zerowej długości w krótkim katalogu %, przestawiono na %d\n" #: .././repair/dir.c:241 .././repair/dir2.c:1000 #, c-format msgid "zero length entry in shortform dir %, would set to %d\n" msgstr "wpis zerowej długości w krótkim katalogu %, zostałby przestawiony na %d\n" #: .././repair/dir.c:246 #, c-format msgid "zero length entry in shortform dir %, " msgstr "wpis zerowej długości w krótkim katalogu %, " #: .././repair/dir.c:249 .././repair/dir.c:292 .././repair/dir2.c:1051 #, c-format msgid "junking %d entries\n" msgstr "wyrzucono %d wpisów\n" #: .././repair/dir.c:252 .././repair/dir.c:301 .././repair/dir2.c:1060 #, c-format msgid "would junk %d entries\n" msgstr "%d wpisów zostałoby wyrzuconych\n" #: .././repair/dir.c:270 .././repair/dir2.c:1029 #, c-format msgid "size of last entry overflows space left in in shortform dir %, " msgstr "rozmiar ostatniego wpisu przekracza miejsce pozostałe w krótkim katalogu %, " #: .././repair/dir.c:273 .././repair/dir2.c:1032 #, c-format msgid "resetting to %d\n" msgstr "przestawiono na %d\n" #: .././repair/dir.c:278 .././repair/dir2.c:1037 #, c-format msgid "would reset to %d\n" msgstr "zostałby przestawiony na %d\n" #: .././repair/dir.c:283 .././repair/dir2.c:1042 #, c-format msgid "size of entry #%d overflows space left in in shortform dir %\n" msgstr "rozmiar wpisu #%d przekracza miejsce pozostałe w krótkim katalogu %\n" #: .././repair/dir.c:288 .././repair/dir2.c:1047 #, c-format msgid "junking entry #%d\n" msgstr "wyrzucono wpis #%d\n" #: .././repair/dir.c:297 .././repair/dir2.c:1056 #, c-format msgid "would junk entry #%d\n" msgstr "wpis #%d zostałby wyrzucony\n" #: .././repair/dir.c:320 .././repair/dir2.c:1079 #, c-format msgid "entry contains illegal character in shortform dir %\n" msgstr "wpis zawiera niedozwolony znak w krótkim katalogu %\n" #: .././repair/dir.c:374 .././repair/dir2.c:1143 #, c-format msgid "junking entry \"%s\" in directory inode %\n" msgstr "wyrzucono wpis \"%s\" w i-węźle katalogu %\n" #: .././repair/dir.c:378 .././repair/dir2.c:1147 #, c-format msgid "would have junked entry \"%s\" in directory inode %\n" msgstr "wpis \"%s\" w i-węźle katalogu % zostałby wyrzucony\n" #: .././repair/dir.c:404 .././repair/dir2.c:1174 #, c-format msgid "would have corrected entry count in directory % from %d to %d\n" msgstr "liczba wpisów w katalogu % zostałaby poprawiona z %d na %d\n" #: .././repair/dir.c:408 .././repair/dir2.c:1178 #, c-format msgid "corrected entry count in directory %, was %d, now %d\n" msgstr "poprawiono liczbę wpisów w katalogu % - było %d, jest %d\n" #: .././repair/dir.c:419 #, c-format msgid "would have corrected directory % size from %to %\n" msgstr "rozmiar katalogu % zostałby poprawiony z % na %\n" #: .././repair/dir.c:424 .././repair/dir2.c:1212 #, c-format msgid "corrected directory % size, was %, now %\n" msgstr "poprawiono rozmiar katalogu % - było %, jest %\n" #: .././repair/dir.c:446 .././repair/dir2.c:1253 #, c-format msgid "bogus .. inode number (%) in directory inode %, " msgstr "błędny numer i-węzła .. (%) w i-węźle katalogu %, " #: .././repair/dir.c:449 .././repair/dir.c:483 .././repair/dir2.c:1257 #: .././repair/dir2.c:1292 msgid "clearing inode number\n" msgstr "wyczyszczono numer i-węzła\n" #: .././repair/dir.c:455 .././repair/dir.c:489 .././repair/dir2.c:1263 #: .././repair/dir2.c:1298 msgid "would clear inode number\n" msgstr "numer i-węzła zostałby wyczyszczony\n" #: .././repair/dir.c:463 .././repair/dir2.c:1271 #, c-format msgid "corrected root directory % .. entry, was %, now %\n" msgstr "poprawiono wpis .. głównego katalogu % - było %, jest %\n" #: .././repair/dir.c:471 .././repair/dir2.c:1279 #, c-format msgid "would have corrected root directory % .. entry from % to %\n" msgstr "wpis .. głównego katalogu % zostałby poprawiony z % na %\n" #: .././repair/dir.c:480 #, c-format msgid "bad .. entry in dir ino %, points to self, " msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie, " #: .././repair/dir.c:524 #, c-format msgid "bad range claimed [%d, %d) in da block\n" msgstr "błędny przedział [%d, %d) przypisany w bloku da\n" #: .././repair/dir.c:531 #, c-format msgid "byte range end [%d %d) in da block larger than blocksize %d\n" msgstr "koniec przedziału bajtów [%d %d) w bloku da większy niż rozmiar bloku %d\n" #: .././repair/dir.c:538 #, c-format msgid "multiply claimed byte %d in da block\n" msgstr "wielokrotnie użyty bajt %d w bloku da\n" #: .././repair/dir.c:568 #, c-format msgid "hole (start %d, len %d) out of range, block %d, dir ino %\n" msgstr "dziura (początek %d, długość %d) poza zakresem, blok %d, i-węzeł katalogu %\n" #: .././repair/dir.c:579 #, c-format msgid "hole claims used byte %d, block %d, dir ino %\n" msgstr "dziura odwołuje się do używanego bajtu %d, blok %d, i-węzeł katalogu %\n" #: .././repair/dir.c:693 #, c-format msgid "- derived hole value %d, saw %d, block %d, dir ino %\n" msgstr "- wyprowadzona wartość dziury %d, widziano %d, blok %d, i-węzeł katalogu %\n" #: .././repair/dir.c:712 #, c-format msgid "- derived hole (base %d, size %d) in block %d, dir inode % not found\n" msgstr "- wyprowadzona dziura (podstawa %d, rozmiar %d) w bloku %d, i-węzeł katalogu % nie znaleziona\n" #: .././repair/dir.c:767 .././repair/phase6.c:1214 .././repair/phase6.c:1583 #, c-format msgid "can't read block %u (fsbno %) for directory inode %\n" msgstr "nie można odczytać bloku %u (fsbno %) dla i-węzła katalogu %\n" #: .././repair/dir.c:771 #, c-format msgid "can't read block %u (fsbno %) for attrbute fork of inode %\n" msgstr "nie można odczytać bloku %u (fsbno %) dla gałęzi atrybutów i-węzła %\n" #: .././repair/dir.c:779 .././repair/phase6.c:1224 #, c-format msgid "bad dir/attr magic number in inode %, file bno = %u, fsbno = %\n" msgstr "błędna liczba magiczna katalogu/atrybutu w i-węźle %, bno pliku = %u, fsbno = %\n" #: .././repair/dir.c:787 .././repair/dir2.c:333 #, c-format msgid "bad record count in inode %, count = %d, max = %d\n" msgstr "błędna liczba rekordów w i-węźle %, liczba = %d, maksimum = %d\n" #: .././repair/dir.c:806 .././repair/dir2.c:356 #, c-format msgid "bad directory btree for directory inode %\n" msgstr "błędne b-drzewo katalogu dla i-węzła katalogu %\n" #: .././repair/dir.c:810 #, c-format msgid "bad attribute fork btree for inode %\n" msgstr "błędne b-drzewo gałęzi atrybutów dla i-węzła %\n" #: .././repair/dir.c:864 #, c-format msgid "release_da_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "release_da_cursor_int otrzymało nieoczekiwany niepusty bp, dabno = %u\n" #: .././repair/dir.c:931 #, c-format msgid "directory/attribute block used/count inconsistency - %d/%hu\n" msgstr "niespójność wartości used/count bloku katalogu/atrybutu - %d/%hu\n" #: .././repair/dir.c:941 .././repair/dir2.c:478 #, c-format msgid "directory/attribute block hashvalue inconsistency, expected > %u / saw %u\n" msgstr "niespójność wartości hasza bloku katalogu/atrybutu - oczekiwano > %u, widziano %u\n" #: .././repair/dir.c:948 .././repair/dir2.c:485 #, c-format msgid "bad directory/attribute forward block pointer, expected 0, saw %u\n" msgstr "błędny wskaźnik bloku w przód katalogu/atrybutu - oczekiwano 0, widziano %u\n" #: .././repair/dir.c:954 #, c-format msgid "bad directory block in dir ino %\n" msgstr "błędny blok katalogu w i-węźle katalogu %\n" #: .././repair/dir.c:984 #, c-format msgid "" "correcting bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" "poprawiono błędne hashval w bloku katalogu/atrybutu nie będącego liściem\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir.c:992 #, c-format msgid "" "would correct bad hashval in non-leaf dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" "błędne hashval zostałoby poprawione w bloku katalogu/atrybutu nie będącego liściem\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir.c:1130 .././repair/dir2.c:652 #, c-format msgid "can't get map info for block %u of directory inode %\n" msgstr "nie można uzyskać informacji o mapie dla bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:1140 #, c-format msgid "can't read block %u (%) for directory inode %\n" msgstr "nie można odczytać bloku %u (%) dla i-węzła katalogu %\n" #: .././repair/dir.c:1153 #, c-format msgid "bad magic number %x in block %u (%) for directory inode %\n" msgstr "błędna liczba magiczna %x w bloku %u (%) dla i-węzła katalogu %\n" #: .././repair/dir.c:1161 #, c-format msgid "bad back pointer in block %u (%) for directory inode %\n" msgstr "błędny wskaźnik wstecz w bloku %u (%) dla i-węzła katalogu %\n" #: .././repair/dir.c:1167 #, c-format msgid "entry count %d too large in block %u (%) for directory inode %\n" msgstr "liczba wpisów %d zbyt duża w bloku %u (%) dla i-węzła katalogu %\n" #: .././repair/dir.c:1174 #, c-format msgid "bad level %d in block %u (%) for directory inode %\n" msgstr "błędny poziom %d w bloku %u (%) dla i-węzła katalogu %\n" #: .././repair/dir.c:1231 #, c-format msgid "" "correcting bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" "poprawiono błędne hashval w wewnętrznym bloku katalogu/atrybutu\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir.c:1239 #, c-format msgid "" "would correct bad hashval in interior dir/attr block\n" "\tin (level %d) in inode %.\n" msgstr "" "błędne hashval zostałoby poprawione w wewnętrznym bloku katalogu/atrybutu\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir.c:1347 #, c-format msgid "directory block header conflicts with used space in directory inode %\n" msgstr "nagłówek bloku katalogu jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" #: .././repair/dir.c:1377 #, c-format msgid "nameidx %d for entry #%d, bno %d, ino % > fs blocksize, deleting entry\n" msgstr "nameidx %d dla wpisu #%d, bno %d, i-węzeł % > rozmiaru bloku fs, usunięto wpis\n" #: .././repair/dir.c:1414 #, c-format msgid "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, marking entry bad\n" msgstr "nameidx %d, wpis #%d, bno %d, i-węzeł % > rozmiaru bloku fs, zaznaczono wpis jako błędny\n" #: .././repair/dir.c:1429 #, c-format msgid "nameidx %d, entry #%d, bno %d, ino % > fs blocksize, would delete entry\n" msgstr "nameidx %d, wpis #%d, bno %d, i-węzeł % > rozmiaru bloku fs, wpis zostałby usunięty\n" #: .././repair/dir.c:1466 #, c-format msgid "invalid ino number % in dir ino %, entry #%d, bno %d\n" msgstr "nieprawidłowy numer i-węzła % w i-węźle katalogu %, wpis #%d, bno %d\n" #: .././repair/dir.c:1470 .././repair/dir.c:1486 .././repair/dir.c:1503 #: .././repair/dir.c:1519 .././repair/dir.c:1536 #, c-format msgid "\tclearing ino number in entry %d...\n" msgstr "\twyczyszczono numer i-węzła we wpisie %d...\n" #: .././repair/dir.c:1477 .././repair/dir.c:1494 .././repair/dir.c:1510 #: .././repair/dir.c:1527 .././repair/dir.c:1544 #, c-format msgid "\twould clear ino number in entry %d...\n" msgstr "\tnumer i-węzła we wpisie %d zostałby wyczyszczony...\n" #: .././repair/dir.c:1482 #, c-format msgid "entry #%d, bno %d in directory % references realtime bitmap inode %\n" msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła bitmapy realtime %\n" #: .././repair/dir.c:1499 #, c-format msgid "entry #%d, bno %d in directory % references realtime summary inode %\n" msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła opisu realtime %\n" #: .././repair/dir.c:1515 #, c-format msgid "entry #%d, bno %d in directory % references user quota inode %\n" msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła limitu użytkownika %\n" #: .././repair/dir.c:1532 #, c-format msgid "entry #%d, bno %d in directory % references group quota inode %\n" msgstr "wpis #%d, bno %d w katalogu % odwołuje się do i-węzła limitu grupy %\n" #: .././repair/dir.c:1569 #, c-format msgid "entry references free inode % in directory %, will clear entry\n" msgstr "wpis odwołuje się do wolnego i-węzła % w katalogu %, zostanie wyczyszczony\n" #: .././repair/dir.c:1577 #, c-format msgid "entry references free inode % in directory %, would clear entry\n" msgstr "wpis odwołuje się do wolnego i-węzła % w katalogu %, zostałby wyczyszczony\n" #: .././repair/dir.c:1585 #, c-format msgid "bad ino number % in dir ino %, entry #%d, bno %d\n" msgstr "błędny numer i-węzła % w i-węźle katalogu %, wpis #%d, bno %d\n" #: .././repair/dir.c:1588 msgid "clearing inode number...\n" msgstr "wyczyszczono numer i-węzła...\n" #: .././repair/dir.c:1593 msgid "would clear inode number...\n" msgstr "numer i-węzła zostałby wyczyszczony\n" #: .././repair/dir.c:1613 #, c-format msgid "entry #%d, dir inode %, has zero-len name, deleting entry\n" msgstr "wpis #%d, i-węzeł katalogu % ma nazwę zerowej długości, usunięto\n" #: .././repair/dir.c:1651 #, c-format msgid "entry #%d, dir inode %, has zero-len name, marking entry bad\n" msgstr "wpis #%d, i-węzeł katalogu % ma nazwę zerowej długości, zaznaczono jako błędny\n" #: .././repair/dir.c:1664 #, c-format msgid "bad size, entry #%d in dir inode %, block %u -- entry overflows block\n" msgstr "błędny rozmiar, wpis #%d w i-węźle katalogu %, blok %u - wpis wykracza poza blok\n" #: .././repair/dir.c:1675 #, c-format msgid "dir entry slot %d in block %u conflicts with used space in dir inode %\n" msgstr "slot wpisu katalogu %d w bloku %u jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" #: .././repair/dir.c:1715 #, c-format msgid "illegal name \"%s\" in directory inode %, entry will be cleared\n" msgstr "niedozwolona nazwa \"%s\" w i-węźle katalogu %, wpis zostanie wyczyszczony\n" #: .././repair/dir.c:1721 #, c-format msgid "illegal name \"%s\" in directory inode %, entry would be cleared\n" msgstr "niedozwolona nazwa \"%s\" w i-węźle katalogu %, wpis zostałby wyczyszczony\n" #: .././repair/dir.c:1731 #, c-format msgid "\tmismatched hash value for entry \"%s\"\n" msgstr "\tniedopasowana wartość hasza dla wpisu \"%s\"\n" #: .././repair/dir.c:1735 #, c-format msgid "\t\tin directory inode %. resetting hash value.\n" msgstr "\t\tw i-węźle katalogu %. Przestawiono wartość hasza.\n" #: .././repair/dir.c:1741 #, c-format msgid "\t\tin directory inode %. would reset hash value.\n" msgstr "\t\tw i-węźle katalogu %. Wartość hasza zostałaby przestawiona.\n" #: .././repair/dir.c:1771 #, c-format msgid "\tbad hash ordering for entry \"%s\"\n" msgstr "\tbłędny porządek hasza dla wpisu \"%s\"\n" #: .././repair/dir.c:1775 #, c-format msgid "\t\tin directory inode %. will clear entry\n" msgstr "\t\tw i-węźle katalogu %. Wpis zostanie wyczyszczony.\n" #: .././repair/dir.c:1782 #, c-format msgid "\t\tin directory inode %. would clear entry\n" msgstr "\t\tw i-węźle katalogu %. Wpis zostałby wyczyszczony.\n" #: .././repair/dir.c:1798 #, c-format msgid "name \"%s\" (block %u, slot %d) conflicts with used space in dir inode %\n" msgstr "nazwa \"%s\" (blok %u, slot %d) jest w konflikcie z użytym miejscem w i-węźle katalogu %\n" #: .././repair/dir.c:1805 #, c-format msgid "will clear entry \"%s\" (#%d) in directory inode %\n" msgstr "wpis \"%s\" (#%d) zostanie wyczyszczony w i-węźle katalogu %\n" #: .././repair/dir.c:1809 #, c-format msgid "would clear entry \"%s\" (#%d)in directory inode %\n" msgstr "wpis \"%s\" (#%d) zostałby wyczyszczony w i-węźle katalogu %\n" #: .././repair/dir.c:1845 #, c-format msgid "bad .. entry in dir ino %, points to self" msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie" #: .././repair/dir.c:1849 .././repair/dir.c:1946 msgid "will clear entry\n" msgstr "wpis zostanie wyczyszczony\n" #: .././repair/dir.c:1854 .././repair/dir.c:1950 .././repair/dir2.c:1642 msgid "would clear entry\n" msgstr "wpis zostałby wyczyszczony\n" #: .././repair/dir.c:1864 #, c-format msgid "correcting .. entry in root inode %, was %\n" msgstr "poprawiono wpis .. w głównym i-węźle %, było %\n" #: .././repair/dir.c:1871 #, c-format msgid "bad .. entry (%) in root inode % should be %\n" msgstr "błędny wpis .. (%) w głównym i-węźle %, powinno być %\n" #: .././repair/dir.c:1888 #, c-format msgid "multiple .. entries in directory inode %, will clear second entry\n" msgstr "wiele wpisów .. w i-węźle katalogu %, drugi wpis zostanie wyczyszczony\n" #: .././repair/dir.c:1894 #, c-format msgid "multiple .. entries in directory inode %, would clear second entry\n" msgstr "wiele wpisów .. w i-węźle katalogu %, drugi wpis zostałby wyczyszczony\n" #: .././repair/dir.c:1907 #, c-format msgid ". in directory inode % has wrong value (%), fixing entry...\n" msgstr ". w i-węźle katalogu % ma niepoprawną wartość (%), poprawiono wpis...\n" #: .././repair/dir.c:1914 #, c-format msgid ". in directory inode % has wrong value (%)\n" msgstr ". w i-węźle katalogu % ma niepoprawną wartość (%)\n" #: .././repair/dir.c:1920 #, c-format msgid "multiple . entries in directory inode %\n" msgstr "wiele wpisów . w i-węźle katalogu %\n" #: .././repair/dir.c:1927 #, c-format msgid "will clear one . entry in directory inode %\n" msgstr "jeden wpis . w i-węźle katalogu % zostanie wyczyszczony\n" #: .././repair/dir.c:1933 #, c-format msgid "would clear one . entry in directory inode %\n" msgstr "jeden wpis . w i-węźle katalogu % zostałby wyczyszczony\n" #: .././repair/dir.c:1943 #, c-format msgid "entry \"%s\" in directory inode % points to self, " msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na siebie, " #: .././repair/dir.c:1968 #, c-format msgid "- resetting first used heap value from %d to %d in block %u of dir ino %\n" msgstr "- przestawiono pierwszą używaną wartość sterty z %d na %d w bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:1976 #, c-format msgid "- would reset first used value from %d to %d in block %u of dir ino %\n" msgstr "- pierwsza używana wartość zostałaby przestawiona z %d na %d w bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:1986 #, c-format msgid "- resetting namebytes cnt from %d to %d in block %u of dir inode %\n" msgstr "- przestawiono liczbę bajtów nazwy z %d na %d w bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:1994 #, c-format msgid "- would reset namebytes cnt from %d to %d in block %u of dir inode %\n" msgstr "- liczba bajtów nazwy zostałaby przestawiona z %d na %d w bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:2029 #, c-format msgid "- found unexpected lost holes in block %u, dir inode %\n" msgstr "- znaleziono nieoczekiwane utracone dziury w bloku %u, i-węźle katalogu %\n" #: .././repair/dir.c:2037 #, c-format msgid "- hole info non-optimal in block %u, dir inode %\n" msgstr "- nieoptymalna informacja o dziurze w bloku %u, i-węźle katalogu %\n" #: .././repair/dir.c:2044 #, c-format msgid "- hole info incorrect in block %u, dir inode %\n" msgstr "- niepoprawna informacja o dziurze w bloku %u, i-węźle katalogu %\n" #: .././repair/dir.c:2055 #, c-format msgid "- existing hole info for block %d, dir inode % (base, size) - \n" msgstr "- istniejąca informacja o dziurze dla bloku %d, i-węzła katalogu % (podstawa, rozmiar) - \n" #: .././repair/dir.c:2063 #, c-format msgid "- holes flag = %d\n" msgstr "- flaga dziur = %d\n" #: .././repair/dir.c:2069 #, c-format msgid "- compacting block %u in dir inode %\n" msgstr "- zagęszczono blok %u w i-węźle katalogu %\n" #: .././repair/dir.c:2110 #, c-format msgid "not enough space in block %u of dir inode % for all entries\n" msgstr "zbyt mało miejsca dla wszystkich wpisów w bloku %u i-węzła katalogu %\n" #: .././repair/dir.c:2180 #, c-format msgid "- would compact block %u in dir inode %\n" msgstr "- bloku %u w i-węźle katalogu % zostałby zagęszczony\n" #: .././repair/dir.c:2245 .././repair/dir2.c:1828 #, c-format msgid "can't map block %u for directory inode %\n" msgstr "nie można odwzorować bloku %u dla i-węzła katalogu %\n" #: .././repair/dir.c:2256 #, c-format msgid "can't read file block %u (fsbno %, daddr %) for directory inode %\n" msgstr "nie można odczytać bloku pliku %u (fsbno %, daddr %) dla i-węzła katalogu %\n" #: .././repair/dir.c:2270 .././repair/dir.c:2529 #, c-format msgid "bad directory leaf magic # %#x for dir ino %\n" msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu %\n" #: .././repair/dir.c:2310 #, c-format msgid "bad sibling back pointer for directory block %u in directory inode %\n" msgstr "błędny wskaźnik wstecz dla bloku katalogu %u w i-węźle katalogu %\n" #: .././repair/dir.c:2341 .././repair/dir2.c:1904 #, c-format msgid "bad hash path in directory %\n" msgstr "błędna ścieżka hasza w katalogu %\n" #: .././repair/dir.c:2450 #, c-format msgid "out of range internal directory block numbers (inode %)\n" msgstr "numery bloków wewnętrznego katalogu spoza zakresu (i-węzeł %)\n" #: .././repair/dir.c:2456 #, c-format msgid "setting directory inode (%) size to % bytes, was % bytes\n" msgstr "ustawiono rozmiar i-węzła katalogu (%) na % bajtów, było % bajtów\n" #: .././repair/dir.c:2509 #, c-format msgid "block 0 for directory inode % is missing\n" msgstr "brak bloku 0 dla i-węzła katalogu %\n" #: .././repair/dir.c:2516 #, c-format msgid "can't read block 0 for directory inode %\n" msgstr "nie można odczytać bloku 0 dla i-węzła katalogu %\n" #: .././repair/dir.c:2552 #, c-format msgid "clearing forw/back pointers for directory inode %\n" msgstr "wyczyszczono wskaźniki w przód/wstecz dla i-węzła katalogu %\n" #: .././repair/dir.c:2558 #, c-format msgid "would clear forw/back pointers for directory inode %\n" msgstr "wskaźniki w przód/wstecz dla i-węzła katalogu % zostałyby wyczyszczone\n" #: .././repair/dir.c:2623 .././repair/dir2.c:2109 #, c-format msgid "no . entry for directory %\n" msgstr "brak wpisu . dla katalogu %\n" #: .././repair/dir.c:2632 .././repair/dir2.c:2119 #, c-format msgid "no .. entry for directory %\n" msgstr "brak wpisu .. dla katalogu %\n" #: .././repair/dir.c:2634 .././repair/dir2.c:2121 #, c-format msgid "no .. entry for root directory %\n" msgstr "brak wpisu .. dla katalogu głównego %\n" #: .././repair/dir2.c:57 #, c-format msgid "malloc failed (%zu bytes) dir2_add_badlist:ino %\n" msgstr "malloc nie powiodło się (%zu bajtów) w dir2_add_badlist:ino %\n" #: .././repair/dir2.c:98 .././repair/dir2.c:209 .././repair/dir2.c:245 msgid "couldn't malloc dir2 buffer list\n" msgstr "nie można przydzielić listy bufora dir2\n" #: .././repair/dir2.c:125 msgid "couldn't malloc dir2 buffer header\n" msgstr "nie można przydzielić nagłówka bufora dir2\n" #: .././repair/dir2.c:142 msgid "couldn't malloc dir2 buffer data\n" msgstr "nie można przydzielić danych bufora dir2\n" #: .././repair/dir2.c:305 .././repair/dir2.c:663 .././repair/dir2.c:1709 #: .././repair/phase6.c:2290 #, c-format msgid "can't read block %u for directory inode %\n" msgstr "nie można odczytać bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:315 #, c-format msgid "found non-root LEAFN node in inode % bno = %u\n" msgstr "znaleziono niegłówny węzeł LEAFN w i-węźle % bno = %u\n" #: .././repair/dir2.c:324 #, c-format msgid "bad dir magic number 0x%x in inode % bno = %u\n" msgstr "błędna liczba magiczna katalogu 0x%x w i-węźle % bno = %u\n" #: .././repair/dir2.c:345 #, c-format msgid "bad header depth for directory inode %\n" msgstr "błędna głębokość nagłówka dla i-węzła katalogu %\n" #: .././repair/dir2.c:406 #, c-format msgid "release_dir2_cursor_int got unexpected non-null bp, dabno = %u\n" msgstr "release_dir2_cursor_int otrzymał nieoczekiwany niezerowy bp, dabno = %u\n" #: .././repair/dir2.c:469 #, c-format msgid "directory block used/count inconsistency - %d / %hu\n" msgstr "niespójność wartości used/count bloku katalogu - %d / %hu\n" #: .././repair/dir2.c:491 #, c-format msgid "bad directory block in inode %\n" msgstr "błędny blok katalogu w i-węźle %\n" #: .././repair/dir2.c:512 #, c-format msgid "" "correcting bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %.\n" msgstr "" "poprawiono błędne hashval w bloku katalogu nie będącego liściem\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir2.c:520 #, c-format msgid "" "would correct bad hashval in non-leaf dir block\n" "\tin (level %d) in inode %.\n" msgstr "" "błędne hashval w bloku katalogu nie będącego liściem zostałoby poprawione\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir2.c:676 #, c-format msgid "bad magic number %x in block %u for directory inode %\n" msgstr "błędna liczba magiczna %x w bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:684 #, c-format msgid "bad back pointer in block %u for directory inode %\n" msgstr "błędny wskaźnik wstecz w bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:690 #, c-format msgid "entry count %d too large in block %u for directory inode %\n" msgstr "liczba wpisów %d zbyt duża w bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:697 #, c-format msgid "bad level %d in block %u for directory inode %\n" msgstr "błędny poziom %d w bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:740 #, c-format msgid "" "correcting bad hashval in interior dir block\n" "\tin (level %d) in inode %.\n" msgstr "" "poprawiono błędne hashval w wewnętrznym bloku katalogu\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir2.c:748 #, c-format msgid "" "would correct bad hashval in interior dir block\n" "\tin (level %d) in inode %.\n" msgstr "" "błędne hashval w wewnętrznym bloku katalogu zostałoby poprawione\n" "\tw i-węźle (poziomu %d) %.\n" #: .././repair/dir2.c:782 msgid "couldn't malloc dir2 shortform copy\n" msgstr "nie udało się przydzielić krótkiej kopii dir2\n" #: .././repair/dir2.c:920 msgid "current" msgstr "bieżącego i-węzła" #: .././repair/dir2.c:923 .././repair/dir2.c:1443 msgid "invalid" msgstr "nieprawidłowego i-węzła" #: .././repair/dir2.c:926 .././repair/dir2.c:1445 msgid "realtime bitmap" msgstr "i-węzła bitmapy realtime" #: .././repair/dir2.c:929 .././repair/dir2.c:1447 msgid "realtime summary" msgstr "i-węzła opisu realtime" #: .././repair/dir2.c:932 .././repair/dir2.c:1449 msgid "user quota" msgstr "i-węzła limitów użytkownika" #: .././repair/dir2.c:935 .././repair/dir2.c:1451 msgid "group quota" msgstr "i-węzła limitów grupy" #: .././repair/dir2.c:953 .././repair/dir2.c:1481 msgid "free" msgstr "free" #: .././repair/dir2.c:970 .././repair/dir2.c:1461 msgid "non-existent" msgstr "nie istniejącego i-węzła" #: .././repair/dir2.c:975 #, c-format msgid "entry \"%*.*s\" in shortform directory % references %s inode %\n" msgstr "wpis \"%*.*s\" w krótkim katalogu % odwołuje się do %s %\n" #: .././repair/dir2.c:1005 #, c-format msgid "zero length entry in shortform dir %" msgstr "wpis zerowej długości w krótkim katalogu %" #: .././repair/dir2.c:1008 #, c-format msgid ", junking %d entries\n" msgstr ", wyrzucono %d wpisów\n" #: .././repair/dir2.c:1011 #, c-format msgid ", would junk %d entries\n" msgstr ", %d wpisów zostałoby wyrzucone\n" #: .././repair/dir2.c:1086 #, c-format msgid "entry contains offset out of order in shortform dir %\n" msgstr "wpis zawiera uszkodzony offset w krótkim katalogu %\n" #: .././repair/dir2.c:1189 #, c-format msgid "would have corrected i8 count in directory % from %d to %d\n" msgstr "liczba i8 zostałaby poprawiona w katalogu % z %d na %d\n" #: .././repair/dir2.c:1193 #, c-format msgid "corrected i8 count in directory %, was %d, now %d\n" msgstr "poprawiono liczbę i8 w katalogu % - było %d, jest %d\n" #: .././repair/dir2.c:1207 #, c-format msgid "would have corrected directory % size from % to %\n" msgstr "rozmiar katalogu % zostałby poprawiony z % na %\n" #: .././repair/dir2.c:1224 #, c-format msgid "directory % offsets too high\n" msgstr "offsety zbyt duże w katalogu %\n" #: .././repair/dir2.c:1230 #, c-format msgid "would have corrected entry offsets in directory %\n" msgstr "offsety wpisów w katalogu % zostałyby poprawione\n" #: .././repair/dir2.c:1234 #, c-format msgid "corrected entry offsets in directory %\n" msgstr "poprawiono offsety wpisów w katalogu %\n" #: .././repair/dir2.c:1289 #, c-format msgid "bad .. entry in directory inode %, points to self, " msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie, " #: .././repair/dir2.c:1401 #, c-format msgid "corrupt block %u in directory inode %\n" msgstr "uszkodzony blok %u w i-węźle katalogu %\n" #: .././repair/dir2.c:1404 msgid "\twill junk block\n" msgstr "\tblok zostanie wyrzucony\n" #: .././repair/dir2.c:1406 msgid "\twould junk block\n" msgstr "\tblok zostałby wyrzucony\n" #: .././repair/dir2.c:1490 #, c-format msgid "entry \"%*.*s\" at block %d offset % in directory inode % references %s inode %\n" msgstr "wpis \"%*.*s\" w bloku %d offsecie % w i-węźle katalogu % odwołuje się do %s %\n" #: .././repair/dir2.c:1501 #, c-format msgid "entry at block %u offset % in directory inode %has 0 namelength\n" msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma zerową długość nazwy\n" #: .././repair/dir2.c:1514 #, c-format msgid "\tclearing inode number in entry at offset %...\n" msgstr "\twyczyszczono numer i-węzła we wpisie o offsecie %...\n" #: .././repair/dir2.c:1521 #, c-format msgid "\twould clear inode number in entry at offset %...\n" msgstr "\tnumer i-węzła we wpisie o offsecie % zostałby wyczyszczony...\n" #: .././repair/dir2.c:1534 #, c-format msgid "entry at block %u offset % in directory inode % has illegal name \"%*.*s\": " msgstr "wpis w bloku %u offsecie % w i-węźle katalogu % ma niedozwoloną nazwę \"%*.*s\": " #: .././repair/dir2.c:1564 #, c-format msgid "bad .. entry in directory inode %, points to self: " msgstr "błędny wpis .. w i-węźle katalogu %, wskazuje na siebie: " #: .././repair/dir2.c:1575 #, c-format msgid "bad .. entry in root directory inode %, was %: " msgstr "błędny wpis w i-węźle głównego katalogu %, było %: " #: .././repair/dir2.c:1578 .././repair/dir2.c:1610 .././repair/phase2.c:180 #: .././repair/phase2.c:189 .././repair/phase2.c:198 msgid "correcting\n" msgstr "poprawiono\n" #: .././repair/dir2.c:1582 .././repair/dir2.c:1614 .././repair/phase2.c:182 #: .././repair/phase2.c:191 .././repair/phase2.c:200 msgid "would correct\n" msgstr "zostałby poprawiony\n" #: .././repair/dir2.c:1594 #, c-format msgid "multiple .. entries in directory inode %: " msgstr "wiele wpisów .. w i-węźle katalogu %: " #: .././repair/dir2.c:1607 #, c-format msgid "bad . entry in directory inode %, was %: " msgstr "błędny wpis . w i-węźle katalogu %, było %: " #: .././repair/dir2.c:1619 #, c-format msgid "multiple . entries in directory inode %: " msgstr "wiele wpisów . w i-węźle katalogu %: " #: .././repair/dir2.c:1629 #, c-format msgid "entry \"%*.*s\" in directory inode % points to self: " msgstr "wpis \"%*.*s\" w i-węźle katalogu % wskazuje na siebie: " #: .././repair/dir2.c:1640 msgid "clearing entry\n" msgstr "wyczyszczono wpis\n" #: .././repair/dir2.c:1655 #, c-format msgid "bad bestfree table in block %u in directory inode %: " msgstr "błędna tablica bestfree w bloku %u w i-węźle katalogu %: " #: .././repair/dir2.c:1658 msgid "repairing table\n" msgstr "naprawiono tablicę\n" #: .././repair/dir2.c:1662 msgid "would repair table\n" msgstr "tablica zostałaby naprawiona\n" #: .././repair/dir2.c:1700 #, c-format msgid "block %u for directory inode % is missing\n" msgstr "brak bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:1719 #, c-format msgid "bad directory block magic # %#x in block %u for directory inode %\n" msgstr "błędna liczba magiczna bloku katalogu %#x w bloku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:1763 #, c-format msgid "bad entry count in block %u of directory inode %\n" msgstr "błędna liczba wpisów w bloku %u i-węzła katalogu %\n" #: .././repair/dir2.c:1771 #, c-format msgid "bad hash ordering in block %u of directory inode %\n" msgstr "błędna kolejność hasza w bloku %u i-węzła katalogu %\n" #: .././repair/dir2.c:1780 #, c-format msgid "bad stale count in block %u of directory inode %\n" msgstr "błędna liczba stale %u i-węzła katalogu %\n" #: .././repair/dir2.c:1838 #, c-format msgid "can't read file block %u for directory inode %\n" msgstr "nie można odczytać bloku pliku %u dla i-węzła katalogu %\n" #: .././repair/dir2.c:1849 #, c-format msgid "bad directory leaf magic # %#x for directory inode % block %u\n" msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu % bloku %u\n" #: .././repair/dir2.c:1879 #, c-format msgid "bad sibling back pointer for block %u in directory inode %\n" msgstr "błędny wskaźnik wstecz dla bloku %u w i-węźle katalogu %\n" #: .././repair/dir2.c:2009 #, c-format msgid "block % for directory inode % is missing\n" msgstr "brak bloku % dla i-węzła katalogu %\n" #: .././repair/dir2.c:2018 #, c-format msgid "can't read block % for directory inode %\n" msgstr "nie można odczytać bloku % dla i-węzła katalogu %\n" #: .././repair/dir2.c:2025 #, c-format msgid "bad directory block magic # %#x in block % for directory inode %\n" msgstr "błędna liczba magiczna bloku katalogu %#x w bloku % dla i-węzła katalogu %\n" #: .././repair/dir2.c:2102 #, c-format msgid "bad size/format for directory %\n" msgstr "błędny rozmiar/format dla katalogu %\n" #: .././repair/phase4.c:202 msgid "Phase 4 - check for duplicate blocks...\n" msgstr "Faza 4 - sprawdzanie powtórzonych bloków...\n" #: .././repair/phase4.c:203 msgid " - setting up duplicate extent list...\n" msgstr " - tworzenie listy powtórzonych ekstentów...\n" #: .././repair/phase4.c:217 msgid "root inode would be lost\n" msgstr "główny i-węzeł zostałby utracony\n" #: .././repair/phase4.c:219 msgid "root inode lost\n" msgstr "główny i-węzeł utracony\n" #: .././repair/phase4.c:236 #, c-format msgid "unknown block state, ag %d, block %d\n" msgstr "nieznany stan bloku, ag %d, blok %d\n" #: .././repair/phase4.c:269 #, c-format msgid "unknown rt extent state, extent %\n" msgstr "nieznany stan ekstentu rt, ekstent %\n" #: .././repair/phase4.c:318 msgid " - check for inodes claiming duplicate blocks...\n" msgstr " - szukanie i-węzłów odwołujących się do powtórzonych bloków...\n" #: .././repair/phase6.c:63 #, c-format msgid "malloc failed add_dotdot_update (%zu bytes)\n" msgstr "malloc nie powiodło się w add_dotdot_update (%zu bajtów)\n" #: .././repair/phase6.c:174 #, c-format msgid "malloc failed in dir_hash_add (%zu bytes)\n" msgstr "malloc nie powiodło się w dir_hash_add (%zu bajtów)\n" #: .././repair/phase6.c:228 msgid "ok" msgstr "ok" #: .././repair/phase6.c:229 msgid "duplicate leaf" msgstr "powtórzony liść" #: .././repair/phase6.c:230 msgid "hash value mismatch" msgstr "niezgodność wartości hasza" #: .././repair/phase6.c:231 msgid "no data entry" msgstr "brak wpisu danych" #: .././repair/phase6.c:232 msgid "no leaf entry" msgstr "brak wpisu liścia" #: .././repair/phase6.c:233 msgid "bad stale count" msgstr "błędna liczba stale" #: .././repair/phase6.c:241 #, c-format msgid "bad hash table for directory inode % (%s): " msgstr "błędna tablica haszująca dla i-węzła katalogu % (%s): " #: .././repair/phase6.c:244 msgid "rebuilding\n" msgstr "przebudowano\n" #: .././repair/phase6.c:246 msgid "would rebuild\n" msgstr "zostałaby przebudowana\n" #: .././repair/phase6.c:282 msgid "calloc failed in dir_hash_init\n" msgstr "calloc nie powiodło się w dir_hash_init\n" #: .././repair/phase6.c:412 msgid "ran out of disk space!\n" msgstr "brak miejsca na dysku!\n" #: .././repair/phase6.c:414 #, c-format msgid "xfs_trans_reserve returned %d\n" msgstr "xfs_trans_reserve zwróciło %d\n" #: .././repair/phase6.c:443 .././repair/phase6.c:536 #, c-format msgid "couldn't iget realtime bitmap inode -- error - %d\n" msgstr "nie udało się wykonać iget dla i-węzła bitmapy realtime - błąd %d\n" #: .././repair/phase6.c:493 #, c-format msgid "couldn't allocate realtime bitmap, error = %d\n" msgstr "nie udało się przydzielić bitmapy realtime, błąd = %d\n" #: .././repair/phase6.c:506 #, c-format msgid "allocation of the realtime bitmap failed, error = %d\n" msgstr "przydzielenie bitmapy realtime nie powiodło się, błąd = %d\n" #: .././repair/phase6.c:549 #, c-format msgid "couldn't map realtime bitmap block %, error = %d\n" msgstr "nie udało się odwzorować bloku bitmapy realtime %, błąd = %d\n" #: .././repair/phase6.c:562 #, c-format msgid "can't access block % (fsbno %) of realtime bitmap inode %\n" msgstr "brak dostępu do bloku % (fsbno %) i-węzła bitmapy realtime %\n" #: .././repair/phase6.c:605 .././repair/phase6.c:676 #, c-format msgid "couldn't iget realtime summary inode -- error - %d\n" msgstr "nie udało się wykonać iget dla i-węzła opisu realtime - błąd %d\n" #: .././repair/phase6.c:618 #, c-format msgid "couldn't map realtime summary inode block %, error = %d\n" msgstr "nie udało się odwzorować bloku i-węzła opisu realtime %, błąd = %d\n" #: .././repair/phase6.c:631 #, c-format msgid "can't access block % (fsbno %) of realtime summary inode %\n" msgstr "brak dostępu do bloku % (fsbno %) i-węzła opisu realtime %\n" #: .././repair/phase6.c:732 #, c-format msgid "couldn't allocate realtime summary inode, error = %d\n" msgstr "nie udało się przydzielić i-węzła opisu realtime, błąd = %d\n" #: .././repair/phase6.c:745 #, c-format msgid "allocation of the realtime summary ino failed, error = %d\n" msgstr "przydzielenie i-węzła opisu realtime nie powiodło się, błąd = %d\n" #: .././repair/phase6.c:775 #, c-format msgid "could not iget root inode -- error - %d\n" msgstr "nie udało się wykonać iget dla głównego i-węzła - błąd %d\n" #: .././repair/phase6.c:845 #, c-format msgid "%d - couldn't iget root inode to obtain %s\n" msgstr "%d - nie udało się wykonać iget dla głównego węzła, aby uzyskać %s\n" #: .././repair/phase6.c:876 #, c-format msgid "%s inode allocation failed %d\n" msgstr "przydzielenie i-węzłą %s nie powiodło się - %d\n" #: .././repair/phase6.c:907 #, c-format msgid "can't make %s, createname error %d\n" msgstr "nie można zrobić %s, błąd createname %d\n" #: .././repair/phase6.c:927 #, c-format msgid "%s directory creation failed -- bmapf error %d\n" msgstr "tworzenie katalogu %s nie powiodło się - błąd bmapf %d\n" #: .././repair/phase6.c:970 #, c-format msgid "%d - couldn't iget orphanage inode\n" msgstr "%d - nie udało się wykonać iget dla i-węzła sierocińca\n" #: .././repair/phase6.c:983 #, c-format msgid "%d - couldn't iget disconnected inode\n" msgstr "%d - nie udało się wykonać iget dla odłączonego i-węzła\n" #: .././repair/phase6.c:1003 .././repair/phase6.c:1047 #: .././repair/phase6.c:1104 .././repair/phase6.c:1747 #, c-format msgid "space reservation failed (%d), filesystem may be out of space\n" msgstr "nie udało się zarezerwować miejsca (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1014 .././repair/phase6.c:1059 #: .././repair/phase6.c:1115 #, c-format msgid "name create failed in %s (%d), filesystem may be out of space\n" msgstr "tworzenie nazwy nie powiodło się w %s (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1027 #, c-format msgid "creation of .. entry failed (%d), filesystem may be out of space\n" msgstr "tworzenie wpisu .. nie powiodło się (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1036 #, c-format msgid "bmap finish failed (err - %d), filesystem may be out of space\n" msgstr "zakończenie bmap nie powiodło się (błąd %d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1078 #, c-format msgid "name replace op failed (%d), filesystem may be out of space\n" msgstr "operacja zastąpienia nazwy nie powiodła się (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1085 .././repair/phase6.c:1125 #: .././repair/phase6.c:1770 #, c-format msgid "bmap finish failed (%d), filesystem may be out of space\n" msgstr "zakończenie bmap nie powiodło się (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1163 .././repair/phase6.c:1564 msgid "dir" msgstr "katalogu" #: .././repair/phase6.c:1172 .././repair/phase6.c:1176 #, c-format msgid "can't map block %d in %s inode %, xfs_bmapi returns %d, nmap = %d\n" msgstr "nie można odwzorować bloku %d w i-węźle %s %, xfs_bmapi zwraca %d, nmap = %d\n" #: .././repair/phase6.c:1185 .././repair/phase6.c:1189 #: .././repair/phase6.c:1643 .././repair/phase6.c:1647 #, c-format msgid "block %d in %s ino % doesn't exist\n" msgstr "blok %d w i-węźle %s % nie istnieje\n" #: .././repair/phase6.c:1244 .././repair/phase6.c:1248 #, c-format msgid "can't map block %d in %s ino %, xfs_bmapi returns %d, nmap = %d\n" msgstr "nie można odwzorować bloku %d w i-węźle %s %, xfs_bmapi zwraca %d, nmap = %d\n" #: .././repair/phase6.c:1256 .././repair/phase6.c:1260 #, c-format msgid "block %d in %s inode % doesn't exist\n" msgstr "blok %d w i-węźle %s % nie istnieje\n" #: .././repair/phase6.c:1283 msgid ", marking entry to be junked\n" msgstr ", zaznaczono wpis do wyrzucenia\n" #: .././repair/phase6.c:1287 msgid ", would junk entry\n" msgstr ", wpis zostałby wyrzucony\n" #: .././repair/phase6.c:1404 #, c-format msgid "entry \"%s\" in dir inode % points to non-existent inode %" msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na nie istniejący i-węzęł %" #: .././repair/phase6.c:1422 #, c-format msgid "entry \"%s\" in dir inode % points to free inode %" msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na wolny i-węzeł %" #: .././repair/phase6.c:1438 .././repair/phase6.c:2105 #: .././repair/phase6.c:2733 .././repair/phase6.c:3063 #, c-format msgid "%s (ino %) in root (%) is not a directory" msgstr "%s (i-węzeł %) w katalogu głównym (%) nie jest katalogiem" #: .././repair/phase6.c:1460 .././repair/phase6.c:2126 #: .././repair/phase6.c:2751 .././repair/phase6.c:3081 #, c-format msgid "entry \"%s\" (ino %) in dir % is a duplicate name" msgstr "wpis \"%s\" (i-węzeł %) w katalogu % jest powtórzoną nazwą" #: .././repair/phase6.c:1491 #, c-format msgid "entry \"%s\" in dir ino % points to an already connected dir inode %,\n" msgstr "wpis \"%s\" w katalogu % wskazuje na już podłączony i-węzeł katalogu %,\n" #: .././repair/phase6.c:1500 .././repair/phase6.c:2226 #: .././repair/phase6.c:2785 .././repair/phase6.c:3113 #, c-format msgid "entry \"%s\" in dir ino % doesn't have a .. entry, will set it in ino %.\n" msgstr "wpis \"%s\" w i-węźle katalogu % nie ma wpisu .., zostanie ustawiony w i-węźle %.\n" #: .././repair/phase6.c:1508 #, c-format msgid "entry \"%s\" in dir ino % not consistent with .. value (%) in ino %,\n" msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %,\n" #: .././repair/phase6.c:1522 .././repair/phase6.c:2249 #, c-format msgid "\twill clear entry \"%s\"\n" msgstr "\twpis \"%s\" zostanie wyczyszczony\n" #: .././repair/phase6.c:1525 .././repair/phase6.c:2252 #, c-format msgid "\twould clear entry \"%s\"\n" msgstr "\twpis \"%s\" zostałby wyczyszczony\n" #: .././repair/phase6.c:1570 #, c-format msgid "cannot map block 0 of directory inode %\n" msgstr "nie można odwzorować bloku 0 i-węzła katalogu %\n" #: .././repair/phase6.c:1593 #, c-format msgid "bad magic # (0x%x) for dir ino % leaf block (bno %u fsbno %)\n" msgstr "błędna liczba magiczna (0x%x) dla bloku liścia i-węzła katalogu % (bno %u fsbno %)\n" #: .././repair/phase6.c:1630 .././repair/phase6.c:1634 #, c-format msgid "can't map leaf block %d in dir %, xfs_bmapi returns %d, nmap = %d\n" msgstr "nie można odwzorować bloku liścia %d w katalogu %, xfs_bmapi zwraca %d, nmap = %d\n" #: .././repair/phase6.c:1686 #, c-format msgid "rebuilding directory inode %\n" msgstr "przebudowywanie i-węzła katalogu %\n" #: .././repair/phase6.c:1711 #, c-format msgid "xfs_bmap_last_offset failed -- error - %d\n" msgstr "xfs_bmap_last_offset nie powiodło się - błąd %d\n" #: .././repair/phase6.c:1718 #, c-format msgid "xfs_bunmapi failed -- error - %d\n" msgstr "xfs_bunmapi nie powiodło się - błąd %d\n" #: .././repair/phase6.c:1760 #, c-format msgid "name create failed in ino % (%d), filesystem may be out of space\n" msgstr "tworzenie nazwy nie powiodło się w i-węźle % (%d), może brakować miejsca w systemie plików\n" #: .././repair/phase6.c:1825 #, c-format msgid "shrink_inode failed inode % block %u\n" msgstr "shrink_inode nie powiodło się dla i-węzła % bloku %u\n" #: .././repair/phase6.c:1906 #, c-format msgid "realloc failed in longform_dir2_entry_check_data (%zu bytes)\n" msgstr "realloc nie powiodło się w longform_dir2_entry_check_data (%zu bajtów)\n" #: .././repair/phase6.c:1963 #, c-format msgid "empty data block %u in directory inode %: " msgstr "pusty blok danych %u w i-węźle katalogu %: " #: .././repair/phase6.c:1967 #, c-format msgid "corrupt block %u in directory inode %: " msgstr "uszkodzony blok %u w i-węźle katalogu %: " #: .././repair/phase6.c:1971 msgid "junking block\n" msgstr "wyrzucono blok\n" #: .././repair/phase6.c:1974 msgid "would junk block\n" msgstr "blok zostałby wyrzucony\n" #: .././repair/phase6.c:1998 #, c-format msgid "bad directory block magic # %#x for directory inode % block %d: " msgstr "błędna liczba magiczna bloku katalogu %#x dla i-węzła katalogu % bloku %d: " #: .././repair/phase6.c:2001 #, c-format msgid "fixing magic # to %#x\n" msgstr "poprawiono liczbę magiczną na %#x\n" #: .././repair/phase6.c:2005 #, c-format msgid "would fix magic # to %#x\n" msgstr "liczba magiczna zostałaby poprawiona na %#x\n" #: .././repair/phase6.c:2026 #, c-format msgid "directory inode % block %u has consecutive free entries: " msgstr "i-węzeł katalogu % blok %u ma kolejne wolne wpisy: " #: .././repair/phase6.c:2029 msgid "joining together\n" msgstr "połączono\n" #: .././repair/phase6.c:2038 msgid "would join together\n" msgstr "zostałyby połączone\n" #: .././repair/phase6.c:2070 #, c-format msgid "entry \"%s\" in directory inode % points to non-existent inode %" msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na nie istniejący i-węzeł %" #: .././repair/phase6.c:2087 #, c-format msgid "entry \"%s\" in directory inode % points to free inode %" msgstr "wpis \"%s\" w i-węźle katalogu % wskazuje na wolny i-węzeł %" #: .././repair/phase6.c:2157 #, c-format msgid "entry \"%s\" (ino %) in dir % is not in the the first block" msgstr "wpis \"%s\" (i-węzeł %) w katalogu % nie jest w pierwszym bloku" #: .././repair/phase6.c:2182 #, c-format msgid "entry \"%s\" in dir % is not the first entry" msgstr "wpis \"%s\" w katalogu % nie jest pierwszym wpisem" #: .././repair/phase6.c:2217 #, c-format msgid "entry \"%s\" in dir % points to an already connected directory inode %\n" msgstr "wpis \"%s\" w katalogu % wskazuje na już podłączony i-węzeł katalogu %\n" #: .././repair/phase6.c:2236 #, c-format msgid "entry \"%s\" in dir inode % inconsistent with .. value (%) in ino %\n" msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %\n" #: .././repair/phase6.c:2307 .././repair/phase6.c:2387 #, c-format msgid "leaf block %u for directory inode % bad header\n" msgstr "błędny nagłówek bloku liścia %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2326 #, c-format msgid "leaf block %u for directory inode % bad tail\n" msgstr "błędna końcówka bloku liścia %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2365 #, c-format msgid "can't read leaf block %u for directory inode %\n" msgstr "nie można odczytać bloku liścia %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2377 #, c-format msgid "unknown magic number %#x for block %u in directory inode %\n" msgstr "nieznana liczba magiczna %#x dla bloku %u w i-węźle katalogu %\n" #: .././repair/phase6.c:2411 #, c-format msgid "can't read freespace block %u for directory inode %\n" msgstr "nie można odczytać bloku wolnego miejsca %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2424 #, c-format msgid "free block %u for directory inode % bad header\n" msgstr "błędny nagłówek wolnego bloku %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2436 #, c-format msgid "free block %u entry %i for directory ino % bad\n" msgstr "błędny wpis wolnego bloku %u numer %i dla i-węzła katalogu %\n" #: .././repair/phase6.c:2446 #, c-format msgid "free block %u for directory inode % bad nused\n" msgstr "błędna liczba nused w wolnym bloku %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2457 #, c-format msgid "missing freetab entry %u for directory inode %\n" msgstr "brak wpisu freetab %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2497 #, c-format msgid "malloc failed in longform_dir2_entry_check (% bytes)\n" msgstr "malloc nie powiodło się w longform_dir2_entry_check (% bajtów)\n" #: .././repair/phase6.c:2527 #, c-format msgid "realloc failed in longform_dir2_entry_check (%zu bytes)\n" msgstr "realloc nie powiodło się w longform_dir2_entry_check (%zu bajtów)\n" #: .././repair/phase6.c:2533 #, c-format msgid "can't read data block %u for directory inode %\n" msgstr "nie można odczytać bloku danych %u dla i-węzła katalogu %\n" #: .././repair/phase6.c:2639 #, c-format msgid "shortform dir inode % has null data entries \n" msgstr "i-węzeł krótkiego katalogu % ma zerowe wpisy danych\n" #: .././repair/phase6.c:2707 #, c-format msgid "entry \"%s\" in shortform dir % references non-existent ino %\n" msgstr "wpis \"%s\" w krótkim katalogu % odwołuje się do nie istniejącego i-węzła %\n" #: .././repair/phase6.c:2720 #, c-format msgid "entry \"%s\" in shortform dir inode % points to free inode %\n" msgstr "wpis \"%s\" w i-węźle krótkiego katalogu % wskazuje na wolny i-węzeł %\n" #: .././repair/phase6.c:2776 #, c-format msgid "entry \"%s\" in dir % references already connected dir ino %.\n" msgstr "wpis \"%s\" w katalogu % odwołuje się do już podłączonego i-węzła katalogu %.\n" #: .././repair/phase6.c:2793 #, c-format msgid "entry \"%s\" in dir % not consistent with .. value (%) in dir ino %.\n" msgstr "wpis \"%s\" w katalogu % niespójny z wartością .. (%) w i-węźle katalogu %.\n" #: .././repair/phase6.c:2833 .././repair/phase6.c:3166 msgid "junking entry\n" msgstr "wyrzucono wpis\n" #: .././repair/phase6.c:2837 .././repair/phase6.c:3170 msgid "would junk entry\n" msgstr "wpis zostałby wyrzucony\n" #: .././repair/phase6.c:2876 .././repair/phase6.c:3228 #, c-format msgid "setting size to % bytes to reflect junked entries\n" msgstr "ustawiono rozmiar na %, aby odzwierciedlał wyrzucone wpisy\n" #: .././repair/phase6.c:2928 #, c-format msgid "would set .. in sf dir inode % to %\n" msgstr "wpis .. w i-węźle katalogu sf % zostałby ustawiony na %\n" #: .././repair/phase6.c:2932 #, c-format msgid "setting .. in sf dir inode % to %\n" msgstr "ustawiono wpis .. w i-węźle katalogu sf % na %\n" #: .././repair/phase6.c:3036 #, c-format msgid "entry \"%s\" in shortform directory % references non-existent inode %\n" msgstr "wpis \"%s\" w krótkim katalogu % odwołuje się do nie istniejącego i-węzła %\n" #: .././repair/phase6.c:3050 #, c-format msgid "entry \"%s\" in shortform directory inode % points to free inode %\n" msgstr "wpis \"%s\" w i-węźle krótkiego katalogu % wskazuje na wolny i-węzeł %\n" #: .././repair/phase6.c:3103 #, c-format msgid "entry \"%s\" in directory inode % references already connected inode %.\n" msgstr "wpis \"%s\" w i-węźle katalogu % odwołuje się do już podłączonego i-węzła %.\n" #: .././repair/phase6.c:3123 #, c-format msgid "entry \"%s\" in directory inode % not consistent with .. value (%) in inode %,\n" msgstr "wpis \"%s\" w i-węźle katalogu % niespójny z wartością .. (%) w i-węźle %,\n" #: .././repair/phase6.c:3194 #, c-format msgid "would fix i8count in inode %\n" msgstr "i8count w i-węźle % zostałoby poprawione\n" #: .././repair/phase6.c:3207 #, c-format msgid "fixing i8count in inode %\n" msgstr "poprawiono i8count w i-węźle %\n" #: .././repair/phase6.c:3382 msgid "missing root directory .. entry, cannot fix in V1 dir filesystem\n" msgstr "brak wpisu .. w głównym katalogu, nie można naprawić w systemie plików V1\n" #: .././repair/phase6.c:3389 #, c-format msgid "%d bad entries found in dir inode %, cannot fix in V1 dir filesystem\n" msgstr "znaleziono %d błędnych wpisów w i-węźle katalogu %, nie można naprawić w systemie plików V1\n" #: .././repair/phase6.c:3396 #, c-format msgid "missing \".\" entry in dir ino %, cannot in fix V1 dir filesystem\n" msgstr "brak wpisu \".\" w i-węźle katalogu %, nie można naprawić w systemie plików V1\n" #: .././repair/phase6.c:3414 msgid "recreating root directory .. entry\n" msgstr "ponowne tworzenie wpisu .. głównego katalogu\n" #: .././repair/phase6.c:3434 #, c-format msgid "can't make \"..\" entry in root inode %, createname error %d\n" msgstr "nie można utworzyć wpisu \"..\" w i-węźle głównego katalogu %, błąd createname %d\n" #: .././repair/phase6.c:3445 msgid "would recreate root directory .. entry\n" msgstr "wpis .. głównego katalogu zostałby ponownie utworzony\n" #: .././repair/phase6.c:3469 #, c-format msgid "would create missing \".\" entry in dir ino %\n" msgstr "brakujący wpis \".\" w i-węźle katalogu % zostałby utworzony\n" #: .././repair/phase6.c:3476 #, c-format msgid "creating missing \".\" entry in dir ino %\n" msgstr "tworzenie brakującego wpisu \".\" w i-węźle katalogu %\n" #: .././repair/phase6.c:3500 #, c-format msgid "can't make \".\" entry in dir ino %, createname error %d\n" msgstr "nie można utworzyć wpisu \".\" w i-węźle katalogu %, błąd createname %d\n" #: .././repair/phase6.c:3589 #, c-format msgid "disconnected dir inode %, " msgstr "odłączony i-węzeł katalogu %, " #: .././repair/phase6.c:3591 #, c-format msgid "disconnected inode %, " msgstr "odłączony i-węzeł %, " #: .././repair/phase6.c:3593 msgid "cannot fix in V1 dir filesystem\n" msgstr "nie można naprawić w systemie plików katalogów V1\n" #: .././repair/phase6.c:3597 #, c-format msgid "moving to %s\n" msgstr "przeniesiono do %s\n" #: .././repair/phase6.c:3600 #, c-format msgid "would move to %s\n" msgstr "zostałby przeniesiony do %s\n" #: .././repair/phase6.c:3691 msgid "Phase 6 - check inode connectivity...\n" msgstr "Faza 6 - sprawdzanie łączności i-węzłów...\n" #: .././repair/phase6.c:3705 msgid "need to reinitialize root directory, but not supported on V1 dir filesystem\n" msgstr "trzeba ponownie utworzyć główny katalog, co nie jest obsługiwane w systemie plików V1\n" #: .././repair/phase6.c:3708 msgid "reinitializing root directory\n" msgstr "ponowne inicjowanie głównego katalogu\n" #: .././repair/phase6.c:3713 msgid "would reinitialize root directory\n" msgstr "główny katalog zostałby ponownie zainicjowany\n" #: .././repair/phase6.c:3719 msgid "reinitializing realtime bitmap inode\n" msgstr "ponowne inicjowanie i-węzła bitmapy realtime\n" #: .././repair/phase6.c:3723 msgid "would reinitialize realtime bitmap inode\n" msgstr "i-węzeł bitmapy realtime zostałby ponownie zainicjowany\n" #: .././repair/phase6.c:3729 msgid "reinitializing realtime summary inode\n" msgstr "ponowne inicjowanie i-węzła opisu realtime\n" #: .././repair/phase6.c:3733 msgid "would reinitialize realtime summary inode\n" msgstr "i-węzeł opisu realtime zostałby ponownie zainicjowany\n" #: .././repair/phase6.c:3739 msgid " - resetting contents of realtime bitmap and summary inodes\n" msgstr " - przestawianie zawartości i-węzłów bitmapy i opisu realtime\n" #: .././repair/phase6.c:3742 .././repair/phase6.c:3747 msgid "Warning: realtime bitmap may be inconsistent\n" msgstr "Uwaga: bitmapa realtime może być niespójna\n" #: .././repair/phase6.c:3753 msgid " - traversing filesystem ...\n" msgstr " - przechodzenie systemu plików...\n" #: .././repair/phase6.c:3776 msgid " - traversal finished ...\n" msgstr " - przechodzenie zakończone...\n" #: .././repair/phase6.c:3777 #, c-format msgid " - moving disconnected inodes to %s ...\n" msgstr " - przenoszenie odłączonych i-węzłów do %s...\n" #: .././repair/progress.c:16 msgid "inodes" msgstr "i-węzłów" #: .././repair/progress.c:18 .././db/freesp.c:406 msgid "blocks" msgstr "bloków" #: .././repair/progress.c:20 msgid "directories" msgstr "katalogów" #: .././repair/progress.c:22 msgid "allocation groups" msgstr "grup alokacji" #: .././repair/progress.c:24 msgid "AGI unlinked buckets" msgstr "odłączonych kubełków AGI" #: .././repair/progress.c:26 .././db/freesp.c:406 msgid "extents" msgstr "ekstentów" #: .././repair/progress.c:28 msgid "realtime extents" msgstr "ekstentów realtime" #: .././repair/progress.c:30 msgid "unlinked lists" msgstr "odłączonych list" #: .././repair/progress.c:37 #, c-format msgid " - %02d:%02d:%02d: %s - %llu of %llu %s done\n" msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu z %llu %s\n" #: .././repair/progress.c:39 #, c-format msgid " - %02d:%02d:%02d: %s - %llu %s done\n" msgstr " - %02d:%02d:%02d: %s - sprawdzono %llu %s\n" #: .././repair/progress.c:51 msgid "scanning filesystem freespace" msgstr "przeszukiwanie wolnego miejsca w systemie plików" #: .././repair/progress.c:53 msgid "scanning agi unlinked lists" msgstr "przeszukiwanie odłączonych list agi" #: .././repair/progress.c:55 msgid "check uncertain AG inodes" msgstr "sprawdzanie niepewnych i-węzłów AG" #: .././repair/progress.c:57 msgid "process known inodes and inode discovery" msgstr "przetwarzanie znanych i-węzłów i rozpoznawanie i-węzłów" #: .././repair/progress.c:59 msgid "process newly discovered inodes" msgstr "przetwarzanie nowo rozpoznanych i-węzłów" #: .././repair/progress.c:61 msgid "setting up duplicate extent list" msgstr "tworzenie listy powtórzonych ekstentów" #: .././repair/progress.c:63 msgid "initialize realtime bitmap" msgstr "inicjowanie bitmapy realtime" #: .././repair/progress.c:65 msgid "reset realtime bitmaps" msgstr "ponowne tworzenie bitmapy realtime" #: .././repair/progress.c:67 msgid "check for inodes claiming duplicate blocks" msgstr "szukanie i-węzłów odwołujących się do powtórzonych bloków" #: .././repair/progress.c:69 msgid "rebuild AG headers and trees" msgstr "przebudowywanie nagłówków i drzew AG" #: .././repair/progress.c:71 msgid "traversing filesystem" msgstr "przechodzenie systemu plików" #: .././repair/progress.c:73 msgid "traversing all unattached subtrees" msgstr "przechodzenie wszystkich odłączonych poddrzew" #: .././repair/progress.c:75 msgid "moving disconnected inodes to lost+found" msgstr "przenoszenie odłączonych i-węzłów do lost+found" #: .././repair/progress.c:77 msgid "verify and correct link counts" msgstr "sprawdzanie i poprawianie liczby dowiązań" #: .././repair/progress.c:79 msgid "verify link counts" msgstr "sprawdzanie liczby dowiązań" #: .././repair/progress.c:118 msgid "cannot malloc pointer to done vector\n" msgstr "nie udało się przydzielić wskaźnika do wektora wykonania\n" #: .././repair/progress.c:134 msgid "unable to create progress report thread\n" msgstr "nie udało się utworzyć wątku raportowania postępu\n" #: .././repair/progress.c:173 msgid "progress_rpt: cannot malloc progress msg buffer\n" msgstr "progress_rpt: nie udało się przydzielić bufora komunikatów postępu\n" #: .././repair/progress.c:187 msgid "progress_rpt: cannot create timer\n" msgstr "progress_rpt: nie można utworzyć zegara\n" #: .././repair/progress.c:190 msgid "progress_rpt: cannot set timer\n" msgstr "progress_rpt: nie można ustawić zegara\n" #: .././repair/progress.c:214 msgid "progress_rpt: cannot lock progress mutex\n" msgstr "progress_rpt: nie można zablokować muteksu\n" #: .././repair/progress.c:251 .././repair/progress.c:354 #, c-format msgid "%s" msgstr "%s" #: .././repair/progress.c:259 #, c-format msgid "\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n" msgstr "\t- %02d:%02d:%02d: Faza %d: miniony czas %s - przetworzono %d %s na minutę\n" #: .././repair/progress.c:264 #, c-format msgid "\t- %02d:%02d:%02d: Phase %d: %%% done - estimated remaining time %s\n" msgstr "\t- %02d:%02d:%02d: Faza %d: %%% zrobione - przewidywany pozostały czas %s\n" #: .././repair/progress.c:272 msgid "progress_rpt: error unlock msg mutex\n" msgstr "progress_rpt: błąd odblokowywania muteksu komunikatów\n" #: .././repair/progress.c:278 msgid "cannot delete timer\n" msgstr "nie można usunąć zegara\n" #: .././repair/progress.c:292 msgid "set_progress_msg: cannot lock progress mutex\n" msgstr "set_progress_msg: nie można zablokować mutekstu postępu\n" #: .././repair/progress.c:302 msgid "set_progress_msg: cannot unlock progress mutex\n" msgstr "set_progress_msg: nie można odblokować mutekstu postępu\n" #: .././repair/progress.c:322 msgid "print_final_rpt: cannot lock progress mutex\n" msgstr "print_final_rpt: nie można zablokować mutekstu postępu\n" #: .././repair/progress.c:358 msgid "print_final_rpt: cannot unlock progress mutex\n" msgstr "print_final_rpt: nie można odblokować muteksu postępu\n" #: .././repair/progress.c:407 #, c-format msgid "%02d:%02d:%02d" msgstr "%02d:%02d:%02d" #: .././repair/progress.c:429 #, c-format msgid "%d week" msgstr "%d tygodni" #: .././repair/progress.c:430 .././repair/progress.c:440 #: .././repair/progress.c:456 .././repair/progress.c:474 #: .././repair/progress.c:489 msgid "s" msgstr " " # XXX: ngettext() #: .././repair/progress.c:439 #, c-format msgid "%d day" msgstr "%d dni" #: .././repair/progress.c:446 .././repair/progress.c:463 #: .././repair/progress.c:481 .././repair/progress.c:491 msgid ", " msgstr ", " #: .././repair/progress.c:455 #, c-format msgid "%d hour" msgstr "%d godzin" #: .././repair/progress.c:473 #, c-format msgid "%d minute" msgstr "%d minut" #: .././repair/progress.c:488 #, c-format msgid "%d second" msgstr "%d sekund" #: .././repair/progress.c:509 #, c-format msgid "" "\n" " XFS_REPAIR Summary %s\n" msgstr "" "\n" " Podsumowanie XFS_REPAIR %s\n" #: .././repair/progress.c:511 msgid "Phase\t\tStart\t\tEnd\t\tDuration\n" msgstr "Faza\t\tPoczątek\tKoniec\t\tCzas trwania\n" #: .././repair/progress.c:516 .././repair/progress.c:519 #, c-format msgid "Phase %d:\tSkipped\n" msgstr "Faza %d:\tPominięta\n" #: .././repair/progress.c:523 #, c-format msgid "Phase %d:\t%02d/%02d %02d:%02d:%02d\t%02d/%02d %02d:%02d:%02d\t%s\n" msgstr "Faza %d:\t%02d.%02d %02d:%02d:%02d\t%02d.%02d %02d:%02d:%02d\t%s\n" #: .././repair/progress.c:529 #, c-format msgid "" "\n" "Total run time: %s\n" msgstr "" "\n" "Całkowity czas trwania: %s\n" #: .././repair/phase2.c:65 #, c-format msgid "zero_log: cannot find log head/tail (xlog_find_tail=%d), zeroing it anyway\n" msgstr "zero_log: nie znaleziono początku/końca logu (xlog_find_tail=%d), wyzerowano go\n" #: .././repair/phase2.c:71 #, c-format msgid "zero_log: head block % tail block %\n" msgstr "zero_log: blok początku % blok końca %\n" #: .././repair/phase2.c:77 msgid "" "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n" msgstr "" "UWAGA: system plików zawiera wartościowe zmiany metadanych w logu, który jest\n" "niszczony, ponieważ użyto opcji -L.\n" #: .././repair/phase2.c:81 msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" "BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" "musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" "a następnie odmontować go przed ponownym uruchomieniem xfs_repair. Jeśli\n" "systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" "log i spróbować naprawić system plików.\n" "Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" "proszę najpierw spróbować podmontować system plików.\n" #: .././repair/phase2.c:123 msgid "This filesystem has an external log. Specify log device with the -l option.\n" msgstr "Ten system plików ma zewnętrzny log. Należy podać urządzenie logu przy użyciu opcji -l.\n" #: .././repair/phase2.c:126 #, c-format msgid "Phase 2 - using external log on %s\n" msgstr "Faza 2 - użycie zewnętrznego logu na %s\n" #: .././repair/phase2.c:128 msgid "Phase 2 - using internal log\n" msgstr "Faza 2 - użycie wewnętrznego logu\n" #: .././repair/phase2.c:132 msgid " - zero log...\n" msgstr " - zerowanie logu...\n" #: .././repair/phase2.c:136 msgid " - scan filesystem freespace and inode maps...\n" msgstr " - przeszukiwanie wolnego miejsca i map i-węzłów w systemie plików...\n" #: .././repair/phase2.c:152 msgid "root inode chunk not found\n" msgstr "nie znaleziono danych głównego i-węzła\n" #: .././repair/phase2.c:171 msgid " - found root inode chunk\n" msgstr " - znaleziono dane głównego i-węzła\n" #: .././repair/phase2.c:177 msgid "root inode marked free, " msgstr "główny i-węzeł oznaczony jako wolny, " #: .././repair/phase2.c:186 msgid "realtime bitmap inode marked free, " msgstr "i-węzeł bitmapy realtime oznaczony jako wolny, " #: .././repair/phase2.c:195 msgid "realtime summary inode marked free, " msgstr "i-węzeł opisu realtime oznaczony jako wolny, " #: .././repair/rt.c:47 msgid "couldn't allocate memory for incore realtime bitmap.\n" msgstr "nie udało się przydzielić pamięci dla bitmapy realtime.\n" #: .././repair/rt.c:51 msgid "couldn't allocate memory for incore realtime summary info.\n" msgstr "nie udało się przydzielić pamięci dla opisu realtime.\n" #: .././repair/rt.c:151 .././db/check.c:1568 #, c-format msgid "rt summary mismatch, size %d block %llu, file: %d, computed: %d\n" msgstr "opis rt nie zgadza się, rozmiar %d bloku %llu, plik: %d, obliczono: %d\n" #: .././repair/rt.c:203 #, c-format msgid "can't find block %d for rtbitmap inode\n" msgstr "nie można odnaleźć bloku %d dla i-węzła bitmapy realtime\n" #: .././repair/rt.c:211 #, c-format msgid "can't read block %d for rtbitmap inode\n" msgstr "nie można odczytać bloku %d dla i-węzła bitmapy realtime\n" #: .././repair/rt.c:265 #, c-format msgid "block %d for rtsummary inode is missing\n" msgstr "brak bloku %d dla i-węzła opisu realtime\n" #: .././repair/rt.c:273 #, c-format msgid "can't read block %d for rtsummary inode\n" msgstr "nie można odczytać bloku %d dla i-węzła opisu realtime\n" #: .././quota/free.c:29 #, c-format msgid "" "\n" " reports the number of free disk blocks and inodes\n" "\n" " This command reports the number of total, used, and available disk blocks.\n" " It can optionally report the same set of numbers for inodes and realtime\n" " disk blocks, and will report on all known XFS filesystem mount points and\n" " project quota paths by default (see 'print' command for a list).\n" " -b -- report the block count values\n" " -i -- report the inode count values\n" " -r -- report the realtime block count values\n" " -h -- report in a human-readable format\n" " -N -- suppress the header from the output\n" "\n" msgstr "" "\n" " informacje o liczbie wolnych bloków i i-węzłów dysku\n" "\n" " To polecenie informuje o liczbie wszystkich, używanych i dostępnych bloków\n" " dysku. Opcjonalnie informuje o tym samym zestawie liczb dla i-węzłów i bloków\n" " realtime oraz domyślnie zgłasza wszystkie znane punkty montowania systemu\n" " plików XFS i ścieżki quot projektów (patrz lista w poleceniu 'print').\n" " -b - informacje o liczbach bloków\n" " -i - informacje o liczbach i-węzłów\n" " -r - informacje o liczbach bloków realtime\n" " -h - informacje w postaci czytelnej dla człowieka\n" " -N - pominięcie nagłówka z wyjścia\n" "\n" #: .././quota/free.c:154 #, c-format msgid "%s: project quota flag not set on %s\n" msgstr "%s: flaga quot projektu nie ustawiona dla %s\n" #: .././quota/free.c:163 #, c-format msgid "%s: project ID %u (%s) doesn't match ID %u (%s)\n" msgstr "%s: ID projektu %u (%s) nie zgadza się z ID %u (%s)\n" #: .././quota/free.c:230 #, c-format msgid "Filesystem " msgstr "System plików " #: .././quota/free.c:230 #, c-format msgid "Filesystem " msgstr "System plików " #: .././quota/free.c:233 #, c-format msgid " Size Used Avail Use%%" msgstr " Rozmiar Użyto Dost. %%uż." #: .././quota/free.c:234 #, c-format msgid " 1K-blocks Used Available Use%%" msgstr " Bloki 1K Użyto Dostępnych %%uż." #: .././quota/free.c:237 #, c-format msgid " Inodes Used Free Use%%" msgstr " I-węzły Użyto Wolne %%uż." #: .././quota/free.c:238 #, c-format msgid " Inodes IUsed IFree IUse%%" msgstr " I-węzły UżytoI WolneI %%użI" #: .././quota/free.c:239 #, c-format msgid " Pathname\n" msgstr " Ścieżka\n" #: .././quota/free.c:371 msgid "[-bir] [-hn] [-f file]" msgstr "[-bir] [hn] [-f plik]" #: .././quota/free.c:372 msgid "show free and used counts for blocks and inodes" msgstr "pokazanie liczby wolnych i zajętych bloków i i-węzłów" #: .././quota/init.c:48 #, c-format msgid "Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n" msgstr "Składnia: %s [-p program] [-c polecenie]... [-d projekt]... [ścieżka]\n" #: .././quota/path.c:39 #, c-format msgid "%sFilesystem Pathname\n" msgstr "%sSystem plików Ścieżka\n" #: .././quota/path.c:40 msgid " " msgstr " " #: .././quota/path.c:43 #, c-format msgid "%c%03d%c " msgstr "%c%03d%c " #: .././quota/path.c:45 #, c-format msgid "%-19s %s" msgstr "%-19s %s" #: .././quota/path.c:48 #, c-format msgid " (project %u" msgstr " (projekt %u" #: .././quota/path.c:50 #, c-format msgid ", %s" msgstr ", %s" #: .././quota/path.c:103 #, c-format msgid "No paths are available\n" msgstr "Brak ścieżek\n" #: .././quota/path.c:112 .././io/sendfile.c:103 .././io/file.c:81 #, c-format msgid "value %d is out of range (0-%d)\n" msgstr "wartość %d jest spoza zakresu (0-%d)\n" #: .././quota/path.c:126 .././io/file.c:94 msgid "[N]" msgstr "[N]" #: .././quota/path.c:131 msgid "set current path, or show the list of paths" msgstr "ustawienie bieżącej ścieżki lub pokazanie listy ścieżek" #: .././quota/path.c:139 msgid "list known mount points and projects" msgstr "wypisanie znanych punktów montowań i projektów" #: .././quota/project.c:45 #, c-format msgid "" "\n" " list projects or setup a project tree for tree quota management\n" "\n" " Example:\n" " 'project -c logfiles'\n" " (match project 'logfiles' to a directory, and setup the directory tree)\n" "\n" " Without arguments, report all projects found in the /etc/projects file.\n" " The project quota mechanism in XFS can be used to implement a form of\n" " directory tree quota, where a specified directory and all of the files\n" " and subdirectories below it (i.e. a tree) can be restricted to using a\n" " subset of the available space in the filesystem.\n" "\n" " A managed tree must be setup initially using the -c option with a project.\n" " The specified project name or identifier is matched to one or more trees\n" " defined in /etc/projects, and these trees are then recursively descended\n" " to mark the affected inodes as being part of that tree - which sets inode\n" " flags and the project identifier on every file.\n" " Once this has been done, new files created in the tree will automatically\n" " be accounted to the tree based on their project identifier. An attempt to\n" " create a hard link to a file in the tree will only succeed if the project\n" " identifier matches the project identifier for the tree. The xfs_io utility\n" " can be used to set the project ID for an arbitrary file, but this can only\n" " be done by a privileged user.\n" "\n" " A previously setup tree can be cleared from project quota control through\n" " use of the -C option, which will recursively descend the tree, clearing\n" " the affected inodes from project quota control.\n" "\n" " The -c option can be used to check whether a tree is setup, it reports\n" " nothing if the tree is correct, otherwise it reports the paths of inodes\n" " which do not have the project ID of the rest of the tree, or if the inode\n" " flag is not set.\n" "\n" " The -p option can be used to manually specify project path without\n" " need to create /etc/projects file. This option can be used multiple times\n" " to specify multiple paths. When using this option only one projid/name can\n" " be specified at command line. Note that /etc/projects is also used if exists.\n" "\n" " The -d option allows to descend at most levels of directories\n" " below the command line arguments. -d 0 means only apply the actions\n" " to the top level of the projects. -d -1 means no recursion limit (default).\n" "\n" " The /etc/projid and /etc/projects file formats are simple, and described\n" " on the xfs_quota man page.\n" "\n" msgstr "" "\n" " wypisanie projektów lub ustanowienie drzewa projektu do zarządzania limitami\n" "\n" " Przykład:\n" " 'project -c logfiles'\n" " (dopasowanie projektu 'logfiles' do katalogu i ustanowienie drzewa katalogów)\n" "\n" " Bez argumentów project wypisuje wszystkie projekty znalezione w pliku\n" " /etc/projects. Mechanizm quota dla projektów w XFS-ie może być używany do\n" " zaimplementowania formy limitów dla drzewa katalogów, gdzie podany katalog\n" " i wszystkie pliki i podkatalogi poniżej niego (czyli drzewo) mogą być\n" " ograniczone do używania podzbioru miejsca dostępnego w systemie plików.\n" "\n" " Zarządzane drzewo musi być ustanowione początkowo przy użyciu opcji project -c.\n" " Podana nazwa lub identyfikator projektu jest dopasowywany do jednego lub\n" " większej liczby drzew zdefiniowanych w /etc/projects, a następnie te drzewa są\n" " rekurencyjnie przechodzone w celu oznaczenia i-węzłów jako będących częścią\n" " tego drzewa - co ustawia flagi i-węzłów i identyfikator projektu dla każdego\n" " pliku.\n" " Po zrobieniu tego nowe pliki tworzone w drzewie będą automatycznie liczone jako\n" " część drzewa o ich identyfikatorze projektu. Próba utworzenia dowiązania\n" " zwykłego do pliku w drzewie powiedzie się tylko jeśli identyfikator projektu\n" " pasuje do identyfikatora projektu drzewa. Można użyć narzędzia xfs_io do\n" " ustawienia ID projektu dla dowolnego pliku, ale może tego dokonać tylko\n" " uprzywilejowany użytkownik.\n" "\n" " Poprzednio ustanowione drzewa można usunąć z kontroli limitów projektu poprzez\n" " użycie opcji -C, która rekurencyjnie przejdzie drzewo, usuwając i-węzły spod\n" " kontroli limitów projektu.\n" "\n" " Opcji -c można użyć do sprawdzenia czy drzewo zostało ustanowione - nie\n" " informuje o niczym jeśli drzewo jest poprawne, a w przeciwnym wypadku zgłasza\n" " ścieżki i-węzłów nie mające ID projektu takiego jak reszta drzewa lub nie\n" " mające ustawionej flagi.\n" "\n" " Opcja -p <ścieżka> umożliwia podanie ścieżki projektu w linii poleceń\n" " bez potrzeby tworzenia pliku /etc/projects. Ta opcja może być używana\n" " wielokrotnie w celu przekazanie wielu ścieżek projektu. Tylko jeden\n" " identyfikator projektu może być podawy w linii poleceń w momencie\n" " używania opcji -p. Jeśli plik /etc/projects istnieje to także jest używany\n" " oprócz ścieżek w linii poleceń.\n" "\n" " Opcja -d pozwala na ograniczanie zagłębiania się w podkatalogach\n" " projektu do granicy . -d 0 oznacza najwyższy poziom. -d 1 oznacza\n" " brak limitu zagłębiania (domyślny).\n" "\n" " Format plików /etc/projid i /etc/projects jest prosty i opisany na stronie\n" " manuala xfs_quota.\n" "\n" #: .././quota/project.c:108 .././quota/project.c:153 .././quota/project.c:200 #, c-format msgid "%s: cannot stat file %s\n" msgstr "%s: nie można wykonać stat na pliku %s\n" #: .././quota/project.c:112 .././quota/project.c:157 .././quota/project.c:204 #, c-format msgid "%s: skipping special file %s\n" msgstr "%s: pominięto plik specjalny %s\n" #: .././quota/project.c:118 .././quota/project.c:163 .././quota/project.c:210 #: .././mkfs/proto.c:284 .././libxfs/init.c:110 .././io/attr.c:171 #: .././io/attr.c:247 .././io/open.c:397 .././io/open.c:469 .././io/open.c:593 #: .././io/open.c:615 #, c-format msgid "%s: cannot open %s: %s\n" msgstr "%s: nie można otworzyć %s: %s\n" #: .././quota/project.c:122 .././quota/project.c:168 .././quota/project.c:215 #: .././io/attr.c:174 .././io/attr.c:221 .././io/attr.c:250 .././io/attr.c:321 #, c-format msgid "%s: cannot get flags on %s: %s\n" msgstr "%s: nie można pobrać flag %s: %s\n" #: .././quota/project.c:126 #, c-format msgid "%s - project identifier is not set (inode=%u, tree=%u)\n" msgstr "%s - identyfikator projektu nie ustawiony (i-węzeł=%u, drzewo=%u)\n" #: .././quota/project.c:130 #, c-format msgid "%s - project inheritance flag is not set\n" msgstr "%s - flaga dziedziczenia projektu nie ustawiona\n" #: .././quota/project.c:178 #, c-format msgid "%s: cannot clear project on %s: %s\n" msgstr "%s: nie można usunąć projektu z %s: %s\n" #: .././quota/project.c:225 #, c-format msgid "%s: cannot set project on %s: %s\n" msgstr "%s: nie można ustawić projektu na %s: %s\n" #: .././quota/project.c:240 #, c-format msgid "Checking project %s (path %s)...\n" msgstr "Sprawdzanie projektu %s (ścieżka %s)...\n" #: .././quota/project.c:244 #, c-format msgid "Setting up project %s (path %s)...\n" msgstr "Ustanawianie projektu %s (ścieżka %s)...\n" #: .././quota/project.c:248 #, c-format msgid "Clearing project %s (path %s)...\n" msgstr "Usuwanie projektu %s (ścieżka %s)...\n" #: .././quota/project.c:271 #, c-format msgid "Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n" msgstr "" "Przetworzono %d (z %s oraz z linii poleceń) ścieżek dla projektu %s\n" "z ograniczeniem %s (%d)\n" #: .././quota/project.c:274 msgid "infinite" msgstr "nieaktywnym" #: .././quota/project.c:274 msgid "limited" msgstr "aktywnym" #: .././quota/project.c:319 #, c-format msgid "projects file \"%s\" doesn't exist\n" msgstr "plik projektów \"%s\" nie istnieje\n" #: .././quota/project.c:326 #, c-format msgid "%s: only one projid/name can be specified when using -p , %d found.\n" msgstr "%s: tylko jeden id projektu/nazwa może być podana kiedy opcja -p <ścieżka> jest w użyciu. Znaleziono %d.\n" #: .././quota/project.c:336 #, c-format msgid "%s - no such project in %s or invalid project number\n" msgstr "%s - nie ma takiego projektu w %s lub błędny numer projektu\n" #: .././quota/project.c:353 msgid "[-c|-s|-C|-d |-p ] project ..." msgstr "[-c|-s|-C| -d |-p <ścieżka>] projekt ..." #: .././quota/project.c:356 msgid "check, setup or clear project quota trees" msgstr "sprawdzenie, ustanowienie lub usunięcie drzew projektów" #: .././quota/quot.c:55 #, c-format msgid "" "\n" " display a summary of filesystem ownership\n" "\n" " -a -- summarise for all local XFS filesystem mount points\n" " -c -- display three columns giving file size in kilobytes, number of files\n" " of that size, and cumulative total of kilobytes in that size or\n" " smaller file. The last row is used as an overflow bucket and is the\n" " total of all files greater than 500 kilobytes.\n" " -v -- display three columns containing the number of kilobytes not\n" " accessed in the last 30, 60, and 90 days.\n" " -g -- display group summary\n" " -p -- display project summary\n" " -u -- display user summary\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" "\n" " wyświetlenie podsumowania własności systemu plików\n" "\n" " -a - podsumowanie dla wszystkich punktów montowania systemów plików XFS\n" " -c - wyświetlenie trzech kolumn z rozmiarem plików w kilobajtach, liczbą\n" " plików tego rozmiaru i sumą kilobajtów w plikach o tym lub mniejszym\n" " rozmiarze. Ostatni wiersz podsumowuje pliki większe niż 500 kilobajtów.\n" " -v - wyświetlenie trzech kolumn zawierających liczbę kilobajtów, do których\n" " nie było odwołań przez ostatnie 30, 60 i 90 dni.\n" " -g - wyświetlenie podsumowania dla grup\n" " -p - wyświetlenie podsumowania dla projektów\n" " -u - wyświetlenie podsumowania dla użytkowników\n" " -b - wyświetlenie liczby wykorzystanych bloków\n" " -i - wyświetlenie liczby wykorzystanych i-węzłów\n" " -r - wyświetlenie liczby wykorzystanych blików realtime\n" " -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" " -N - pominięcie początkowego nagłówka\n" " -f - zapisanie wyjścia do pliku\n" " (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" " numeru (tzn. uid/gid/projid).\n" #: .././quota/quot.c:219 #, c-format msgid "%s (%s) %s:\n" msgstr "%s (%s) %s:\n" #: .././quota/quot.c:295 #, c-format msgid "%s (%s):\n" msgstr "%s (%s):\n" #: .././quota/quot.c:300 .././quota/quot.c:304 #, c-format msgid "%d\t%llu\t%llu\n" msgstr "%d\t%llu\t%llu\n" #: .././quota/quot.c:418 msgid "[-bir] [-gpu] [-acv] [-f file]" msgstr "[-bir] [-gpu] [-acv] [-f plik]" #: .././quota/quot.c:419 msgid "summarize filesystem ownership" msgstr "podsumowanie własności systemu plików" #: .././quota/quota.c:32 #, c-format msgid "" "\n" " display usage and quota information\n" "\n" " -g -- display group quota information\n" " -p -- display project quota information\n" " -u -- display user quota information\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -v -- increase verbosity in reporting (also dumps zero values)\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n" msgstr "" "\n" " wyświetlenie informacji o wykorzystaniu miejsca i limitach\n" "\n" " -g - wyświetlenie informacji o limitach grup\n" " -p - wyświetlenie informacji o limitach projektów\n" " -u - wyświetlenie informacji o limitach użytkowników\n" " -b - wyświetlenie liczby wykorzystanych bloków\n" " -i - wyświetlenie liczby wykorzystanych i-węzłów\n" " -r - wyświetlenie liczby wykorzystanych bloków realtime\n" " -h - użycie formatu czytelnego dla człowieka\n" " -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" " -N - pominięcie początkowego nagłówka\n" " -v - zwiększenie szczegółowości (wypisywanie także wartości zerowych)\n" " -f - zapisanie wyjścia do pliku\n" " (opcjonalny) użytkownik/grupa/projekt może być podany za pomocą nazwy lub\n" " numeru (tzn. uid/gid/projid).\n" #: .././quota/quota.c:85 #, c-format msgid "" "Disk quotas for %s %s (%u)\n" "Filesystem%s" msgstr "" "Limity dyskowe (quota) dla %s %s (%u)\n" "System plików%s" #: .././quota/quota.c:90 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr " Bloki Quota Limit Czas ostrz. " #: .././quota/quota.c:91 #, c-format msgid " Blocks Quota Limit Warn/Time " msgstr " Bloki Quota Limit Czas ostrz. " #: .././quota/quota.c:94 #, c-format msgid " Files Quota Limit Warn/Time " msgstr " Pliki Quota Limit Czas ostrz. " #: .././quota/quota.c:95 #, c-format msgid " Files Quota Limit Warn/Time " msgstr " Pliki Quota Limit Czas ostrz. " #: .././quota/quota.c:98 #, c-format msgid "Realtime Quota Limit Warn/Time " msgstr "Realtime Quota Limit Czas ostrz. " #: .././quota/quota.c:99 #, c-format msgid " Realtime Quota Limit Warn/Time " msgstr " Realtime Quota Limit Czas ostrz. " #: .././quota/quota.c:235 #, c-format msgid "%s: cannot find user %s\n" msgstr "%s: nie można odnaleźć użytkownika %s\n" #: .././quota/quota.c:285 #, c-format msgid "%s: cannot find group %s\n" msgstr "%s: nie można odnaleźć grupy %s\n" #: .././quota/quota.c:342 #, c-format msgid "%s: must specify a project name/ID\n" msgstr "%s: należy podać nazwę/ID projektu\n" #: .././quota/quota.c:355 #, c-format msgid "%s: cannot find project %s\n" msgstr "%s: nie można odnaleźć projektu %s\n" #: .././quota/quota.c:460 msgid "[-bir] [-gpu] [-hnNv] [-f file] [id|name]..." msgstr "[-bir] [-gpu] [-hnNv] [-f plik] [id|nazwa]..." #: .././quota/quota.c:461 msgid "show usage and limits" msgstr "pokazanie wykorzystania i limitów" #: .././quota/report.c:33 .././quota/report.c:647 .././quota/edit.c:697 msgid "[-gpu] [-f file]" msgstr "[-gpu] [-f plik]" #: .././quota/report.c:34 .././quota/report.c:648 msgid "dump quota information for backup utilities" msgstr "zrzucenie informacji o limitach (quota) dla narzędzi backupowych" #: .././quota/report.c:36 #, c-format msgid "" "\n" " create a backup file which contains quota limits information\n" " -g -- dump out group quota limits\n" " -p -- dump out project quota limits\n" " -u -- dump out user quota limits (default)\n" " -f -- write the dump out to the specified file\n" "\n" msgstr "" "\n" " utworzenie pliku kopii zapasowej zawierającego informacje o limitach (quota)\n" " -g - zrzucenie limitów dla grup\n" " -p - zrzucenie limitów dla projektów\n" " -u - zrzucenie limitów dla użytkowników (domyślne)\n" " -f - zapisanie zrzutu do podanego pliku\n" "\n" #: .././quota/report.c:48 msgid "[-bir] [-gpu] [-ahntLNU] [-f file]" msgstr "[-bir] [-gpu] [-ahntLNU] [-f plik]" #: .././quota/report.c:49 .././quota/report.c:657 msgid "report filesystem quota information" msgstr "raportowanie informacji o limitach (quota) w systemie plików" #: .././quota/report.c:51 #, c-format msgid "" "\n" " report used space and inodes, and quota limits, for a filesystem\n" " Example:\n" " 'report -igh'\n" " (reports inode usage for all groups, in an easy-to-read format)\n" " This command is the equivalent of the traditional repquota command, which\n" " prints a summary of the disk usage and quotas for the current filesystem,\n" " or all filesystems.\n" " -a -- report for all mounted filesystems with quota enabled\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the header from the output\n" " -t -- terse output format, hides rows which are all zero\n" " -L -- lower ID bound to report on\n" " -U -- upper ID bound to report on\n" " -g -- report group usage and quota information\n" " -p -- report project usage and quota information\n" " -u -- report user usage and quota information\n" " -b -- report blocks-used information only\n" " -i -- report inodes-used information only\n" " -r -- report realtime-blocks-used information only\n" "\n" msgstr "" "\n" " informacje o wykorzystanym miejscu i i-węzłach oraz limitach quota dla systemu\n" " plików\n" "\n" " Przykład:\n" " 'report -igh'\n" " (raport o wykorzystaniu i-węzłów dla wszystkich grup w czytelnym formacie)\n" "\n" " To polecenie jest odpowiednikiem tradycyjnego polecenia repquota, wypisującego\n" " podsumowanie wykorzystania dysku i limitów dla bieżącego systemu plików lub\n" " wszystkich systemów plików.\n" " -a - informacje o wszystkich zamontowanych systemach plików z limitami\n" " -h - informacje w formacie czytelnym dla człowieka\n" " -n - pominięcie tłumaczenia identyfikatorów na nazwy, wypisywanie ID\n" " -N - pominięcie początkowego nagłówka\n" " -t - zwięzły format, ukrycie wierszy zerowych\n" " -L - dolna granica ID dla wypisywanych informacji\n" " -U - górna granica ID dla wypisywanych informacji\n" " -g - informacje o wykorzystanym miejscu i limitach dla grup\n" " -p - informacje o wykorzystanym miejscu i limitach dla projektów\n" " -u - informacje o wykorzystanym miejscu i limitach dla użytkowników\n" " -b - tylko informacje o wykorzystanych blokach\n" " -i - tylko informacje o wykorzystanych i-węzłach\n" " -r - tylko informacje o wykorzystanych blokach realtime\n" "\n" #: .././quota/report.c:228 #, c-format msgid "%s quota on %s (%s)\n" msgstr "limit %s na %s (%s)\n" #: .././quota/report.c:253 .././quota/report.c:261 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Użyto Miękki Twardy Ostrzeżenie " #: .././quota/report.c:254 .././quota/report.c:262 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Użyto Miękki Twardy Ostrzeżenie " #: .././quota/report.c:257 #, c-format msgid " Used Soft Hard Warn/Grace " msgstr " Użyto Miękki Twardy Ostrzeżenie" #: .././quota/report.c:258 #, c-format msgid " Used Soft Hard Warn/ Grace " msgstr " Użyto Miękki Twardy Ostrzeżenie " #: .././quota/report.c:656 msgid "[-bir] [-gpu] [-ahnt] [-f file]" msgstr "[-bir] [-gpu] [-ahnt] [-f plik]" #: .././quota/state.c:33 #, c-format msgid "" "\n" " turn filesystem quota off, both accounting and enforcement\n" "\n" " Example:\n" " 'off -uv' (switch off user quota on the current filesystem)\n" " This command is the equivalent of the traditional quotaoff command,\n" " which disables quota completely on a mounted filesystem.\n" " Note that there is no 'on' command - for XFS filesystems (with the\n" " exception of the root filesystem on IRIX) quota can only be enabled\n" " at mount time, through the use of one of the quota mount options.\n" "\n" " The state command is useful for displaying the current state. Using\n" " the -v (verbose) option with the 'off' command will display the quota\n" " state for the affected filesystem once the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " wyłączenie podsystemu quota (zarówno rozliczania jak i wymuszania)\n" "\n" " Przykład:\n" " 'off -uv' (wyłączenie limitów użytkownika w bieżącym systemie plików)\n" "\n" " To polecenie jest odpowiednikiem tradycyjnego polecenia quotaoff,\n" " wyłączającego całkowicie limity na podmontowanym systemie plików.\n" " Należy zauważyć, że nie ma polecenia 'on' - dla systemów plików XFS\n" " (z wyjątkiem głównego systemu plików pod systemem IRIX) limity można\n" " włączyć wyłącznie na etapie montowania, poprzez użycie jednej z opcji\n" " quota programu mount.\n" "\n" " Polecenie state jest przydatne do wyświetlania aktualnego stanu. Użycie\n" " opcji -v (szczegółowość) dla polecenia 'off' wyświetli stan quoty dla\n" " danego systemu plików po zakończeniu operacji.\n" " Rodzaj limitu którego dotyczy polecenie można wybrać opcją -g (grupy),\n" " -p (projekty) lub -u (użytkownicy); domyślnie polecenie dotyczy limitów\n" " użytkowników (można podać wiele rodzajów).\n" "\n" #: .././quota/state.c:56 #, c-format msgid "" "\n" " query the state of quota on the current filesystem\n" "\n" " This is a verbose status command, reporting whether or not accounting\n" " and/or enforcement are enabled for a filesystem, which inodes are in\n" " use as the quota state inodes, and how many extents and blocks are\n" " presently being used to hold that information.\n" " The quota type is specified via -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " odczytanie stanu podsystemu quota w bieżącym systemie plików\n" "\n" " Jest to polecenie szczegółowo informujące o stanie, opisujące czy włączone\n" " jest rozliczanie i/lub wymuszanie limitów w systemie plików, które i-węzły\n" " są wykorzystywane jako i-węzły stanu quot oraz ile ekstentów i bloków jest\n" " aktualnie używana do przechowywania tych informacji.\n" " Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" " domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" "\n" #: .././quota/state.c:72 #, c-format msgid "" "\n" " enable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and has quota accounting enabled, but not\n" " quota enforcement, enforcement can be enabled with this command.\n" " With the -v (verbose) option, the status of the filesystem will be\n" " reported after the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " włączenie wymuszania limitów w systemie plików\n" "\n" " Jeśli system plików jest podmontowany i ma włączone rozliczanie limitów,\n" " ale nie ma wymuszania limitów, można włączyć wymuszanie tym poleceniem.\n" " Z opcją -v (szczegółowość) po zakończeniu operacji zostanie zraportowany\n" " stan systemu plików.\n" " Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" " domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" "\n" #: .././quota/state.c:88 #, c-format msgid "" "\n" " disable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and is currently enforcing quota, this\n" " provides a mechanism to switch off the enforcement, but continue to\n" " perform used space (and used inodes) accounting.\n" " The affected quota type is -g (groups), -p (projects) or -u (users).\n" "\n" msgstr "" "\n" " wyłączenie wymuszania limitów w systemie plików\n" "\n" " Jeśli system plików jest podmontowany i aktualnie wymusza przestrzeganie\n" " limitów, tym poleceniem można wyłączyć wymuszanie, ale nadal pozostawić\n" " rozliczanie wykorzystanego miejsca (oraz i-węzłów).\n" " Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy).\n" "\n" #: .././quota/state.c:102 #, c-format msgid "" "\n" " remove any space being used by the quota subsystem\n" "\n" " Once quota has been switched 'off' on a filesystem, the space that\n" " was allocated to holding quota metadata can be freed via this command.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n" msgstr "" "\n" " zwolnienie miejsca zajmowanego przez podsystem quota\n" "\n" " Po wyłączeniu limitów dla systemu plików można tym poleceniem zwolnić miejsce\n" " przydzielone na przechowywanie metadanych quot.\n" " Rodzaj limitów podaje się opcją -g (grupy), -p (projekty) lub -u (użytkownicy);\n" " domyślnie polecenie dotyczy limitów użytkowników (można podać wiele rodzajów).\n" "\n" #: .././quota/state.c:121 #, c-format msgid "%s quota state on %s (%s)\n" msgstr "stan limitów %s na %s (%s)\n" #: .././quota/state.c:123 #, c-format msgid " Accounting: %s\n" msgstr " Rozliczanie: %s\n" #: .././quota/state.c:123 .././quota/state.c:124 msgid "ON" msgstr "WŁĄCZONE" #: .././quota/state.c:123 .././quota/state.c:124 msgid "OFF" msgstr "WYŁĄCZONE" #: .././quota/state.c:124 #, c-format msgid " Enforcement: %s\n" msgstr " Wymuszanie: %s\n" #: .././quota/state.c:126 #, c-format msgid " Inode: #%llu (%llu blocks, %lu extents)\n" msgstr " I-węzeł: #%llu (%llu bloków, %lu ekstentów)\n" #: .././quota/state.c:131 #, c-format msgid " Inode: N/A\n" msgstr " I-węzeł: N/A\n" #: .././quota/state.c:140 #, c-format msgid "%s grace time: %s\n" msgstr "czas pobłażliwości %s: %s\n" #: .././quota/state.c:157 #, c-format msgid "%s quota are not enabled on %s\n" msgstr "Limity %s nie są włączone na %s\n" #: .././quota/state.c:527 .././quota/state.c:543 .././quota/state.c:551 #: .././quota/state.c:559 msgid "[-gpu] [-v]" msgstr "[-gpu] [-v]" #: .././quota/state.c:528 msgid "permanently switch quota off for a path" msgstr "wyłączenie limitów na stałe dla ścieżki" #: .././quota/state.c:535 msgid "[-gpu] [-a] [-v] [-f file]" msgstr "[-gpu] [-a] [-v] [-f plik]" #: .././quota/state.c:536 msgid "get overall quota state information" msgstr "uzyskanie ogólnych informacji o stanie quot" #: .././quota/state.c:544 msgid "enable quota enforcement" msgstr "włączenie wymuszania limitów" #: .././quota/state.c:552 msgid "disable quota enforcement" msgstr "wyłączenie wymuszania limitów" #: .././quota/state.c:560 msgid "remove quota extents from a filesystem" msgstr "usunięcie ekstentów związanych z limitami z systemu plików" #: .././quota/util.c:59 #, c-format msgid "[-none-]" msgstr "[-brak-]" #: .././quota/util.c:59 #, c-format msgid "[--none--]" msgstr "[--brak--]" #: .././quota/util.c:62 #, c-format msgid "[------]" msgstr "[------]" #: .././quota/util.c:62 #, c-format msgid "[--------]" msgstr "[--------]" # XXX: ngettext() #: .././quota/util.c:66 .././quota/util.c:69 msgid "day" msgstr "dzień" #: .././quota/util.c:66 .././quota/util.c:69 msgid "days" msgstr "dni" #: .././quota/util.c:194 msgid "Blocks" msgstr "Bloki" #: .././quota/util.c:194 msgid "Inodes" msgstr "I-węzły" #: .././quota/util.c:194 msgid "Realtime Blocks" msgstr "Bloki realtime" #: .././quota/util.c:209 msgid "User" msgstr "użytkowników" #: .././quota/util.c:209 msgid "Group" msgstr "grup" #: .././quota/util.c:209 msgid "Project" msgstr "projektów" #: .././quota/util.c:417 #, c-format msgid "%s: open on %s failed: %s\n" msgstr "%s: open dla %s nie powiodło się: %s\n" #: .././quota/util.c:423 #, c-format msgid "%s: fdopen on %s failed: %s\n" msgstr "%s: fdopen dla %s nie powiodło się: %s\n" #: .././quota/edit.c:36 #, c-format msgid "" "\n" " modify quota limits for the specified user\n" "\n" " Example:\n" " 'limit bsoft=100m bhard=110m tanya\n" "\n" " Changes the soft and/or hard block limits, inode limits and/or realtime\n" " block limits that are currently being used for the specified user, group,\n" " or project. The filesystem identified by the current path is modified.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota limits\n" " -p -- modify project quota limits\n" " -u -- modify user quota limits\n" " The block limit values can be specified with a units suffix - accepted\n" " units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" "\n" " zmiana limitów quot dla podanego użytkownika\n" "\n" "Przykład:\n" " 'limit bsoft=100m bhard=110m tanya'\n" "\n" " limit zmienia miękki i/lub twardy limit bloków, limity i-węzłów i/lub limity\n" " bloków realtime aktualnie używane dla podanego użytkownika, grupy lub projektu.\n" " System plików określony bieżącą ścieżką jest modyfikowany.\n" " -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" " -g - zmiana limitów quot grupy\n" " -p - zmiana limitów quot projektu\n" " -u - zmiana limitów quot użytkownika\n" " Wartości limitów bloków mogą być podane z końcówką jednostki - przyjmowane\n" " jednostki to: k (kilobajty), m (megabajty), g (gigabajty) i t (terabajty).\n" " Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" "\n" #: .././quota/edit.c:59 #, c-format msgid "" "\n" " modify quota enforcement timeout for the current filesystem\n" "\n" " Example:\n" " 'timer -i 3days'\n" " (soft inode limit timer is changed to 3 days)\n" "\n" " Changes the timeout value associated with the block limits, inode limits\n" " and/or realtime block limits for all users, groups, or projects on the\n" " current filesystem.\n" " As soon as a user consumes the amount of space or number of inodes set as\n" " the soft limit, a timer is started. If the timer expires and the user is\n" " still over the soft limit, the soft limit is enforced as the hard limit.\n" " The default timeout is 7 days.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota timer\n" " -p -- modify project quota timer\n" " -u -- modify user quota timer\n" " -b -- modify the blocks-used timer\n" " -i -- modify the inodes-used timer\n" " -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" " The timeout value is specified as a number of seconds, by default.\n" " However, a suffix may be used to alternatively specify minutes (m),\n" " hours (h), days (d), or weeks (w) - either the full word or the first\n" " letter of the word can be used.\n" "\n" msgstr "" "\n" " zmiana czasu wymuszenia limitów dla bieżącego systemu plików\n" "\n" " Przykład:\n" " 'timer -i 3days'\n" " (zmiana czasu wymuszenia miękkiego limitu i-węzłów na 3 dni)\n" "\n" " timer zmienia wartość ograniczenia czasu związanego z limitami bloków,\n" " limitami i-węzłów i/lub limitami bloków realtime dla wszystkich użytkowników,\n" " grup lub projektów na bieżącym systemie plików.\n" " Po tym jak użytkownik wykorzysta ilość miejsca lub liczbę i-węzłów ustawioną\n" " jako miękki limit, zaczyna działać zegar. Kiedy czas minie, a użytkownik nadal\n" " przekracza miękki limit, miękki limit staje się twardym.\n" " Domyślne ograniczenie czasowe to 7 dni.\n" " -d - ustawienie wartości domyślnych, użytych pierwszy raz przy tworzeniu pliku\n" " -g - zmiana czasu dla limitów quot grup\n" " -p - zmiana czasu dla limitów quot projektów\n" " -u - zmiana czasu dla limitów quot użytkowników\n" " -b - zmiana czasu dla użytych bloków\n" " -i - zmiana czasu dla użytych i-węzłów\n" " -r - zmiana czasu dla użytych bloków na (opcjonalnym) podwolumenie realtime\n" " Wartość ograniczenia czasu jest podawana domyślnie jako liczba sekund.\n" " Jednak można dodać końcówkę, aby podać czas w minutach (m), godzinach (h),\n" " dniach (d) lub tygodniach (w) - można użyć pełnego słowa lub pierwsze litery.\n" "\n" #: .././quota/edit.c:91 #, c-format msgid "" "\n" " modify the number of quota warnings sent to the specified user\n" "\n" " Example:\n" " 'warn 2 jimmy'\n" " (tell the quota system that two warnings have been sent to user jimmy)\n" "\n" " Changes the warning count associated with the block limits, inode limits\n" " and/or realtime block limits for the specified user, group, or project.\n" " When a user has been warned the maximum number of times allowed, the soft\n" " limit is enforced as the hard limit. It is intended as an alternative to\n" " the timeout system, where the system administrator updates a count of the\n" " number of warnings issued to people, and they are penalised if the warnings\n" " are ignored.\n" " -d -- set maximum warning count, which triggers soft limit enforcement\n" " -g -- set group quota warning count\n" " -p -- set project quota warning count\n" " -u -- set user quota warning count\n" " -b -- set the blocks-used warning count\n" " -i -- set the inodes-used warning count\n" " -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" " The user/group/project can be specified either by name or by number.\n" "\n" msgstr "" "\n" " zmiana liczby ostrzeżeń quot wysyłanych do podanego użytkownika\n" "\n" " Przykład:\n" " 'warn 2 jimmy'\n" " (przekazanie systemowi quota, że wysłano 2 ostrzeżenia do użytkownika jimmy)\n" "\n" " warn zmienia liczbę ostrzeżeń związanych z limitami bloków, limitami i-węzłów\n" " i/lub limitami bloków realtime dla podanego użytkownika, grupy lub projektu.\n" " Kiedy użytkownik został ostrzeżony maksymalną dozwoloną liczbę razy, miękki\n" " limit staje się twardym. Jest to pomyślane jako alternatywa dla systemu\n" " ograniczeń czasowych, gdzie administrator uaktualnia licznik ostrzeżeń\n" " wysłanych do ludzi i karze użytkowników ignorujących ostrzeżenia.\n" " -d - ustawienie maksymalnej liczby ostrzeżeń, po której wymuszane są limity\n" " -g - ustawienie liczby ostrzeżeń dla grupy\n" " -p - ustawienie liczby ostrzeżeń dla projektu\n" " -u - ustawienie liczby ostrzeżeń dla grupy\n" " -b - ustawienie liczby ostrzeżeń dla użytych bloków\n" " -i - ustawienie liczby ostrzeżeń dla użytych i-węzłów\n" " -r - ustawienie liczby ostrzeżeń dla użytych bloków na podwolumenie realtime\n" " Użytkownik/grupa/projekt może być podany za pomocą nazwy lub numeru.\n" "\n" #: .././quota/edit.c:145 #, c-format msgid "%s: cannot set limits: %s\n" msgstr "%s: nie można ustawić limitów: %s\n" #: .././quota/edit.c:166 .././quota/edit.c:569 #, c-format msgid "%s: invalid user name: %s\n" msgstr "%s: nieprawidłowa nazwa użytkownika: %s\n" #: .././quota/edit.c:189 .././quota/edit.c:586 #, c-format msgid "%s: invalid group name: %s\n" msgstr "%s: nieprawidłowa nazwa grupy: %s\n" #: .././quota/edit.c:212 .././quota/edit.c:603 #, c-format msgid "%s: invalid project name: %s\n" msgstr "%s: nieprawidłowa nazwa projektu: %s\n" #: .././quota/edit.c:237 #, c-format msgid "%s: Error: could not parse size %s.\n" msgstr "%s: Błąd: nie udało się przeanalizować rozmiaru %s.\n" #: .././quota/edit.c:243 #, c-format msgid "%s: Warning: `%s' in quota blocks is 0 (unlimited).\n" msgstr "%s: Uwaga: `%s' w blokach limitów wynosi 0 (bez ograniczeń).\n" #: .././quota/edit.c:332 #, c-format msgid "%s: unrecognised argument %s\n" msgstr "%s: nierozpoznany argument %s\n" #: .././quota/edit.c:339 #, c-format msgid "%s: cannot find any valid arguments\n" msgstr "%s: nie można znaleźć żadnych poprawnych argumentów\n" #: .././quota/edit.c:447 #, c-format msgid "%s: fopen on %s failed: %s\n" msgstr "%s: fopen na %s nie powiodło się: %s\n" #: .././quota/edit.c:479 #, c-format msgid "%s: cannot set timer: %s\n" msgstr "%s: nie można ustawić czasu: %s\n" #: .././quota/edit.c:553 #, c-format msgid "%s: cannot set warnings: %s\n" msgstr "%s: nie można ustawić ostrzeżeń: %s\n" #: .././quota/edit.c:689 msgid "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name" msgstr "[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|nazwa" #: .././quota/edit.c:690 msgid "modify quota limits" msgstr "zmiana limitów quot" #: .././quota/edit.c:698 msgid "restore quota limits from a backup file" msgstr "odtworzenie limitów quot z pliku kopii zapasowej" #: .././quota/edit.c:704 .././quota/edit.c:712 msgid "[-bir] [-gpu] value -d|id|name" msgstr "[-bir] [-gpu] wartość -d|id|nazwa" #: .././quota/edit.c:705 msgid "get/set quota enforcement timeouts" msgstr "pobranie/ustawienie czasu wymuszenia quot" #: .././quota/edit.c:713 msgid "get/set enforcement warning counter" msgstr "pobranie/ustawienie licznika ostrzeżeń" #: .././mkfs/proto.c:60 #, c-format msgid "%s: failed to open %s: %s\n" msgstr "%s: nie udało się otworzyć %s: %s\n" #: .././mkfs/proto.c:66 .././mkfs/proto.c:291 #, c-format msgid "%s: read failed on %s: %s\n" msgstr "%s: odczyt nie powiódł się dla %s: %s\n" #: .././mkfs/proto.c:71 #, c-format msgid "%s: proto file %s premature EOF\n" msgstr "%s: plik prototypu %s skończył się przedwcześnie\n" #: .././mkfs/proto.c:108 msgid "cannot reserve space" msgstr "nie można zarezerwować miejsca" #: .././mkfs/proto.c:161 #, c-format msgid "%s: premature EOF in prototype file\n" msgstr "%s: przedwczesny EOF w pliku prototypu\n" #: .././mkfs/proto.c:180 msgid "error reserving space for a file" msgstr "błąd podczas rezerwowania miejsca na plik" #: .././mkfs/proto.c:249 msgid "error allocating space for a file" msgstr "błąd podczas przydzielania miejsca na plik" #: .././mkfs/proto.c:253 #, c-format msgid "%s: cannot allocate space for file\n" msgstr "%s: nie można przydzielić miejsca na plik\n" #: .././mkfs/proto.c:316 msgid "directory createname error" msgstr "błąd tworzenia nazwy katalogu" #: .././mkfs/proto.c:330 msgid "directory create error" msgstr "błąd tworzenia katalogu" #: .././mkfs/proto.c:396 .././mkfs/proto.c:408 .././mkfs/proto.c:419 #: .././mkfs/proto.c:426 #, c-format msgid "%s: bad format string %s\n" msgstr "%s: błędny łańcuch formatujący %s\n" #: .././mkfs/proto.c:447 .././mkfs/proto.c:486 .././mkfs/proto.c:501 #: .././mkfs/proto.c:513 .././mkfs/proto.c:525 .././mkfs/proto.c:536 msgid "Inode allocation failed" msgstr "Przydzielanie i-węzła nie powiodło się" #: .././mkfs/proto.c:464 msgid "Inode pre-allocation failed" msgstr "Wczesne przydzielanie i-węzła nie powiodło się" #: .././mkfs/proto.c:474 msgid "Pre-allocated file creation failed" msgstr "Tworzenie wcześnie przydzielonego pliku nie powiodło się" #: .././mkfs/proto.c:556 msgid "Directory creation failed" msgstr "Tworzenie katalogu nie powiodło się" #: .././mkfs/proto.c:580 msgid "Error encountered creating file from prototype file" msgstr "Wystąpił błąd podczas tworzenia pliku z pliku prototypu" #: .././mkfs/proto.c:630 msgid "Realtime bitmap inode allocation failed" msgstr "Przydzielanie i-węzła bitmapy realtime nie powiodło się" #: .././mkfs/proto.c:648 msgid "Realtime summary inode allocation failed" msgstr "Tworzenie i-węzła opisu realtime nie powiodło się" #: .././mkfs/proto.c:675 msgid "Allocation of the realtime bitmap failed" msgstr "Przydzielenie bitmapy realtime nie powiodło się" #: .././mkfs/proto.c:688 msgid "Completion of the realtime bitmap failed" msgstr "Uzupełnienie bitmapy realtime nie powiodło się" #: .././mkfs/proto.c:712 msgid "Allocation of the realtime summary failed" msgstr "Przydzielenie opisu realtime nie powiodło się" #: .././mkfs/proto.c:724 msgid "Completion of the realtime summary failed" msgstr "Uzupełnienie opisu realtime nie powiodło się" #: .././mkfs/proto.c:741 msgid "Error initializing the realtime space" msgstr "Błąd podczas inicjalizacji przestrzeni realtime" #: .././mkfs/proto.c:746 msgid "Error completing the realtime space" msgstr "Błąd podczas uzupełniania przestrzeni realtime" #: .././mkfs/xfs_mkfs.c:220 #, c-format msgid "data su/sw must not be used in conjunction with data sunit/swidth\n" msgstr "su/sw danych nie można użyć w połączeniu z sunit/swidth danych\n" #: .././mkfs/xfs_mkfs.c:227 #, c-format msgid "both data sunit and data swidth options must be specified\n" msgstr "trzeba podać obie opcje sunit i swidth dla danych\n" #: .././mkfs/xfs_mkfs.c:236 #, c-format msgid "data sunit/swidth must not be used in conjunction with data su/sw\n" msgstr "sunit/swidth danych nie można użyć w połączeniu z su/sw danych\n" #: .././mkfs/xfs_mkfs.c:243 #, c-format msgid "both data su and data sw options must be specified\n" msgstr "trzeba podać obie opcje su i sw dla danych\n" #: .././mkfs/xfs_mkfs.c:250 #, c-format msgid "data su must be a multiple of the sector size (%d)\n" msgstr "su danych musi być wielokrotnością rozmiaru sektora (%d)\n" #: .././mkfs/xfs_mkfs.c:261 #, c-format msgid "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n" msgstr "szerokość pasa danych (%d) musi być wielokrotnością jednostki pasa danych (%d)\n" #: .././mkfs/xfs_mkfs.c:271 #, c-format msgid "log su should not be used in conjunction with log sunit\n" msgstr "su logu nie powinno być używane w połączeniu z sunit logu\n" #: .././mkfs/xfs_mkfs.c:280 #, c-format msgid "log sunit should not be used in conjunction with log su\n" msgstr "sunit logu nie powinno być używane w połączeniu z su logu\n" #: .././mkfs/xfs_mkfs.c:350 .././mkfs/xfs_mkfs.c:474 #, c-format msgid "%s: %s appears to contain an existing filesystem (%s).\n" msgstr "%s: %s zdaje się zawierać istniejący system plików (%s).\n" #: .././mkfs/xfs_mkfs.c:354 .././mkfs/xfs_mkfs.c:480 #, c-format msgid "%s: %s appears to contain a partition table (%s).\n" msgstr "%s: %s zdaje się zawierać tablicę partycji (%s).\n" #: .././mkfs/xfs_mkfs.c:358 #, c-format msgid "%s: %s appears to contain something weird according to blkid\n" msgstr "%s: %s zdaje się zawierać coś dziwnego wg blkid\n" #: .././mkfs/xfs_mkfs.c:368 #, c-format msgid "%s: probe of %s failed, cannot detect existing filesystem.\n" msgstr "%s: test %s nie powiódł się, nie można wykryć istniejącego systemu plików.\n" #: .././mkfs/xfs_mkfs.c:421 #, c-format msgid "warning: device is not properly aligned %s\n" msgstr "uwaga: urządzenie nie jest właściwie wyrównane: %s\n" #: .././mkfs/xfs_mkfs.c:426 #, c-format msgid "Use -f to force usage of a misaligned device\n" msgstr "Można użyć -f do wymuszenia użycia źle wyrównanego urządzenia\n" #: .././mkfs/xfs_mkfs.c:440 #, c-format msgid "warning: unable to probe device toplology for device %s\n" msgstr "uwaga: nie udało się odczytać topologii urządzenia %s\n" #: .././mkfs/xfs_mkfs.c:549 #, c-format msgid "log size %lld is not a multiple of the log stripe unit %d\n" msgstr "rozmiar logu %lld nie jest wielokrotnością jednostki pasa logu %d\n" #: .././mkfs/xfs_mkfs.c:577 #, c-format msgid "Due to stripe alignment, the internal log size (%lld) is too large.\n" msgstr "Ze względu na wyrównanie do rozmiaru pasa rozmiar wewnętrznego logu (%lld) jest zbyt duży.\n" #: .././mkfs/xfs_mkfs.c:579 #, c-format msgid "Must fit within an allocation group.\n" msgstr "Musi zmieścić się wewnątrz grupy alokacji.\n" #: .././mkfs/xfs_mkfs.c:590 #, c-format msgid "log size %lld blocks too small, minimum size is %d blocks\n" msgstr "rozmiar logu %lld bloków jest zbyt mały, minimalny rozmiar to %d bloków\n" #: .././mkfs/xfs_mkfs.c:596 #, c-format msgid "log size %lld blocks too large, maximum size is %lld blocks\n" msgstr "rozmiar logu %lld bloków jest zbyt duży, maksymalny rozmiar to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:602 #, c-format msgid "log size %lld bytes too large, maximum size is %lld bytes\n" msgstr "rozmiar logu %lld bajtów jest zbyt duży, maksymalny rozmiar to %lld bajtów\n" #: .././mkfs/xfs_mkfs.c:710 #, c-format msgid "agsize (%lldb) too small, need at least %lld blocks\n" msgstr "agsize (%lldb) zbyt małe, potrzeba co najmniej %lld bloków\n" #: .././mkfs/xfs_mkfs.c:718 #, c-format msgid "agsize (%lldb) too big, maximum is %lld blocks\n" msgstr "agsize (%lldb) zbyt duże, maksimum to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:726 #, c-format msgid "agsize (%lldb) too big, data area is %lld blocks\n" msgstr "agsize (%lldb) zbyt duże, obszar danych to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:733 #, c-format msgid "too many allocation groups for size = %lld\n" msgstr "zbyt dużo grup alokacji dla rozmiaru = %lld\n" #: .././mkfs/xfs_mkfs.c:735 #, c-format msgid "need at most %lld allocation groups\n" msgstr "potrzeba najwyżej %lld grup alokacji\n" #: .././mkfs/xfs_mkfs.c:743 #, c-format msgid "too few allocation groups for size = %lld\n" msgstr "zbyt mało grup alokacji dla rozmiaru = %lld\n" #: .././mkfs/xfs_mkfs.c:745 #, c-format msgid "need at least %lld allocation groups\n" msgstr "potrzeba co najmniej %lld grup alokacji\n" #: .././mkfs/xfs_mkfs.c:758 #, c-format msgid "last AG size %lld blocks too small, minimum size is %lld blocks\n" msgstr "rozmiar ostatniej AG %lld bloków zbyt mały, minimalny rozmiar to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:769 #, c-format msgid "%lld allocation groups is too many, maximum is %lld\n" msgstr "%lld grup alokacji to zbyt dużo, maksimum to %lld\n" #: .././mkfs/xfs_mkfs.c:793 #, c-format msgid "error reading existing superblock -- failed to memalign buffer\n" msgstr "błąd podczas odczytu istniejącego superbloku - nie udało się wykonać memalign dla bufora\n" #: .././mkfs/xfs_mkfs.c:799 #, c-format msgid "existing superblock read failed: %s\n" msgstr "odczyt istniejącego superbloku nie powiódł się: %s\n" #: .././mkfs/xfs_mkfs.c:1098 #, c-format msgid "%s: Specify data sunit in 512-byte blocks, no unit suffix\n" msgstr "%s: sunit danych należy podać w 512-bajtowych blokach, bez jednostki\n" #: .././mkfs/xfs_mkfs.c:1114 #, c-format msgid "%s: Specify data swidth in 512-byte blocks, no unit suffix\n" msgstr "%s: swidth danych należy podać w 512-bajtowych blokach, bez jednostki\n" #: .././mkfs/xfs_mkfs.c:1141 #, c-format msgid "%s: Specify data sw as multiple of su, no unit suffix\n" msgstr "%s: sw danych należy podać jako wielokrotność su, bez jednostki\n" #: .././mkfs/xfs_mkfs.c:1370 #, c-format msgid "Specify log sunit in 512-byte blocks, no size suffix\n" msgstr "sunit należy podać w 512-bajtowych blokach, bez jednostki\n" #: .././mkfs/xfs_mkfs.c:1630 #, c-format msgid "extra arguments\n" msgstr "nadmiarowe argumenty\n" #: .././mkfs/xfs_mkfs.c:1636 #, c-format msgid "cannot specify both %s and -d name=%s\n" msgstr "nie można podać jednocześnie %s i -d name=%s\n" #: .././mkfs/xfs_mkfs.c:1653 #, c-format msgid "illegal block size %d\n" msgstr "niedozwolony rozmiar bloku %d\n" #: .././mkfs/xfs_mkfs.c:1688 #, c-format msgid "specified blocksize %d is less than device physical sector size %d\n" msgstr "podany rozmiar bloku %d jest mniejszy niż rozmiar fizycznego sektora urządzenia (%d)\n" #: .././mkfs/xfs_mkfs.c:1691 #, c-format msgid "switching to logical sector size %d\n" msgstr "przełączono na rozmiar sektora logicznego %d\n" #: .././mkfs/xfs_mkfs.c:1709 #, c-format msgid "illegal sector size %d\n" msgstr "niedozwolony rozmiar sektora %d\n" #: .././mkfs/xfs_mkfs.c:1712 #, c-format msgid "block size %d cannot be smaller than logical sector size %d\n" msgstr "rozmiar bloku %d nie może być mniejszy niż rozmiar sektora logicznego %d\n" #: .././mkfs/xfs_mkfs.c:1717 #, c-format msgid "illegal sector size %d; hw sector is %d\n" msgstr "niedozwolony rozmiar sektora %d; sektor sprzętowy ma %d\n" #: .././mkfs/xfs_mkfs.c:1723 #, c-format msgid "illegal log sector size %d\n" msgstr "niedozwolony rozmiar sektora logu %d\n" #: .././mkfs/xfs_mkfs.c:1733 #, c-format msgid "illegal directory block size %d\n" msgstr "niedozwolony rozmiar bloku katalogu %d\n" #: .././mkfs/xfs_mkfs.c:1747 #, c-format msgid "both -d agcount= and agsize= specified, use one or the other\n" msgstr "podano jednocześnie -d agcount= i agsize=, można użyć tylko jednej z tych opcji\n" #: .././mkfs/xfs_mkfs.c:1753 #, c-format msgid "if -d file then -d name and -d size are required\n" msgstr "jeśli podano -d file, to -d name i -d size są wymagane\n" #: .././mkfs/xfs_mkfs.c:1762 #, c-format msgid "illegal data length %lld, not a multiple of %d\n" msgstr "niedozwolona długość danych %lld, nie jest wielokrotnością %d\n" #: .././mkfs/xfs_mkfs.c:1768 #, c-format msgid "warning: data length %lld not a multiple of %d, truncated to %lld\n" msgstr "uwaga: długość danych %lld nie jest wielokrotnością %d, ucięto do %lld\n" #: .././mkfs/xfs_mkfs.c:1782 #, c-format msgid "if -l file then -l name and -l size are required\n" msgstr "jeśli podano -l file to -l name i -l size są wymagane\n" #: .././mkfs/xfs_mkfs.c:1791 #, c-format msgid "illegal log length %lld, not a multiple of %d\n" msgstr "niedozwolona długość logu %lld, nie jest wielokrotnością %d\n" #: .././mkfs/xfs_mkfs.c:1798 #, c-format msgid "warning: log length %lld not a multiple of %d, truncated to %lld\n" msgstr "uwaga: długość logu %lld nie jest wielokrotnością %d, ucięto do %lld\n" #: .././mkfs/xfs_mkfs.c:1804 #, c-format msgid "if -r file then -r name and -r size are required\n" msgstr "jeśli podano -r file, to -r name i -r size są wymagane\n" #: .././mkfs/xfs_mkfs.c:1813 #, c-format msgid "illegal rt length %lld, not a multiple of %d\n" msgstr "niedozwolona długość rt %lld, nie jest wielokrotnością %d\n" #: .././mkfs/xfs_mkfs.c:1820 #, c-format msgid "warning: rt length %lld not a multiple of %d, truncated to %lld\n" msgstr "uwaga: długość rt %lld nie jest wielokrotnością %d, ucięto do %lld\n" #: .././mkfs/xfs_mkfs.c:1833 #, c-format msgid "illegal rt extent size %lld, not a multiple of %d\n" msgstr "niedozwolony rozmiar ekstentu rt %lld, nie jest wielokrotnością %d\n" #: .././mkfs/xfs_mkfs.c:1839 #, c-format msgid "rt extent size %s too large, maximum %d\n" msgstr "rozmiar ekstentu rt %s zbyt duży, maksimum to %d\n" #: .././mkfs/xfs_mkfs.c:1845 #, c-format msgid "rt extent size %s too small, minimum %d\n" msgstr "rozmiar ekstentu rt %s zbyt mały, minimum to %d\n" #: .././mkfs/xfs_mkfs.c:1890 #, c-format msgid "illegal inode size %d\n" msgstr "niedozwolony rozmiar i-węzła %d\n" #: .././mkfs/xfs_mkfs.c:1895 #, c-format msgid "allowable inode size with %d byte blocks is %d\n" msgstr "dozwolony rozmiar i-węzła przy blokach %d-bajtowych to %d\n" #: .././mkfs/xfs_mkfs.c:1899 #, c-format msgid "allowable inode size with %d byte blocks is between %d and %d\n" msgstr "dozwolone rozmiary i-węzła przy blokach %d-bajtowych są od %d do %d\n" #: .././mkfs/xfs_mkfs.c:1907 #, c-format msgid "log stripe unit specified, using v2 logs\n" msgstr "podano jednostkę pasa logu, użyto logów v2\n" #: .././mkfs/xfs_mkfs.c:1922 #, c-format msgid "no device name given in argument list\n" msgstr "nie podano nazwy urządzenia w liście argumentów\n" #: .././mkfs/xfs_mkfs.c:1947 #, c-format msgid "%s: Use the -f option to force overwrite.\n" msgstr "%s: Można użyć opcji -f do wymuszenia nadpisania.\n" #: .././mkfs/xfs_mkfs.c:1966 msgid "internal log" msgstr "log wewnętrzny" #: .././mkfs/xfs_mkfs.c:1968 msgid "volume log" msgstr "log na wolumenie" #: .././mkfs/xfs_mkfs.c:1970 #, c-format msgid "no log subvolume or internal log\n" msgstr "brak podwolumenu logu ani logu wewnętrznego\n" #: .././mkfs/xfs_mkfs.c:1977 msgid "volume rt" msgstr "wolumen rt" #: .././mkfs/xfs_mkfs.c:1979 .././logprint/log_misc.c:152 #: .././growfs/xfs_growfs.c:86 .././db/io.c:157 #, c-format msgid "none" msgstr "brak" #: .././mkfs/xfs_mkfs.c:1982 #, c-format msgid "size %s specified for data subvolume is too large, maximum is %lld blocks\n" msgstr "rozmiar %s podany dla podwolumenu danych jest zbyt duży, maksimum to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:1989 #, c-format msgid "can't get size of data subvolume\n" msgstr "nie można pobrać rozmiaru podwolumenu danych\n" #: .././mkfs/xfs_mkfs.c:1994 #, c-format msgid "size %lld of data subvolume is too small, minimum %d blocks\n" msgstr "rozmiar %lld dla podwolumenu danych jest zbyt mały, minimum to %d bloków\n" #: .././mkfs/xfs_mkfs.c:2001 #, c-format msgid "can't have both external and internal logs\n" msgstr "nie można mieć jednocześnie zewnętrznego i wewnętrznego logu\n" #: .././mkfs/xfs_mkfs.c:2005 #, c-format msgid "data and log sector sizes must be equal for internal logs\n" msgstr "rozmiary sektora danych i logu muszą być równe dla logów wewnętrznych\n" #: .././mkfs/xfs_mkfs.c:2011 #, c-format msgid "" "Warning: the data subvolume sector size %u is less than the sector size \n" "reported by the device (%u).\n" msgstr "" "Uwaga: rozmiar sektora podwolumenu danych %u jest mniejszy od rozmiaru\n" "sektora zgłaszanego przez urządzenie (%u).\n" #: .././mkfs/xfs_mkfs.c:2017 #, c-format msgid "" "Warning: the log subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" "Uwaga: rozmiar sektora podwolumenu logu %u jest mniejszy od rozmiaru\n" "sektora zgłaszanego przez urządzenie (%u).\n" #: .././mkfs/xfs_mkfs.c:2023 #, c-format msgid "" "Warning: the realtime subvolume sector size %u is less than the sector size\n" "reported by the device (%u).\n" msgstr "" "Uwaga: rozmiar sektora podwolumenu realtime %u jest mniejszy od rozmiaru\n" "sektora zgłaszanego przez urządzenie (%u).\n" #: .././mkfs/xfs_mkfs.c:2037 #, c-format msgid "size %s specified for log subvolume is too large, maximum is %lld blocks\n" msgstr "rozmiar %s podany dla podwolumenu logu jest zbyt duży, maksimum to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:2044 #, c-format msgid "size specified for non-existent log subvolume\n" msgstr "podano rozmiar dla nie istniejącego podwolumenu logu\n" #: .././mkfs/xfs_mkfs.c:2047 #, c-format msgid "size %lld too large for internal log\n" msgstr "rozmiar %lld jest zbyt duży dla logu wewnętrznego\n" #: .././mkfs/xfs_mkfs.c:2074 #, c-format msgid "size %s specified for rt subvolume is too large, maximum is %lld blocks\n" msgstr "rozmiar %s podany dla podwolumenu rt jest zbyt duży, maksimum to %lld bloków\n" #: .././mkfs/xfs_mkfs.c:2082 #, c-format msgid "size specified for non-existent rt subvolume\n" msgstr "podano rozmiar dla nie istniejącego podwolumenu rt\n" #: .././mkfs/xfs_mkfs.c:2099 #, c-format msgid "agsize (%lld) not a multiple of fs blk size (%d)\n" msgstr "agsize (%lld) nie jest wielokrotnością rozmiaru bloku systemu plików (%d)\n" #: .././mkfs/xfs_mkfs.c:2116 #, c-format msgid "%s: Specified data stripe unit %d is not the same as the volume stripe unit %d\n" msgstr "%s: Podana jednostka pasa danych %d nie jest taka sama jak jednostka pasa wolumenu %d\n" #: .././mkfs/xfs_mkfs.c:2123 #, c-format msgid "%s: Specified data stripe width %d is not the same as the volume stripe width %d\n" msgstr "%s: Podana szerokość pasa danych %d nie jest taka sama jak szerokość pasa wolumenu %d\n" #: .././mkfs/xfs_mkfs.c:2171 #, c-format msgid "agsize rounded to %lld, swidth = %d\n" msgstr "agsize zaokrąglone do %lld, swidth = %d\n" #: .././mkfs/xfs_mkfs.c:2178 #, c-format msgid "Allocation group size (%lld) is not a multiple of the stripe unit (%d)\n" msgstr "Rozmiar grupy alokacji (%lld) nie jest wielokrotnością jednostki pasa (%d)\n" #: .././mkfs/xfs_mkfs.c:2200 #, c-format msgid "" "Warning: AG size is a multiple of stripe width. This can cause performance\n" "problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n" "an AG size that is one stripe unit smaller, for example %llu.\n" msgstr "" "Uwaga: rozmiar AG jest wielokrotnością szerokości pasa. Może to spowodować\n" "problemy z wydajnością poprzez wyrównanie wszystkich AG na tym samym dysku.\n" "Aby temu zapobiec, należy uruchomić mkfs z rozmiarem AG o jedną jednostkę\n" "pasa mniejszym, na przykład %llu.\n" #: .././mkfs/xfs_mkfs.c:2225 #, c-format msgid "%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n" msgstr "%s: Jednostka pasa (%d) lub szerokość pasa (%d) nie jest wielokrotnością rozmiaru bloku (%d)\n" #: .././mkfs/xfs_mkfs.c:2257 #, c-format msgid "log stripe unit (%d) must be a multiple of the block size (%d)\n" msgstr "jednostka pasa logu (%d) musi być wielokrotnością rozmiaru bloku (%d)\n" #: .././mkfs/xfs_mkfs.c:2270 #, c-format msgid "log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" msgstr "jednostka pasa logu (%d bajtów) jest zbyt duża (maksimum to 256KiB)\n" #: .././mkfs/xfs_mkfs.c:2273 #, c-format msgid "log stripe unit adjusted to 32KiB\n" msgstr "jednostka pasa logu zmodyfikowana na 32KiB\n" #: .././mkfs/xfs_mkfs.c:2298 #, c-format msgid "internal log size %lld too large, must fit in allocation group\n" msgstr "rozmiar wewnętrznego logu %lld zbyt duży, musi się zmieścić w grupie alokacji\n" #: .././mkfs/xfs_mkfs.c:2305 #, c-format msgid "log ag number %d too large, must be less than %lld\n" msgstr "liczba ag logu %d zbyt duża, musi być mniejsza niż %lld\n" #: .././mkfs/xfs_mkfs.c:2335 #, c-format msgid "" "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" msgstr "" "metadane=%-22s isize=%-6d agcount=%lld, agsize=%lld bloków\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" "dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u bloków\n" "nazwy =wersja %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6d blocks=%lld, wersja=%d\n" " =%-22s sectsz=%-5u sunit=%d bloków, lazy-count=%d\n" "realtime=%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n" #: .././mkfs/xfs_mkfs.c:2451 #, c-format msgid "%s: Growing the data section failed\n" msgstr "%s: Powiększenie sekcji danych nie powiodło się\n" #: .././mkfs/xfs_mkfs.c:2481 #, c-format msgid "%s: filesystem failed to initialize\n" msgstr "%s: nie udało się zainicjować systemu plików\n" #: .././mkfs/xfs_mkfs.c:2693 #, c-format msgid "%s: root inode created in AG %u, not AG 0\n" msgstr "%s: główny i-węzeł utworzony w AG %u, nie AG 0\n" #: .././mkfs/xfs_mkfs.c:2760 #, c-format msgid "Cannot specify both -%c %s and -%c %s\n" msgstr "Nie można podać jednocześnie -%c %s i %c %s\n" #: .././mkfs/xfs_mkfs.c:2771 #, c-format msgid "Illegal value %s for -%s option\n" msgstr "Niedozwolona wartość %s dla opcji -%s\n" #: .././mkfs/xfs_mkfs.c:2788 #, c-format msgid "-%c %s option requires a value\n" msgstr "Opcja -%c %s wymaga wartości\n" #: .././mkfs/xfs_mkfs.c:2849 #, c-format msgid "blocksize not available yet.\n" msgstr "rozmiar bloku jeszcze nie dostępny.\n" #: .././mkfs/xfs_mkfs.c:2875 #, c-format msgid "" "Usage: %s\n" "/* blocksize */\t\t[-b log=n|size=num]\n" "/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n" "\t\t\t (sunit=value,swidth=value|su=num,sw=num),\n" "\t\t\t sectlog=n|sectsize=num\n" "/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n" "\t\t\t projid32bit=0|1]\n" "/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n" "\t\t\t sunit=value|su=num,sectlog=n|sectsize=num,\n" "\t\t\t lazy-count=0|1]\n" "/* label */\t\t[-L label (maximum 12 characters)]\n" "/* naming */\t\t[-n log=n|size=num,version=2|ci]\n" "/* prototype file */\t[-p fname]\n" "/* quiet */\t\t[-q]\n" "/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n" "/* sectorsize */\t[-s log=n|size=num]\n" "/* version */\t\t[-V]\n" "\t\t\tdevicename\n" " is required unless -d name=xxx is given.\n" " is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n" " xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n" " is xxx (512 byte blocks).\n" msgstr "" "Składnia: %s\n" "/* rozmiar bloku */ [-b log=n|size=liczba]\n" "/* podwolumen danych */ [-d agcount=n,agsize=n,file,name=xxx,size=liczba,\n" " (sunit=wartość,swidth=wartość|su=liczba,sw=liczba),\n" " sectlog=n|sectsize=liczba]\n" "/* rozmiar i-węzła */ [-i log=n|perblock=n|size=liczba,maxpct=n,attr=0|1|2,\n" " projid32bit=0|1]\n" "/* podwolumen logu */ [-l agnum=n,internal,size=liczba,logdev=xxx,version=n\n" " sunit=wartość|su=liczba,sectlog=n|sectsize=liczba,\n" " lazy-count=0|1]\n" "/* etykieta */ [-L etykieta (maksymalnie 12 znaków)]\n" "/* nazwy */ [-n log=n|size=liczba,wersja=2|ci]\n" "/* plik prototypu */ [-p nazwa_pliku]\n" "/* cisza */ [-q]\n" "/* podwolumen rt */ [-r extsize=liczba,size=liczba,rtdev=xxx]\n" "/* rozmiar sektora */ [-s log=n|size=liczba]\n" "/* wersja */ [-V]\n" " nazwa_urządzenia\n" " jest wymagana, chyba że podano -d name=xxx.\n" " to xxx (bajtów), xxxs (sektorów), xxxb (bloków systemu plików),\n" " xxxk (xxx KiB), xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB),\n" " xxxp (xxx PiB).\n" " to xxx (512-bajtowych bloków).\n" #: .././logprint/log_copy.c:44 .././logprint/log_dump.c:43 #, c-format msgid "%s: read error (%lld): %s\n" msgstr "%s: błąd odczytu (%lld): %s\n" #: .././logprint/log_copy.c:49 .././logprint/log_dump.c:48 #, c-format msgid "%s: physical end of log at %lld\n" msgstr "%s: fizyczny koniec logu na %lld\n" #: .././logprint/log_copy.c:53 #, c-format msgid "%s: short read? (%lld)\n" msgstr "%s: skrócony odczyt? (%lld)\n" #: .././logprint/log_copy.c:60 #, c-format msgid "%s: write error (%lld): %s\n" msgstr "%s: błąd zapisu (%lld): %s\n" #: .././logprint/log_copy.c:65 #, c-format msgid "%s: short write? (%lld)\n" msgstr "%s: skrócony zapis? (%lld)\n" #: .././logprint/log_dump.c:56 #, c-format msgid "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n" msgstr "%6lld NAGŁÓWEK Cykl %d koniec %d:%06d len %6d ops %d\n" #: .././logprint/log_dump.c:67 #, c-format msgid "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n" msgstr "[%05lld - %05lld] Cykl 0x%08x Nowy cykl 0x%08x\n" #: .././logprint/logprint.c:42 #, c-format msgid "" "Usage: %s [options...] \n" "\n" "Options:\n" " -c\t try to continue if error found in log\n" " -C copy the log from the filesystem to filename\n" " -d\t dump the log in log-record format\n" " -f\t specified device is actually a file\n" " -l filename of external log\n" " -n\t don't try and interpret log data\n" " -o\t print buffer data in hex\n" " -s block # to start printing\n" " -v print \"overwrite\" data\n" " -t\t print out transactional view\n" "\t-b in transactional view, extract buffer info\n" "\t-i in transactional view, extract inode info\n" "\t-q in transactional view, extract quota info\n" " -D print only data; no decoding\n" " -V print version information\n" msgstr "" "Składnia: %s [opcje...] \n" "\n" "Opcje:\n" " -c próba kontynuacji w przypadku błędu w logu\n" " -C skopiowanie logu z systemu plików do pliku o podanej nazwie\n" " -d zrzut logu w formacie jego rekordów\n" " -f podane urządzenie jest plikiem\n" " -l nazwa pliku z logiem zewnętrznym\n" " -n bez prób interpretacji danych logu\n" " -o wypisanie danych bufora szesnastkowo\n" " -s numer pierwszego bloku do wypisania\n" " -v wypisanie danych \"overwrite\"\n" " -t wypisywanie w widoku transakcyjnym\n" " -b w wid.transakcyjnym: wypisywanie informacji o buforze\n" " -i w wid.transakcyjnym: wypisywanie informacji o i-węzłach\n" " -q w wid.transakcyjnym: wypisywanie informacji o limitach\n" " -D wypisywanie tylko danych, bez dekodowania\n" " -V wypisanie informacji o wersji\n" #: .././logprint/logprint.c:75 #, c-format msgid " Can't open device %s: %s\n" msgstr " Nie można otworzyć urządzenia %s: %s\n" #: .././logprint/logprint.c:81 #, c-format msgid " read of XFS superblock failed\n" msgstr " odczyt superbloku XFS-a nie powiódł się\n" #: .././logprint/logprint.c:97 #, c-format msgid "" " external log device not specified\n" "\n" msgstr "" " Nie podano urządzenia zewnętrznego loga\n" "\n" #: .././logprint/logprint.c:112 #, c-format msgid "Can't open file %s: %s\n" msgstr "Nie można otworzyć pliku %s: %s\n" #: .././logprint/logprint.c:212 #, c-format msgid "xfs_logprint:\n" msgstr "xfs_logprint:\n" #: .././logprint/logprint.c:220 #, c-format msgid " data device: 0x%llx\n" msgstr " urządzenie danych: 0x%llx\n" #: .././logprint/logprint.c:223 #, c-format msgid " log file: \"%s\" " msgstr " plik logu: \"%s\" " #: .././logprint/logprint.c:225 #, c-format msgid " log device: 0x%llx " msgstr " urządzenie logu: 0x%llx " #: .././logprint/logprint.c:228 #, c-format msgid "" "daddr: %lld length: %lld\n" "\n" msgstr "" "daddr: %lld długość: %lld\n" "\n" #: .././logprint/log_misc.c:132 #, c-format msgid "Oper (%d): tid: %x len: %d clientid: %s " msgstr "Operacja (%d): tid: %x len: %d clientid: %s " #: .././logprint/log_misc.c:137 #, c-format msgid "flags: " msgstr "flagi: " #: .././logprint/log_misc.c:231 #, c-format msgid " Not enough data to decode further\n" msgstr " Za mało danych do dalszego dekodowania\n" #: .././logprint/log_misc.c:235 #, c-format msgid " type: %s tid: %x num_items: %d\n" msgstr " typ: %s tid: %x num_items: %d\n" #: .././logprint/log_misc.c:277 #, c-format msgid "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" msgstr "#regs: %d start blkno: %lld (0x%llx) len: %d bmap size: %d flags: 0x%x\n" #: .././logprint/log_misc.c:283 #, c-format msgid "#regs: %d Not printing rest of data\n" msgstr "#regs: %d Bez wypisywania reszty danych\n" #: .././logprint/log_misc.c:300 #, c-format msgid "SUPER BLOCK Buffer: " msgstr "Bufor SUPER BLOKU: " #: .././logprint/log_misc.c:302 .././logprint/log_misc.c:366 #: .././logprint/log_misc.c:392 #, c-format msgid "Out of space\n" msgstr "Brak miejsca na dysku\n" #: .././logprint/log_misc.c:310 #, c-format msgid "icount: %llu ifree: %llu " msgstr "icount: %llu ifree: %llu " #: .././logprint/log_misc.c:315 #, c-format msgid "fdblks: %llu frext: %llu\n" msgstr "fdblks: %llu frext: %llu\n" #: .././logprint/log_misc.c:322 #, c-format msgid "AGI Buffer: XAGI " msgstr "Bufor AGI: XAGI " #: .././logprint/log_misc.c:325 #, c-format msgid "out of space\n" msgstr "brak miejsca na dysku\n" #: .././logprint/log_misc.c:328 #, c-format msgid "ver: %d " msgstr "wersja: %d " #: .././logprint/log_misc.c:330 #, c-format msgid "seq#: %d len: %d cnt: %d root: %d\n" msgstr "seq#: %d len: %d cnt: %d root: %d\n" #: .././logprint/log_misc.c:335 #, c-format msgid "level: %d free#: 0x%x newino: 0x%x\n" msgstr "level: %d free#: 0x%x newino: 0x%x\n" #: .././logprint/log_misc.c:345 #, c-format msgid "AGI unlinked data skipped " msgstr "Pominięto niedowiązane dane AGI " #: .././logprint/log_misc.c:346 #, c-format msgid "(CONTINUE set, no space)\n" msgstr "(KONTYNUACJA, brak miejsca)\n" #: .././logprint/log_misc.c:352 #, c-format msgid "bucket[%d - %d]: " msgstr "kubełek[%d - %d]: " #: .././logprint/log_misc.c:364 #, c-format msgid "AGF Buffer: XAGF " msgstr "Bufor AGF: XAGF " #: .././logprint/log_misc.c:369 #, c-format msgid "ver: %d seq#: %d len: %d \n" msgstr "ver: %d seq#: %d len: %d \n" #: .././logprint/log_misc.c:373 #, c-format msgid "root BNO: %d CNT: %d\n" msgstr "root BNO: %d CNT: %d\n" #: .././logprint/log_misc.c:376 #, c-format msgid "level BNO: %d CNT: %d\n" msgstr "level BNO: %d CNT: %d\n" #: .././logprint/log_misc.c:379 #, c-format msgid "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" msgstr "1st: %d last: %d cnt: %d freeblks: %d longest: %d\n" #: .././logprint/log_misc.c:389 #, c-format msgid "DQUOT Buffer: DQ " msgstr "Bufor DQUOT: DQ " #: .././logprint/log_misc.c:396 #, c-format msgid "ver: %d flags: 0x%x id: %d \n" msgstr "ver: %d flags: 0x%x id: %d \n" #: .././logprint/log_misc.c:399 #, c-format msgid "blk limits hard: %llu soft: %llu\n" msgstr "blk limits hard: %llu soft: %llu\n" #: .././logprint/log_misc.c:404 #, c-format msgid "blk count: %llu warns: %d timer: %d\n" msgstr "blk count: %llu warns: %d timer: %d\n" #: .././logprint/log_misc.c:408 #, c-format msgid "ino limits hard: %llu soft: %llu\n" msgstr "ino limits hard: %llu soft: %llu\n" #: .././logprint/log_misc.c:413 #, c-format msgid "ino count: %llu warns: %d timer: %d\n" msgstr "ino count: %llu warns: %d timer: %d\n" #: .././logprint/log_misc.c:419 #, c-format msgid "BUF DATA\n" msgstr "DANE BUFORA\n" #: .././logprint/log_misc.c:461 #, c-format msgid "EFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "EFD: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_misc.c:468 #, c-format msgid "EFD: Not enough data to decode further\n" msgstr "EFD: Za mało danych do dalszego dekodowania\n" #: .././logprint/log_misc.c:488 .././logprint/log_misc.c:497 #, c-format msgid "%s: xlog_print_trans_efi: malloc failed\n" msgstr "%s: xlog_print_trans_efi: malloc nie powiodło się\n" #: .././logprint/log_misc.c:505 #, c-format msgid "EFI: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "EFI: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_misc.c:532 #, c-format msgid "QOFF: #regs: %d flags: 0x%x\n" msgstr "QOFF: #regs: %d flags: 0x%x\n" #: .././logprint/log_misc.c:535 #, c-format msgid "QOFF: Not enough data to decode further\n" msgstr "QOFF: Za mało danych do dalszego dekodowania\n" #: .././logprint/log_misc.c:544 #, c-format msgid "INODE CORE\n" msgstr "RDZEŃ I-WĘZŁA\n" #: .././logprint/log_misc.c:545 #, c-format msgid "magic 0x%hx mode 0%ho version %d format %d\n" msgstr "magic 0x%hx mode 0%ho version %d format %d\n" #: .././logprint/log_misc.c:548 #, c-format msgid "nlink %hd uid %d gid %d\n" msgstr "nlink %hd uid %d gid %d\n" #: .././logprint/log_misc.c:550 #, c-format msgid "atime 0x%x mtime 0x%x ctime 0x%x\n" msgstr "atime 0x%x mtime 0x%x ctime 0x%x\n" #: .././logprint/log_misc.c:552 #, c-format msgid "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" msgstr "size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n" #: .././logprint/log_misc.c:555 #, c-format msgid "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" msgstr "naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n" #: .././logprint/log_misc.c:558 #, c-format msgid "flags 0x%x gen 0x%x\n" msgstr "flags 0x%x gen 0x%x\n" #: .././logprint/log_misc.c:574 #, c-format msgid "SHORTFORM DIRECTORY size %d\n" msgstr "Rozmiar KATALOGU W POSTACI KRÓTKIEJ %d\n" #: .././logprint/log_misc.c:580 #, c-format msgid "SHORTFORM DIRECTORY size %d count %d\n" msgstr "KATALOG W POSTACI KRÓTKIEJ: rozmiar %d liczba %d\n" #: .././logprint/log_misc.c:583 #, c-format msgid ".. ino 0x%llx\n" msgstr ".. ino 0x%llx\n" #: .././logprint/log_misc.c:591 #, c-format msgid "%s ino 0x%llx namelen %d\n" msgstr "%s ino 0x%llx namelen %d\n" #: .././logprint/log_misc.c:623 #, c-format msgid "INODE: " msgstr "I-WĘZEŁ: " #: .././logprint/log_misc.c:624 #, c-format msgid "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" msgstr "#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n" #: .././logprint/log_misc.c:627 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr " blkno: %lld len: %d boff: %d\n" #: .././logprint/log_misc.c:632 #, c-format msgid "INODE: #regs: %d Not printing rest of data\n" msgstr "I-WĘZEŁ: #regs: %d Bez wypisywania reszty danych\n" #: .././logprint/log_misc.c:665 #, c-format msgid "EXTENTS inode data\n" msgstr "EKSTENTY danych i-węzła\n" #: .././logprint/log_misc.c:676 #, c-format msgid "BTREE inode data\n" msgstr "B-DRZEWO danych i-węzła\n" #: .././logprint/log_misc.c:687 #, c-format msgid "LOCAL inode data\n" msgstr "LOKALNE dane i-węzła\n" #: .././logprint/log_misc.c:701 #, c-format msgid "EXTENTS inode attr\n" msgstr "EKSTENTY atrybutów i-węzła\n" #: .././logprint/log_misc.c:712 #, c-format msgid "BTREE inode attr\n" msgstr "B-DRZEWO atrybutów i-węzła\n" #: .././logprint/log_misc.c:723 #, c-format msgid "LOCAL inode attr\n" msgstr "LOKALNE atrybuty i-węzła\n" #: .././logprint/log_misc.c:735 #, c-format msgid "DEV inode: no extra region\n" msgstr "I-węzeł DEV: brak dodatkowego regionu\n" #: .././logprint/log_misc.c:740 #, c-format msgid "UUID inode: no extra region\n" msgstr "I-węzeł UUID: brak dodatkowego regionu\n" #: .././logprint/log_misc.c:748 msgid "xlog_print_trans_inode: illegal inode type" msgstr "xlog_print_trans_inode: niedozwolony typ i-węzła" #: .././logprint/log_misc.c:776 #, c-format msgid "#regs: %d id: 0x%x" msgstr "#regs: %d id: 0x%x" #: .././logprint/log_misc.c:777 #, c-format msgid " blkno: %lld len: %d boff: %d\n" msgstr " blkno: %lld len: %d boff: %d\n" #: .././logprint/log_misc.c:781 #, c-format msgid "DQUOT: #regs: %d Not printing rest of data\n" msgstr "DQUOT: #regs: %d Bez wypisywania reszty danych\n" #: .././logprint/log_misc.c:800 #, c-format msgid "DQUOT: magic 0x%hx flags 0%ho\n" msgstr "DQUOT: magic 0x%hx flags 0%ho\n" #: .././logprint/log_misc.c:828 #, c-format msgid "%s: lseek64 to %lld failed: %s\n" msgstr "%s: lseek64 na %lld nie powiodło się: %s\n" #: .././logprint/log_misc.c:871 #, c-format msgid "%s: xlog_print_record: malloc failed\n" msgstr "%s: xlog_print_record: malloc nie powiodło się\n" #: .././logprint/log_misc.c:880 #, c-format msgid "%s: xlog_print_record: read error\n" msgstr "%s: xlog_print_record: błąd odczytu\n" #: .././logprint/log_misc.c:967 #, c-format msgid "Left over region from split log item\n" msgstr "Region pozostały z podziału elementu logu\n" #: .././logprint/log_misc.c:1011 #, c-format msgid "Unmount filesystem\n" msgstr "Niezamontowany system plików\n" #: .././logprint/log_misc.c:1016 #, c-format msgid "%s: unknown log operation type (%x)\n" msgstr "%s: nieznany typ operacji w logu (%x)\n" #: .././logprint/log_misc.c:1051 #, c-format msgid "Header 0x%x wanted 0x%x\n" msgstr "Nagłówek 0x%x, pożądany 0x%x\n" #: .././logprint/log_misc.c:1065 #, c-format msgid "cycle: %d\tversion: %d\t" msgstr "cykl: %d\twersja: %d\t" #: .././logprint/log_misc.c:1071 #, c-format msgid "length of Log Record: %d\tprev offset: %d\t\tnum ops: %d\n" msgstr "długość rekordu logu: %d\tpoprz.offset: %d\t\tl.oper.: %d\n" #: .././logprint/log_misc.c:1077 .././logprint/log_misc.c:1119 #, c-format msgid "cycle num overwrites: " msgstr "liczba nadpisań cyklu: " #: .././logprint/log_misc.c:1086 #, c-format msgid "uuid: %s format: " msgstr "uuid: %s format: " #: .././logprint/log_misc.c:1089 #, c-format msgid "unknown\n" msgstr "nieznany\n" #: .././logprint/log_misc.c:1092 #, c-format msgid "little endian linux\n" msgstr "Linux little endian\n" #: .././logprint/log_misc.c:1095 #, c-format msgid "big endian linux\n" msgstr "Linux big endian\n" #: .././logprint/log_misc.c:1098 #, c-format msgid "big endian irix\n" msgstr "IRIX big endian\n" #: .././logprint/log_misc.c:1104 #, c-format msgid "h_size: %d\n" msgstr "h_size: %d\n" #: .././logprint/log_misc.c:1116 #, c-format msgid "extended-header: cycle: %d\n" msgstr "nagłówek-rozszerzony: cykl: %d\n" #: .././logprint/log_misc.c:1132 #, c-format msgid "* ERROR: found data after zeroed blocks block=%-21lld *\n" msgstr "* BŁĄD: znaleziono dane za wyzerowanymi blokami blok=%-21lld *\n" #: .././logprint/log_misc.c:1143 #, c-format msgid "* ERROR: header cycle=%-11d block=%-21lld *\n" msgstr "* BŁĄD: nagłówek cykl=%-11d blok=%-21lld *\n" #: .././logprint/log_misc.c:1154 #, c-format msgid "* ERROR: data block=%-21lld *\n" msgstr "* BŁĄD: blok danych=%-21lld *\n" #: .././logprint/log_misc.c:1165 #, c-format msgid "" "* ERROR: for header block=%lld\n" "* not enough hdrs for data length, required num = %d, hdr num = %d\n" msgstr "" "* BŁĄD: dla bloku nagłówka %lld\n" "* za mało nagłówków dla długości danych, wymaganych = %d, liczba = %d\n" #: .././logprint/log_misc.c:1171 msgid "Not enough headers for data length." msgstr "Za mało nagłówków dla długości danych." #: .././logprint/log_misc.c:1181 #, c-format msgid "%s: xlog_print: malloc failed for ext hdrs\n" msgstr "%s: xlog_print: malloc dla rozszerzonych nagłówków nie powiódł się\n" #: .././logprint/log_misc.c:1227 .././logprint/log_misc.c:1302 #: .././logprint/log_misc.c:1368 .././logprint/log_misc.c:1405 #, c-format msgid "%s: physical end of log\n" msgstr "%s: fizyczny koniec logu\n" #: .././logprint/log_misc.c:1233 .././logprint/log_misc.c:1307 #: .././logprint/log_misc.c:1420 #, c-format msgid "BLKNO: %lld\n" msgstr "BLKNO: %lld\n" #: .././logprint/log_misc.c:1290 #, c-format msgid "%s: problem finding oldest LR\n" msgstr "%s: problem ze znalezieniem najstarszego rekordu logu\n" #: .././logprint/log_misc.c:1316 #, c-format msgid "%s: after %d zeroed blocks\n" msgstr "%s: po %d wyzerowanych blokach\n" #: .././logprint/log_misc.c:1380 msgid "illegal value" msgstr "niedozwolona wartość" #: .././logprint/log_misc.c:1386 #, c-format msgid "%s: skipped %d cleared blocks in range: %lld - %lld\n" msgstr "%s: pominięto %d wyzerowanych bloków w przedziale: %lld - %lld\n" #: .././logprint/log_misc.c:1391 #, c-format msgid "%s: totally cleared log\n" msgstr "%s: całkowicie wyczyszczony log\n" #: .././logprint/log_misc.c:1396 #, c-format msgid "%s: skipped %d zeroed blocks in range: %lld - %lld\n" msgstr "%s: pominięto %d wyzerowanych bloków w przedziale %lld - %lld\n" #: .././logprint/log_misc.c:1401 #, c-format msgid "%s: totally zeroed log\n" msgstr "%s: całkowicie wyzerowany log\n" #: .././logprint/log_misc.c:1417 msgid "xlog_find_head: bad read" msgstr "xlog_find_head: błędny odczyt" #: .././logprint/log_misc.c:1473 #, c-format msgid "%s: logical end of log\n" msgstr "%s: logiczny koniec logu\n" #: .././logprint/log_misc.c:1565 #, c-format msgid "%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n" msgstr "%s: błędny rozmiar formatu efi: %u; oczekiwano %u lub %u; nextents = %u\n" #: .././logprint/log_print_trans.c:25 #, c-format msgid "TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n" msgstr "TRANS: tid:0x%x typ:%s #elem:%d trans:0x%x q:0x%lx\n" #: .././logprint/log_print_trans.c:51 #, c-format msgid "%s: failed to find head and tail, error: %d\n" msgstr "%s: nie udało się odnaleźć początku ani końca, błąd: %d\n" #: .././logprint/log_print_trans.c:56 #, c-format msgid " log tail: %lld head: %lld state: %s\n" msgstr " koniec logu: %lld początek: %lld stan: %s\n" #: .././logprint/log_print_trans.c:62 #, c-format msgid " override tail: %d\n" msgstr " koniec override: %d\n" #: .././logprint/log_print_trans.c:72 #, c-format msgid "%s: failed in xfs_do_recovery_pass, error: %d\n" msgstr "%s: xfs_do_recovery_pass nie powiodło się, błąd: %d\n" #: .././logprint/log_print_all.c:98 #, c-format msgid "BUF: #regs:%d start blkno:0x%llx len:%d bmap size:%d flags:0x%x\n" msgstr "BUF: #regs:%d blok pocz.:0x%llx dług.:%d rozm.bmapy:%d flagi:0x%x\n" #: .././logprint/log_print_all.c:108 #, c-format msgid "\tSUPER Block Buffer:\n" msgstr "\tBufor SUPER bloku:\n" #: .././logprint/log_print_all.c:111 #, c-format msgid " icount:%llu ifree:%llu " msgstr " icount:%llu ifree:%llu " #: .././logprint/log_print_all.c:116 #, c-format msgid "fdblks:%llu frext:%llu\n" msgstr "fdblks:%llu frext:%llu\n" #: .././logprint/log_print_all.c:121 #, c-format msgid "\t\tsunit:%u swidth:%u\n" msgstr "\t\tsunit:%u swidth:%u\n" #: .././logprint/log_print_all.c:126 #, c-format msgid "\tAGI Buffer: (XAGI)\n" msgstr "\tBufor AGI: (XAGI)\n" #: .././logprint/log_print_all.c:129 #, c-format msgid "\t\tver:%d " msgstr "\t\twersja:%d " #: .././logprint/log_print_all.c:131 #, c-format msgid "seq#:%d len:%d cnt:%d root:%d\n" msgstr "seq#:%d len:%d cnt:%d root:%d\n" #: .././logprint/log_print_all.c:136 #, c-format msgid "\t\tlevel:%d free#:0x%x newino:0x%x\n" msgstr "\t\tlevel:%d free#:0x%x newino:0x%x\n" #: .././logprint/log_print_all.c:142 #, c-format msgid "\tAGF Buffer: (XAGF)\n" msgstr "\tBufor AGI: (XAGF)\n" #: .././logprint/log_print_all.c:145 #, c-format msgid "\t\tver:%d seq#:%d len:%d \n" msgstr "\t\tver:%d seq#:%d len:%d \n" #: .././logprint/log_print_all.c:149 #, c-format msgid "\t\troot BNO:%d CNT:%d\n" msgstr "\t\troot BNO:%d CNT:%d\n" #: .././logprint/log_print_all.c:152 #, c-format msgid "\t\tlevel BNO:%d CNT:%d\n" msgstr "\t\tlevel BNO:%d CNT:%d\n" #: .././logprint/log_print_all.c:155 #, c-format msgid "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" msgstr "\t\t1st:%d last:%d cnt:%d freeblks:%d longest:%d\n" #: .././logprint/log_print_all.c:164 #, c-format msgid "\tDQUOT Buffer:\n" msgstr "\tBufor DQUOT:\n" #: .././logprint/log_print_all.c:167 #, c-format msgid "\t\tUIDs 0x%lx-0x%lx\n" msgstr "\t\tUIDs 0x%lx-0x%lx\n" #: .././logprint/log_print_all.c:172 #, c-format msgid "\tBUF DATA\n" msgstr "\tDANE BUF\n" #: .././logprint/log_print_all.c:194 #, c-format msgid "\tQUOTAOFF: #regs:%d type:%s\n" msgstr "\tQUOTAOFF: #regs:%d type:%s\n" #: .././logprint/log_print_all.c:209 #, c-format msgid "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" msgstr "\tDQUOT: #regs:%d blkno:%lld boffset:%u id: %d\n" #: .././logprint/log_print_all.c:213 #, c-format msgid "\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n" msgstr "\t\tmagic 0x%x\twersja 0x%x\tID 0x%x (%d)\t\n" #: .././logprint/log_print_all.c:218 #, c-format msgid "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" msgstr "\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x\tino_soft 0x%x\n" #: .././logprint/log_print_all.c:224 #, c-format msgid "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" msgstr "\t\tbcount 0x%x (%d) icount 0x%x (%d)\n" #: .././logprint/log_print_all.c:229 #, c-format msgid "\t\tbtimer 0x%x itimer 0x%x \n" msgstr "\t\tbtimer 0x%x itimer 0x%x \n" #: .././logprint/log_print_all.c:238 #, c-format msgid "\tCORE inode:\n" msgstr "\tGŁÓWNY i-węzeł:\n" #: .././logprint/log_print_all.c:241 #, c-format msgid "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlink:%d\n" msgstr "\t\tmagic:%c%c mode:0x%x ver:%d format:%d onlin:%d\n" #: .././logprint/log_print_all.c:245 #, c-format msgid "\t\tuid:%d gid:%d nlink:%d projid:%u\n" msgstr "\t\tuid:%d gid:%d nlink:%d projid:%u\n" #: .././logprint/log_print_all.c:247 #, c-format msgid "\t\tatime:%d mtime:%d ctime:%d\n" msgstr "\t\tatime:%d mtime:%d ctime:%d\n" #: .././logprint/log_print_all.c:249 #, c-format msgid "\t\tflushiter:%d\n" msgstr "\t\tflushiter:%d\n" #: .././logprint/log_print_all.c:250 #, c-format msgid "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" msgstr "\t\tsize:0x%llx nblks:0x%llx exsize:%d nextents:%d anextents:%d\n" #: .././logprint/log_print_all.c:254 #, c-format msgid "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" msgstr "\t\tforkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x gen:%d\n" #: .././logprint/log_print_all.c:274 #, c-format msgid "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" msgstr "\tINODE: #regs:%d ino:0x%llx flags:0x%x dsize:%d\n" #: .././logprint/log_print_all.c:289 #, c-format msgid "\t\tDATA FORK EXTENTS inode data:\n" msgstr "\t\tDane EKSTENTÓW GAŁĘZI DANYCH i-węzła:\n" #: .././logprint/log_print_all.c:296 #, c-format msgid "\t\tDATA FORK BTREE inode data:\n" msgstr "\t\tDane B-DRZEWA GAŁĘZI DANYCH i-węzła:\n" #: .././logprint/log_print_all.c:303 #, c-format msgid "\t\tDATA FORK LOCAL inode data:\n" msgstr "\t\tDane LOKALNE GAŁĘZI DANYCH i-węzła:\n" #: .././logprint/log_print_all.c:310 #, c-format msgid "\t\tDEV inode: no extra region\n" msgstr "\t\tI-węzeł DEV: brak dodatkowego regionu\n" #: .././logprint/log_print_all.c:314 #, c-format msgid "\t\tUUID inode: no extra region\n" msgstr "\t\tI-węzeł UUID: brak dodatkowego regionu\n" #: .././logprint/log_print_all.c:329 #, c-format msgid "\t\tATTR FORK EXTENTS inode data:\n" msgstr "\t\tDane EKSTENTÓW GAŁĘZI ATRYBUTÓW i-węzła:\n" #: .././logprint/log_print_all.c:337 #, c-format msgid "\t\tATTR FORK BTREE inode data:\n" msgstr "\t\tDane B-DRZEWA GAŁĘZI ATRYBUTÓW i-węzła:\n" #: .././logprint/log_print_all.c:345 #, c-format msgid "\t\tATTR FORK LOCAL inode data:\n" msgstr "\t\tDane LOKALNE GAŁĘZI ATRYBUTÓW i-węzła:\n" #: .././logprint/log_print_all.c:370 #, c-format msgid "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" msgstr "\tEFD: #regs: %d num_extents: %d id: 0x%llx\n" #: .././logprint/log_print_all.c:394 #, c-format msgid "%s: xlog_recover_print_efi: malloc failed\n" msgstr "%s: xlog_recover_print_efi: malloc nie powiodło się\n" #: .././logprint/log_print_all.c:402 #, c-format msgid "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" msgstr "\tEFI: #regs:%d num_extents:%d id:0x%llx\n" #: .././logprint/log_print_all.c:442 #, c-format msgid "xlog_recover_print_logitem: illegal type\n" msgstr "xlog_recover_print_logitem: niedozwolony typ\n" #: .././logprint/log_print_all.c:473 #, c-format msgid "%s: illegal type" msgstr "%s: niedozwolony typ" #: .././logprint/log_print_all.c:481 #, c-format msgid ": cnt:%d total:%d " msgstr ": cnt:%d total:%d " #: .././logprint/log_print_all.c:483 #, c-format msgid "a:0x%lx len:%d " msgstr "a:0x%lx len:%d " #: .././libxlog/util.c:37 #, c-format msgid "" "* ERROR: mismatched uuid in log\n" "* SB : %s\n" "* log: %s\n" msgstr "" "* BŁĄD: niepasujący uuid w logu\n" " SB : %s\n" " log: %s\n" #: .././libxlog/util.c:50 #, c-format msgid "" "\n" "LOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n" msgstr "" "\n" "LOG REC AT LSN cykl %d blok %d (0x%x, 0x%x)\n" #: .././libxlog/util.c:58 #, c-format msgid "* ERROR: bad magic number in log header: 0x%x\n" msgstr "* BŁĄD: błędna liczba magiczna w nagłówku logu: 0x%x\n" #: .././libxlog/util.c:67 #, c-format msgid "* ERROR: log format incompatible (log=%d, ours=%d)\n" msgstr "* BŁĄD: niekompatybilny format logu (log=%d, nasz=%d)\n" #: .././libxlog/util.c:77 .././libxlog/util.c:89 msgid "Bad log" msgstr "Błędny log" #: .././libxfs/freebsd.c:49 #, c-format msgid "%s: %s possibly contains a mounted filesystem\n" msgstr "%s: %s może zawierać podmontowany system plików\n" #: .././libxfs/freebsd.c:60 .././libxfs/linux.c:67 #, c-format msgid "%s: %s contains a mounted filesystem\n" msgstr "%s: %s zawiera podmontowany system plików\n" #: .././libxfs/freebsd.c:75 .././libxfs/linux.c:85 #, c-format msgid "%s: %s contains a possibly writable, mounted filesystem\n" msgstr "%s: %s zawiera podmontowany, być może zapisywalny system plików\n" #: .././libxfs/freebsd.c:89 .././libxfs/linux.c:99 #, c-format msgid "%s: %s contains a mounted and writable filesystem\n" msgstr "%s: %s zawiera podmontowany, zapisywalny system plików\n" #: .././libxfs/freebsd.c:116 .././libxfs/darwin.c:76 .././libxfs/irix.c:58 #: .././libxfs/linux.c:138 #, c-format msgid "%s: cannot stat the device file \"%s\": %s\n" msgstr "%s: nie można wykonać stat na pliku urządzenia \"%s\": %s\n" #: .././libxfs/freebsd.c:129 #, c-format msgid "%s: Not a device or file: \"%s\"\n" msgstr "%s: Nie jest urządzeniem ani plikiem: \"%s\"\n" #: .././libxfs/freebsd.c:135 #, c-format msgid "%s: DIOCGMEDIASIZE failed on \"%s\": %s\n" msgstr "%s: DIOCGMEDIASIE nie powiodło się dla \"%s\": %s\n" #: .././libxfs/freebsd.c:141 #, c-format msgid "%s: DIOCGSECTORSIZE failed on \"%s\": %s\n" msgstr "%s: DIOCGSECTORSIZE nie powiodło się dla \"%s\": %s\n" #: .././libxfs/freebsd.c:196 .././libxfs/darwin.c:139 .././libxfs/irix.c:106 #: .././libxfs/linux.c:216 #, c-format msgid "%s: can't determine memory size\n" msgstr "%s: nie można określić rozmiaru pamięci\n" #: .././libxfs/util.c:707 #, c-format msgid "%s: cannot reserve space: %s\n" msgstr "%s: nie można zarezerwować przestrzeni: %s\n" #: .././libxfs/darwin.c:41 #, c-format msgid "%s: error opening the device special file \"%s\": %s\n" msgstr "%s: błąd podczas otwierania pliku specjalnego urządzenia \"%s\": %s\n" #: .././libxfs/darwin.c:48 #, c-format msgid "%s: can't tell if \"%s\" is writable: %s\n" msgstr "%s: nie można stwierdzić czy \"%s\" jest zapisywalny: %s\n" #: .././libxfs/darwin.c:86 #, c-format msgid "%s: can't determine device size: %s\n" msgstr "%s: nie można określić rozmiaru urządzenia: %s\n" #: .././libxfs/kmem.c:15 #, c-format msgid "%s: zone init failed (%s, %d bytes): %s\n" msgstr "%s: inicjalizacja strefy nie powiodła się (%s, %d bajtów): %s\n" #: .././libxfs/kmem.c:32 #, c-format msgid "%s: zone alloc failed (%s, %d bytes): %s\n" msgstr "%s: przydzielenie strefy nie powiodło się (%s, %d bajtów): %s\n" #: .././libxfs/kmem.c:56 #, c-format msgid "%s: malloc failed (%d bytes): %s\n" msgstr "%s: malloc nie powiodło się (%d bajtów): %s\n" #: .././libxfs/kmem.c:77 #, c-format msgid "%s: realloc failed (%d bytes): %s\n" msgstr "%s: realloc nie powiodło się (%d bajtów): %s\n" #: .././libxfs/linux.c:114 #, c-format msgid "%s: %s - cannot set blocksize %d on block device %s: %s\n" msgstr "%s: %s - nie można ustawić rozmiaru bloku %d dla urządzenia blokowego %s: %s\n" #: .././libxfs/linux.c:161 #, c-format msgid "%s: can't determine device size\n" msgstr "%s: nie można określić rozmiaru urządzenia\n" #: .././libxfs/linux.c:169 #, c-format msgid "%s: warning - cannot get sector size from block device %s: %s\n" msgstr "%s: uwaga - nie można pobrać rozmiaru sektora urządzenia blokowego %s: %s\n" #: .././libxfs/init.c:80 .././libxfs/init.c:179 #, c-format msgid "%s: %s: device %lld is not open\n" msgstr "%s: %s: urządzenie %lld nie jest otwarte\n" #: .././libxfs/init.c:116 #, c-format msgid "%s: cannot stat %s: %s\n" msgstr "%s: nie można wykonać stat na %s: %s\n" #: .././libxfs/init.c:141 #, c-format msgid "%s: device %lld is already open\n" msgstr "%s: urządzenie %lld jest już otwarte\n" #: .././libxfs/init.c:154 #, c-format msgid "%s: %s: too many open devices\n" msgstr "%s: %s: zbyt dużo otwartych urządzeń\n" #: .././libxfs/init.c:197 #, c-format msgid "%s: can't find a character device matching %s\n" msgstr "%s: nie można odnaleźć urządzenia znakowego odpowiadającego %s\n" #: .././libxfs/init.c:203 #, c-format msgid "%s: can't find a block device matching %s\n" msgstr "%s: nie można odnaleźć urządzenia blokowego odpowiadającego %s\n" #: .././libxfs/init.c:320 #, c-format msgid "%s: can't get size for data subvolume\n" msgstr "%s: nie można pobrać rozmiaru podwolumenu danych\n" #: .././libxfs/init.c:325 #, c-format msgid "%s: can't get size for log subvolume\n" msgstr "%s: nie można pobrać rozmiaru podwolumenu logu\n" #: .././libxfs/init.c:330 #, c-format msgid "%s: can't get size for realtime subvolume\n" msgstr "%s: nie można pobrać rozmiaru podwolumenu realtime\n" #: .././libxfs/init.c:430 #, c-format msgid "%s: cannot read realtime bitmap inode (%d)\n" msgstr "%s: nie można odczytać i-węzła bitmapy realtime (%d)\n" #: .././libxfs/init.c:440 #, c-format msgid "%s: cannot read realtime summary inode (%d)\n" msgstr "%s: nie można odczytać i-węzła opisu realtime (%d)\n" #: .././libxfs/init.c:464 #, c-format msgid "%s: filesystem has a realtime subvolume\n" msgstr "%s: system plików ma podwolumen realtime\n" #: .././libxfs/init.c:486 #, c-format msgid "%s: realtime init - %llu != %llu\n" msgstr "%s: inicjalizacja realtime - %llu != %llu\n" #: .././libxfs/init.c:494 #, c-format msgid "%s: realtime size check failed\n" msgstr "%s: sprawdzenie rozmiaru realtime nie powiodło się\n" #: .././libxfs/init.c:699 #, c-format msgid "%s: size check failed\n" msgstr "%s: sprawdzenie rozmiaru nie powiodło się\n" #: .././libxfs/init.c:708 #, c-format msgid "%s: WARNING - filesystem uses v1 dirs,limited functionality provided.\n" msgstr "%s: UWAGA - system plików używa katalogów v1, funkcjonalność jest ograniczona.\n" #: .././libxfs/init.c:728 #, c-format msgid "%s: data size check failed\n" msgstr "%s: sprawdzenie rozmiaru danych nie powiodło się\n" #: .././libxfs/init.c:741 #, c-format msgid "%s: log size checks failed\n" msgstr "%s: sprawdzenie rozmiaru logu nie powiodło się\n" #: .././libxfs/init.c:752 #, c-format msgid "%s: realtime device init failed\n" msgstr "%s: inicjalizacja urządzenia realtime nie powiodła się\n" #: .././libxfs/init.c:759 #, c-format msgid "%s: perag init failed\n" msgstr "%s: nie udało się zainicjować perag\n" #: .././libxfs/init.c:771 #, c-format msgid "%s: cannot read root inode (%d)\n" msgstr "%s: nie można odczytać i-węzła głównego (%d)\n" #: .././libxfs/init.c:791 #, c-format msgid "%s: cannot init perag data (%d)\n" msgstr "%s: nie można zainicjować tabeli perag (%d)\n" #: .././libxfs/rdwr.c:40 #, c-format msgid "%s: %s can't memalign %d bytes: %s\n" msgstr "%s: %s nie można wykonać memalign dla %d bajtów: %s\n" #: .././libxfs/rdwr.c:50 #, c-format msgid "%s: %s seek to offset %llu failed: %s\n" msgstr "%s: %s zmiana offsetu na %llu nie powiodła się: %s\n" #: .././libxfs/rdwr.c:60 #, c-format msgid "%s: %s write failed: %s\n" msgstr "%s: %s zapis nie powiódł się: %s\n" #: .././libxfs/rdwr.c:64 #, c-format msgid "%s: %s not progressing?\n" msgstr "%s: %s nie postępuje?\n" #: .././libxfs/rdwr.c:336 #, c-format msgid "%s: %s can't memalign %u bytes: %s\n" msgstr "%s: %s nie można wykonać memalign dla %u bajtów: %s\n" #: .././libxfs/rdwr.c:425 #, c-format msgid "Warning: recursive buffer locking at block % detected\n" msgstr "Uwaga: wykryto rekurencyjną blokadę bufora na bloku %\n" #: .././libxfs/rdwr.c:519 #, c-format msgid "%s: read failed: %s\n" msgstr "%s: odczyt nie powiódł się: %s\n" #: .././libxfs/rdwr.c:525 #, c-format msgid "%s: error - read only %d of %d bytes\n" msgstr "%s: błąd - odczytano tylko %d z %d bajtów\n" #: .././libxfs/rdwr.c:568 #, c-format msgid "%s: pwrite64 failed: %s\n" msgstr "%s: pwrite64 nie powiodło się: %s\n" #: .././libxfs/rdwr.c:574 #, c-format msgid "%s: error - wrote only %d of %d bytes\n" msgstr "%s: błąd - zapisano tylko %d z %d bajtów\n" #: .././libxfs/trans.c:33 #, c-format msgid "%s: xact calloc failed (%d bytes): %s\n" msgstr "%s: xact calloc nie powiodło się (%d bajtów): %s\n" #: .././libxfs/trans.c:602 #, c-format msgid "%s: warning - itobp failed (%d)\n" msgstr "%s: uwaga - itobp nie powiodło się (%d)\n" #: .././libxfs/trans.c:610 #, c-format msgid "%s: warning - iflush_int failed (%d)\n" msgstr "%s: uwaga - iflush_int nie powiodło się (%d)\n" #: .././libxfs/trans.c:682 .././libxfs/trans.c:741 #, c-format msgid "%s: unrecognised log item type\n" msgstr "%s: nierozpoznany typ elementu logu\n" #: .././libxcmd/command.c:85 #, c-format msgid "bad argument count %d to %s, expected at least %d arguments\n" msgstr "błędna liczba argumentów %d dla %s, oczekiwano co najmniej %d argumentów\n" #: .././libxcmd/command.c:89 #, c-format msgid "bad argument count %d to %s, expected %d arguments\n" msgstr "błędna liczba argumentów %d dla %s, oczekiwano %d argumentów\n" #: .././libxcmd/command.c:93 #, c-format msgid "bad argument count %d to %s, expected between %d and %d arguments\n" msgstr "błędna liczba argumentów %d dla %s, oczekiwano od %d do %d argumentów\n" #: .././libxcmd/command.c:155 #, c-format msgid "cannot strdup command '%s': %s\n" msgstr "nie można wykonać strdup na poleceniu '%s': %s\n" #: .././libxcmd/command.c:171 .././libxcmd/command.c:189 #, c-format msgid "command \"%s\" not found\n" msgstr "nie znaleziono polecenia \"%s\"\n" #: .././libxcmd/help.c:33 .././db/help.c:40 #, c-format msgid "" "\n" "Use 'help commandname' for extended help.\n" msgstr "" "\n" "Rozszerzony opis można uzyskać przez 'help nazwa_polecenia'.\n" #: .././libxcmd/help.c:49 .././db/command.c:82 .././db/help.c:56 #, c-format msgid "command %s not found\n" msgstr "nie znaleziono polecenia %s\n" #: .././libxcmd/help.c:92 .././db/help.c:30 .././db/io.c:48 msgid "[command]" msgstr "[polecenie]" #: .././libxcmd/help.c:93 .././db/help.c:31 msgid "help for one or all commands" msgstr "opis dla jednego lub wszystkich poleceń" #: .././libxcmd/paths.c:263 #, c-format msgid "%s: unable to extract mount options for \"%s\"\n" msgstr "%s: nie udało się wydobyć opcji montowania dla \"%s\"\n" #: .././libxcmd/paths.c:324 #, c-format msgid "%s: getmntinfo() failed: %s\n" msgstr "%s: getmntinfo() nie powiodło się: %s\n" #: .././libxcmd/paths.c:385 #, c-format msgid "%s: cannot setup path for mount %s: %s\n" msgstr "%s: nie można ustawić ścieżki dla montowania %s: %s\n" #: .././libxcmd/paths.c:407 #, c-format msgid "%s: cannot find mount point for path `%s': %s\n" msgstr "%s: nie można znaleźć punktu montowania dla ścieżki `%s': %s\n" #: .././libxcmd/paths.c:435 #, c-format msgid "%s: cannot setup path for project %s: %s\n" msgstr "%s: nie można ustawić ścieżki dla projektu %s: %s\n" #: .././libxcmd/paths.c:476 #, c-format msgid "%s: cannot initialise path table: %s\n" msgstr "%s: nie można zainicjować tabeli ścieżek: %s\n" #: .././libxcmd/paths.c:496 #, c-format msgid "%s: cannot setup path for project dir %s: %s\n" msgstr "%s: nie można ustawić ścieżki dla katalogu projektu %s: %s\n" #: .././libxcmd/quit.c:42 msgid "exit the program" msgstr "wyjście z programu" #: .././libdisk/drivers.c:35 #, c-format msgid "Cannot stat %s: %s\n" msgstr "Nie można wykonać stat na %s: %s\n" #: .././libdisk/lvm.c:60 #, c-format msgid "Warning - LVM device, but no lvdisplay(8) found\n" msgstr "Uwaga - urządzenie LVM, ale nie znaleziono lvdisplay(8)\n" #: .././libdisk/lvm.c:70 .././libdisk/dm.c:73 #, c-format msgid "Could not open pipe\n" msgstr "Nie udało się otworzyć potoku\n" #: .././libdisk/lvm.c:85 .././libdisk/dm.c:88 #, c-format msgid "Failed to execute %s\n" msgstr "Nie udało się wywołać %s\n" #: .././libdisk/lvm.c:89 #, c-format msgid "Failed forking lvdisplay process\n" msgstr "Nie udało się odgałęzić procesu lvdisplay\n" #: .././libdisk/md.c:61 #, c-format msgid "Error getting MD array device from %s\n" msgstr "Błąd podczas pobierania urządzenia macierzy MD z %s\n" #: .././libdisk/md.c:68 #, c-format msgid "Couldn't malloc device string\n" msgstr "Nie można przydzielić łańcucha nazwy urządzenia\n" #: .././libdisk/md.c:84 #, c-format msgid "Error getting MD array info from %s\n" msgstr "Błąd podczas pobierania informacji o macierzy MD z %s\n" #: .././libdisk/dm.c:57 #, c-format msgid "Warning - device mapper device, but no dmsetup(8) found\n" msgstr "Uwaga - urządzenie device mappera, ale nie znaleziono dmsetup(8)\n" #: .././libdisk/dm.c:92 #, c-format msgid "Failed forking dmsetup process\n" msgstr "Nie udało się odgałęzić procesu dmsetup\n" #: .././io/inject.c:109 #, c-format msgid "" "\n" " inject errors into the filesystem of the currently open file\n" "\n" " Example:\n" " 'inject readagf' - cause errors on allocation group freespace reads\n" "\n" " Causes the kernel to generate and react to errors within XFS, provided\n" " the XFS kernel code has been built with debugging features enabled.\n" " With no arguments, displays the list of error injection tags.\n" "\n" msgstr "" "\n" " wprowadzenie błędów do systemu plików aktualnie otwartego pliku\n" "\n" " Przykład:\n" " 'inject readagf' - spowodowanie błędów przy odczytach wolnego miejsca grup\n" " alokacji\n" "\n" " inject powoduje, że jądro generuje i reaguje na błędy wewnątrz XFS-a,\n" " pod warunkiem, że kod XFS-a w jądrze został zbudowany z włączonymi opcjami\n" " diagnostycznymi. Bez argumentów wyświetla listę znaczników wprowadzania\n" " błędów.\n" "\n" #: .././io/inject.c:135 #, c-format msgid "no such tag -- %s\n" msgstr "nie ma takiego znacznika - %s\n" #: .././io/inject.c:156 msgid "[tag ...]" msgstr "[znacznik ...]" #: .././io/inject.c:157 msgid "inject errors into a filesystem" msgstr "wprowadzanie błędów do systemu plików" #: .././io/getrusage.c:118 msgid "report process resource usage" msgstr "informacje o wykorzystaniu zasobów przez proces" #: .././io/freeze.c:37 #, c-format msgid "%s: cannot freeze filesystem at %s: %s\n" msgstr "%s: nie można zamrozić systemu plików na %s: %s\n" #: .././io/freeze.c:54 #, c-format msgid "%s: cannot unfreeze filesystem mounted at %s: %s\n" msgstr "%s: nie można odmrozić systemu plików podmontowanego pod %s: %s\n" #: .././io/freeze.c:70 msgid "freeze filesystem of current file" msgstr "zamrożenie systemu plików na bieżącym pliku" #: .././io/freeze.c:77 msgid "unfreeze filesystem of current file" msgstr "odmrożenie systemu plików na bieżącym pliku" #: .././io/fiemap.c:32 #, c-format msgid "" "\n" " prints the block mapping for a file's data or attribute forks\n" " Example:\n" " 'fiemap -v' - tabular format verbose map\n" "\n" " fiemap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -v -- Verbose information\n" "\n" msgstr "" "\n" " wypisanie mapowania bloków dla danych lub atrybutów pliku\n" " Przykład:\n" " 'fiemap -v' - szczegółowa mapa w formacie tabeli\n" "\n" " fiemap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" " Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" " nie mające przypisanych bloków (dziury).\n" " Domyślnie każda linia listingu przyjmuje następującą postać:\n" " ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" " Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" " Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" " -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" " -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" " -n - odpytanie n ekstentów.\n" " -v - szczegółowe informacje\n" "\n" #: .././io/fiemap.c:97 .././io/fiemap.c:317 .././io/fiemap.c:321 #: .././io/bmap.c:251 .././io/bmap.c:379 #, c-format msgid "hole" msgstr "dziura" #: .././io/fiemap.c:139 .././io/fiemap.c:153 .././io/fiemap.c:323 #, c-format msgid " %llu blocks\n" msgstr " %llu bloków\n" #: .././io/fiemap.c:210 .././io/bmap.c:149 #, c-format msgid "%s: malloc of %d bytes failed.\n" msgstr "%s: przydzielenie %d bajtów nie powiodło się.\n" #: .././io/fiemap.c:243 .././io/bmap.c:339 msgid "EXT" msgstr "EXT" #: .././io/fiemap.c:244 .././io/bmap.c:340 msgid "FILE-OFFSET" msgstr "OFFSET-W-PLIKU" #: .././io/fiemap.c:245 .././io/bmap.c:341 msgid "BLOCK-RANGE" msgstr "ZAKRES-BLOKÓW" #: .././io/fiemap.c:246 .././io/bmap.c:344 msgid "TOTAL" msgstr "RAZEM" #: .././io/fiemap.c:247 msgid "FLAGS" msgstr "FLAGI" #: .././io/fiemap.c:343 msgid "[-alv] [-n nx]" msgstr "[-alv] [-n nx]" #: .././io/fiemap.c:344 msgid "print block mapping for a file" msgstr "wypisanie mapowania bloków dla pliku" #: .././io/imap.c:53 #, c-format msgid "ino %10llu count %2d mask %016llx\n" msgstr "i-węzeł %10llu liczba %2d maska %016llx\n" #: .././io/imap.c:71 msgid "[nentries]" msgstr "[liczba_wpisów]" #: .././io/imap.c:73 msgid "inode map for filesystem of current file" msgstr "map i-węzłów dla systemu plików bieżącego pliku" #: .././io/madvise.c:32 #, c-format msgid "" "\n" " advise the page cache about access patterns expected for a mapping\n" "\n" " Modifies page cache behavior when operating on the current mapping.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" " -r -- expect random page references (POSIX_MADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" " Notes:\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED forces the maximum readahead.\n" "\n" msgstr "" "\n" " doradzenie buforowi stron w sprawie oczekiwanych schematów dostępu do odwzorowań\n" "\n" " madvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym\n" " odwzorowaniu. Niektóre polecenia madvise ([*] poniżej) wymagają podania zakresu.\n" " Bez argumentów zakłada się doradzenie POSIX_MADV_NORMAL.\n" " -d - podane strony nie są wymagane (POSIX_MADV_DONTNEED) [*]\n" " -r - należy oczekiwać losowych odwołań do stron (POSIX_MADV_RANDOM)\n" " -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_MADV_SEQUENTIAL)\n" " -w - podane strony będą potrzebne (POSIX_MADV_WILLNEED) [*]\n" " Uwagi:\n" " NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" " RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" " SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" " WILLNEED wymusza maksymalne czytanie z wyprzedzeniem.\n" "\n" #: .././io/madvise.c:87 .././io/mincore.c:48 .././io/mmap.c:206 #: .././io/mmap.c:301 .././io/mmap.c:387 .././io/mmap.c:546 #: .././io/prealloc.c:55 .././io/pwrite.c:284 .././io/sendfile.c:126 #: .././io/fadvise.c:92 #, c-format msgid "non-numeric offset argument -- %s\n" msgstr "nieliczbowy argument będący offsetem - %s\n" #: .././io/madvise.c:94 .././io/mincore.c:54 .././io/mmap.c:212 #: .././io/mmap.c:308 .././io/mmap.c:394 .././io/mmap.c:553 #: .././io/pread.c:330 .././io/pread.c:338 .././io/prealloc.c:60 #: .././io/pwrite.c:290 .././io/sendfile.c:133 .././io/fadvise.c:99 #, c-format msgid "non-numeric length argument -- %s\n" msgstr "nieliczbowy argument będący długością - %s\n" #: .././io/madvise.c:98 .././io/mincore.c:58 #, c-format msgid "length argument too large -- %lld\n" msgstr "zbyt duży argument będący długością - %lld\n" #: .././io/madvise.c:127 msgid "[-drsw] [off len]" msgstr "[-drsw] [offset długość]" #: .././io/madvise.c:128 msgid "give advice about use of memory" msgstr "doradzenie w sprawie użycia pamięci" #: .././io/mincore.c:92 .././io/mincore.c:102 #, c-format msgid "0x%lx %lu pages (%llu : %lu)\n" msgstr "0x%lx %lu stron (%llu : %lu)\n" #: .././io/mincore.c:122 msgid "[off len]" msgstr "[offset długość]" #: .././io/mincore.c:123 msgid "find mapping pages that are memory resident" msgstr "odnalezienie stron odwzorowań przechowywanych w pamięci" #: .././io/mmap.c:76 #, c-format msgid "offset (%lld) is before start of mapping (%lld)\n" msgstr "offset (%lld) przed początkiem odwzorowania (%lld)\n" #: .././io/mmap.c:82 #, c-format msgid "offset (%lld) is beyond end of mapping (%lld)\n" msgstr "offset (%lld) za końcem odwzorowania (%lld)\n" #: .././io/mmap.c:87 #, c-format msgid "range (%lld:%lld) is beyond mapping (%lld:%ld)\n" msgstr "przedział (%lld:%lld) poza odwzorowaniem (%lld:%ld)\n" #: .././io/mmap.c:93 #, c-format msgid "offset address (%p) is not page aligned\n" msgstr "adres offsetu (%p) nie jest wyrównany do rozmiaru strony\n" #: .././io/mmap.c:133 #, c-format msgid "" "\n" " maps a range within the current file into memory\n" "\n" " Example:\n" " 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" "\n" " Memory maps a range of a file for subsequent use by other xfs_io commands.\n" " With no arguments, mmap shows the current mappings. The current mapping\n" " can be set by using the single argument form (mapping number or address).\n" " If two arguments are specified (a range), a new mapping is created and the\n" " following options are available:\n" " -r -- map with PROT_READ protection\n" " -w -- map with PROT_WRITE protection\n" " -x -- map with PROT_EXEC protection\n" " If no protection mode is specified, all are used by default.\n" "\n" msgstr "" "\n" " odwzorowanie przedziału z bieżącego pliku w pamięci\n" "\n" "Przykład:\n" " 'mmap -rw 0 1m' - odwzorowuje 1MB od początku bieżącego pliku\n" "\n" " mmap odwzorowuje w pamięci przedział z pliku do dalszego wykorzystania przez\n" " inne polecenia xfs_io.\n" " Bez argumentów mmap pokazuje aktualne odwzorowania. Bieżące odwzorowanie\n" " można ustawić przy użyciu formy jednoargumentowej (mmap numer lub adres).\n" " Jeśli podano dwa argumenty (przedział), tworzone jest nowe odwzorowanie\n" " i dostępne są następujące opcje:\n" " -r - odwzorowanie z ochroną PROT_READ\n" " -w - odwzorowanie z ochroną PROT_WRITE\n" " -x - odwzorowanie z ochroną PROT_EXEC\n" " Jeśli nie podano trybu ochrony, domyślnie używane są wszystkie.\n" "\n" #: .././io/mmap.c:167 .././io/mmap.c:174 .././io/init.c:105 #, c-format msgid "no mapped regions, try 'help mmap'\n" msgstr "nie ma podmapowanych regionów, spróbuj 'help mmap'\n" #: .././io/mmap.c:168 .././io/mmap.c:175 .././io/mmap.c:178 .././io/init.c:101 #: .././io/open.c:273 #, c-format msgid "no files are open, try 'help open'\n" msgstr "nie ma otwartych plików, spróbuj 'help open'\n" #: .././io/mmap.c:254 #, c-format msgid "" "\n" " flushes a range of bytes in the current memory mapping\n" "\n" " Writes all modified copies of pages over the specified range (or entire\n" " mapping if no range specified) to their backing storage locations. Also,\n" " optionally invalidates so that subsequent references to the pages will be\n" " obtained from their backing storage locations (instead of cached copies).\n" " -a -- perform asynchronous writes (MS_ASYNC)\n" " -i -- invalidate mapped pages (MS_INVALIDATE)\n" " -s -- perform synchronous writes (MS_SYNC)\n" "\n" msgstr "" "\n" " zrzucenie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" "\n" " msync zapisuje wszystkie zmodyfikowane kopie stron z podanego przedziału\n" " (lub całego odwzorowania, jeśli nie podano przedziału) do miejsca\n" " przechowywania danych. Opcjonalnie unieważnia bufor, żeby dalsze odwołania\n" " do tych stron odbywały się z miejsca przechowywania danych (zamiast kopii\n" " w pamięci podręcznej).\n" " -a - wykonanie zapisu asynchronicznego (MS_ASYNC)\n" " -i - unieważnienie odwzorowanych stron (MS_INVALIDATE)\n" " -s - wykonanie zapisu synchronicznego (MS_SYNC)\n" "\n" #: .././io/mmap.c:330 #, c-format msgid "" "\n" " reads a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" "\n" " Accesses a range of the current memory mapping, optionally dumping it to\n" " the standard output stream (with -v option) for subsequent inspection.\n" " -f -- verbose mode, dump bytes with offsets relative to start of file.\n" " -r -- reverse order; start accessing from the end of range, moving backward\n" " -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" " The accesses are performed sequentially from the start offset by default.\n" " Notes:\n" " References to whole pages following the end of the backing file results\n" " in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" " on various filesystem conditions, including quota exceeded errors, and\n" " for physical device errors (such as unreadable disk blocks). No attempt\n" " has been made to catch signals at this stage...\n" "\n" msgstr "" "\n" " odczytanie przedziału bajtów w bieżącym odwzorowaniu pamięci\n" "\n" " Przykład:\n" " 'mread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu\n" " w odwzorowaniu\n" "\n" " mread odwołuje się do przedziału bieżącego odwzorowania pamięci, opcjonalnie\n" " zrzucając go na strumień standardowego wyjścia (z opcją -v) do dalszych badań.\n" " -f - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku pliku.\n" " -r - odwrotna kolejność; dostęp począwszy od końca przedziału do początku.\n" " -v - tryb szczegółowy, zrzucenie bajtów z offsetami względem początku\n" " odwzorowania.\n" " Dostępy są wykonywane sekwencyjnie, domyślnie od offsetu początkowego.\n" " Uwagi:\n" " Odwołania do całych stron za końcem pliku powodują w efekcie sygnał SIGBUS.\n" " Sygnały SIGBUS mogą być wywołane także przy różnych zdarzeniach związanych\n" " z systemem plików, włącznie z błędami przekroczenia limitów (quota) oraz\n" " fizycznymi błędami urządzenia (takimi jak nieczytelne bloki dysku). Na tym\n" " etapie nie ma prób wyłapania sygnałów...\n" "\n" #: .././io/mmap.c:494 #, c-format msgid "" "\n" " dirties a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" "\n" " Stores a byte into memory for a range within a mapping.\n" " The default stored value is 'X', repeated to fill the range specified.\n" " -S -- use an alternate seed character\n" " -r -- reverse order; start storing from the end of range, moving backward\n" " The stores are performed sequentially from the start offset by default.\n" "\n" msgstr "" "\n" " zmiana przedziału bajtów w bieżącym odwzorowaniu pamięci\n" "\n" " Przykład:\n" " 'mwrite 512 20' - zapisuje 20 bajtów od 512 bajtu w bieżącym odwzorowaniu.\n" "\n" " mwrite zapisuje bajt do przedziału pamięci w ramach odwzorowania.\n" " Domyślnie zapisywaną wartością jest 'X', powtarzane do wypełnienia przedziału.\n" " -S - użycie alternatywnego znaku\n" " -r - odwrotna kolejność; rozpoczęcie zapisywania od końca przedziału do\n" " początku\n" " Zapisy są wykonywane kolejno, domyślnie od offsetu początkowego.\n" "\n" #: .././io/mmap.c:530 .././io/pread.c:315 .././io/pwrite.c:251 #: .././io/pwrite.c:270 #, c-format msgid "non-numeric seed -- %s\n" msgstr "nieliczbowy zarodek - %s\n" #: .././io/mmap.c:586 msgid "[N] | [-rwx] [off len]" msgstr "[N] | [-rwx] [offset długość]" #: .././io/mmap.c:588 msgid "mmap a range in the current file, show mappings" msgstr "odwzorowanie przedziału w bieżącym pliku, pokazanie odwzorowań" #: .././io/mmap.c:597 msgid "[-r] [off len]" msgstr "[-r] [offset długość]" #: .././io/mmap.c:599 msgid "reads data from a region in the current memory mapping" msgstr "odczyt danych z regionu w bieżącym odwzorowaniu pamięci" #: .././io/mmap.c:608 msgid "[-ais] [off len]" msgstr "[-ais] [offset długość]" #: .././io/mmap.c:609 msgid "flush a region in the current memory mapping" msgstr "zrzucenie regionu w bieżącym odwzorowaniu pamięci" #: .././io/mmap.c:618 msgid "unmaps the current memory mapping" msgstr "usunięcie bieżącego odwzorowania pamięci" #: .././io/mmap.c:626 msgid "[-r] [-S seed] [off len]" msgstr "[-r] [-S wartość] [offset długość]" #: .././io/mmap.c:628 msgid "writes data into a region in the current memory mapping" msgstr "zapis danych do regionu w bieżącym odwzorowaniu pamięci" #: .././io/parent.c:49 #, c-format msgid "%s%s" msgstr "%s%s" #: .././io/parent.c:54 #, c-format msgid "inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n" msgstr "inode-path dla i-węzła: %llu jest niepoprawna - ścieżka \"%s\" nie istnieje\n" #: .././io/parent.c:58 #, c-format msgid "path \"%s\" does not stat for inode: %llu; err = %s\n" msgstr "ścieżka \"%s\" nie pozwala na stat dla i-węzła: %llu; błąd = %s\n" #: .././io/parent.c:67 #, c-format msgid "path \"%s\" found\n" msgstr "ścieżki \"%s\" nie znaleziono\n" #: .././io/parent.c:73 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong inode#\n" msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła\n" #: .././io/parent.c:77 .././io/parent.c:107 #, c-format msgid "ino mismatch for path \"%s\" %llu vs %llu\n" msgstr "niezgodność i-węzła dla ścieżki \"%s\" %llu vs %llu\n" #: .././io/parent.c:85 #, c-format msgid "inode number match: %llu\n" msgstr "zgodność numeru i-węzła: %llu\n" #: .././io/parent.c:95 #, c-format msgid "parent path \"%s\" does not stat: %s\n" msgstr "ścieżka nadrzędna \"%s\" nie pozwala na stat: %s\n" #: .././io/parent.c:103 #, c-format msgid "inode-path for inode: %llu is incorrect - wrong parent inode#\n" msgstr "inode-path dla i-węzła: %llu jest niepoprawna - niewłaściwy numer i-węzła nadrzędnego\n" #: .././io/parent.c:116 #, c-format msgid "parent ino match for %llu\n" msgstr "zgodność numeru i-węzła nadrzędnego dla %llu\n" #: .././io/parent.c:138 #, c-format msgid "parentpaths failed for ino %llu: %s\n" msgstr "parentpaths nie powiodło się dla i-węzła %llu: %s\n" #: .././io/parent.c:149 #, c-format msgid "inode-path for inode: %llu is missing\n" msgstr "brak inode-path dla i-węzła: %llu\n" #: .././io/parent.c:173 #, c-format msgid "can't stat mount point \"%s\": %s\n" msgstr "nie można wykonać stat na punkcie montowania \"%s\": %s\n" #: .././io/parent.c:194 #, c-format msgid "failed to get bulkstat information for inode %llu\n" msgstr "nie udało się uzyskać informacji bulkstat dla i-węzła %llu\n" #: .././io/parent.c:200 #, c-format msgid "failed to get valid bulkstat information for inode %llu\n" msgstr "nie udało się uzyskać prawidłowych informacji bulkstat dla i-węzła %llu\n" #: .././io/parent.c:212 #, c-format msgid "checking inode %llu\n" msgstr "sprawdzanie i-węzła %llu\n" #: .././io/parent.c:227 #, c-format msgid "syssgi bulkstat failed: %s\n" msgstr "syssgi bulkstat nie powiodło się: %s\n" #: .././io/parent.c:249 #, c-format msgid "unable to open \"%s\" for jdm: %s\n" msgstr "nie udało się otworzyć \"%s\" dla jdm: %s\n" #: .././io/parent.c:259 #, c-format msgid "unable to allocate buffers: %s\n" msgstr "nie udało się przydzielić buforów: %s\n" #: .././io/parent.c:268 #, c-format msgid "num errors: %d\n" msgstr "liczba błędów: %d\n" #: .././io/parent.c:270 #, c-format msgid "succeeded checking %llu inodes\n" msgstr "udało się sprawdzić %llu i-węzłów\n" #: .././io/parent.c:281 #, c-format msgid "p_ino = %llu\n" msgstr "p_ino = %llu\n" #: .././io/parent.c:282 #, c-format msgid "p_gen = %u\n" msgstr "p_gen = %u\n" #: .././io/parent.c:283 #, c-format msgid "p_reclen = %u\n" msgstr "p_reclen = %u\n" #: .././io/parent.c:285 #, c-format msgid "p_name = \"%s%s\"\n" msgstr "p_name = \"%s%s\"\n" #: .././io/parent.c:287 #, c-format msgid "p_name = \"%s\"\n" msgstr "p_name = \"%s\"\n" #: .././io/parent.c:309 #, c-format msgid "%s: failed path_to_fshandle \"%s\": %s\n" msgstr "%s: path_to_fshandle nie powiodło się dla \"%s\": %s\n" #: .././io/parent.c:316 #, c-format msgid "%s: path_to_handle failed for \"%s\"\n" msgstr "%s: path_to_handle nie powiodło się dla \"%s\"\n" #: .././io/parent.c:323 #, c-format msgid "%s: unable to allocate parent buffer: %s\n" msgstr "%s: nie udało się przydzielić bufora nadrzędnego: %s\n" #: .././io/parent.c:344 #, c-format msgid "%s: %s call failed for \"%s\": %s\n" msgstr "%s: wywołanie %s nie powiodło się dla \"%s\": %s\n" #: .././io/parent.c:353 #, c-format msgid "%s: inode-path is missing\n" msgstr "%s: brak inode-path\n" #: .././io/parent.c:384 #, c-format msgid "file argument, \"%s\", is not in a mounted XFS filesystem\n" msgstr "argument plikowy \"%s\" nie jest na podmontowanym systemie plików XFS\n" #: .././io/parent.c:424 #, c-format msgid "" "\n" " list the current file's parents and their filenames\n" "\n" " -c -- check the current file's file system for parent consistency\n" " -p -- list the current file's parents and their full paths\n" " -v -- verbose mode\n" "\n" msgstr "" "\n" " wypisanie rodziców bieżącego pliku i ich nazw\n" "\n" " -c - sprawdzenie systemu plików pod kątem spójności rodziców pliku\n" " -p - wypisanie rodziców bieżącego pliku i ich pełnych ścieżek\n" " -v - tryb szczegółowy\n" "\n" #: .././io/parent.c:440 msgid "[-cpv]" msgstr "[-cpv]" #: .././io/parent.c:442 msgid "print or check parent inodes" msgstr "wypisanie lub sprawdzenie i-węzłów nadrzędnych" #: .././io/pread.c:32 #, c-format msgid "" "\n" " reads a range of bytes in a specified block size from the given offset\n" "\n" " Example:\n" " 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" "\n" " Reads a segment of the currently open file, optionally dumping it to the\n" " standard output stream (with -v option) for subsequent inspection.\n" " The reads are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different pattern is requested.\n" " -B -- read backwards through the range from offset (backwards N bytes)\n" " -F -- read forwards through the range of bytes from offset (default)\n" " -v -- be verbose, dump out buffers (used when reading forwards)\n" " -R -- read at random offsets in the range of bytes\n" " -Z N -- zeed the random number generator (used when reading randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" " When in \"random\" mode, the number of read operations will equal the\n" " number required to do a complete forward/backward scan of the range.\n" " Note that the offset within the range is chosen at random each time\n" " (an offset may be read more than once when operating in this mode).\n" "\n" msgstr "" "\n" " odczytanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" "\n" " Przykład:\n" " 'pread -v 512 20' - zrzucenie 20 bajtów odczytanych od 512 bajtu w pliku\n" "\n" " pread odczytuje segment aktualnie otwartego pliku, opcjonalnie zrzucając\n" " zawartość na strumień standardowego wyjścia (z opcją -v) dla dalszych badań.\n" " Odczyty są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" " bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" " chyba że zażądano innego schematu.\n" " -B - odczyt przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" " -F - odczyt przedziału od przodu począwszy od offsetu (domyślny)\n" " -v - tryb szczegółowy, zrzucenie bufora (przy odczycie od przodu)\n" " -R - odczyt losowych offsetów z przedziału bajtów\n" " -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy odczycie losowym)\n" " (nieztety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" " W przypadku trybu losowego liczba operacji odczytu będzie równa liczbie\n" " potrzebnej do pełnego przeskanowania od przodu lub od tyłu całego przedziału.\n" " Należy zauważyć, że offset w przedziale jest wybierany za każdym razem losowo\n" " (dowolny offset może być w tym trybie czytany więcej niż raz).\n" "\n" #: .././io/pread.c:286 .././io/pwrite.c:217 #, c-format msgid "non-numeric bsize -- %s\n" msgstr "nieliczbowy rozmiar bloku - %s\n" #: .././io/pread.c:375 #, c-format msgid "read %lld/%lld bytes at offset %lld\n" msgstr "odczytano %lld/%lld bajtów od offsetu %lld\n" #: .././io/pread.c:377 .././io/pwrite.c:336 .././io/sendfile.c:163 #, c-format msgid "%s, %d ops; %s (%s/sec and %.4f ops/sec)\n" msgstr "%s, %d operacji; %s (%s/sek i %.4f operacji/sek)\n" #: .././io/pread.c:396 msgid "[-b bs] [-v] off len" msgstr "[-b rozm_bloku] [-v] offset długość" #: .././io/pread.c:397 msgid "reads a number of bytes at a specified offset" msgstr "odczyt podanej liczby bajtów od podanego offsetu" #: .././io/prealloc.c:216 .././io/prealloc.c:224 .././io/prealloc.c:232 #: .././io/prealloc.c:240 .././io/prealloc.c:250 .././io/prealloc.c:276 msgid "off len" msgstr "offset długość" #: .././io/prealloc.c:217 msgid "allocates zeroed space for part of a file" msgstr "przydzielenie wyzerowanej przestrzeni dla części pliku" #: .././io/prealloc.c:225 msgid "frees space associated with part of a file" msgstr "zwolnienie miejsca związanego z częścią pliku" #: .././io/prealloc.c:234 msgid "reserves space associated with part of a file" msgstr "zarezerwowanie miejsca związanego z częścią pliku" #: .././io/prealloc.c:243 msgid "frees reserved space associated with part of a file" msgstr "zwolnienie zarezerwowanego miejsca związanego z częścią pliku" #: .././io/prealloc.c:252 msgid "Converts the given range of a file to allocated zeros" msgstr "Zamiana podanego przedziału pliku na przydzielone zera" #: .././io/prealloc.c:266 msgid "[-k] [-p] off len" msgstr "[-k] [-p] offset długość" #: .././io/prealloc.c:268 msgid "allocates space associated with part of a file via fallocate" msgstr "przydzielenie miejsca powiązanego z częścią pliku przez fallocate" #: .././io/prealloc.c:278 msgid "de-allocates space assocated with part of a file via fallocate" msgstr "zwolnienie miejsca powiązanego z częścią pliku przez fallocate" #: .././io/pwrite.c:31 #, c-format msgid "" "\n" " writes a range of bytes (in block size increments) from the given offset\n" "\n" " Example:\n" " 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Writes into a segment of the currently open file, using either a buffer\n" " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" " The writes are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different write pattern is requested.\n" " -S -- use an alternate seed number for filling the write buffer\n" " -i -- input file, source of data to write (used when writing forward)\n" " -d -- open the input file for direct IO\n" " -s -- skip a number of bytes at the start of the input file\n" " -w -- call fdatasync(2) at the end (included in timing results)\n" " -W -- call fsync(2) at the end (included in timing results)\n" " -B -- write backwards through the range from offset (backwards N bytes)\n" " -F -- write forwards through the range of bytes from offset (default)\n" " -R -- write at random offsets in the specified range of bytes\n" " -Z N -- zeed the random number generator (used when writing randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" "\n" msgstr "" "\n" " zapisanie przedziału bajtów w podanym rozmiarze bloku od podanego offsetu\n" "\n" " Przykład:\n" " 'pwrite 512 20' - zapisanie 20 bajtów odczytanych od 512 bajtu w pliku\n" "\n" " pwrite zapisuje segment aktualnie otwartego pliku, używając bufora wypełnionego\n" " ustawionym wzorcem (0xcdcdcdcd) lub danymi odczytanymi z pliku wejściowego.\n" " Zapisy są wykonywane sekwencyjnie blokami począwszy od offsetu z rozmiarem\n" " bloku ustawianym przy użyciu opcji -b (domyślny rozmiar bloku to 4096 bajtów),\n" " chyba że zażądano innego schematu.\n" " -S - użycie innej liczby do wypełnienia bufora zapisu\n" " -i - plik wejściowy, źródło danych do zapisania (przy pisaniu od przodu)\n" " -d - otwarcie pliku wejściowego dla bezpośredniego we/wy\n" " -s - pominięcie podanej liczby bajtów od początku pliku wejściowego\n" " -w - wywołanie fdatasync(2) na końcu (wliczane w wyniki czasowe)\n" " -W - wywołanie fsync(2) na końcu (wliczane w wyniki czasowe)\n" " -B - zapis przedziału od tyłu począwszy od offsetu (N bajtów do tyłu)\n" " -F - zapis przedziału od przodu począwszy od offsetu (domyślny)\n" " -R - zapis losowych offsetów z przedziału bajtów\n" " -Z N - (\"zeed\") nakarmienie generatora liczb losowych (przy zapisie losowym)\n" " (nieztety opcje -s/-S pasujące do \"seed\" były już zajęte w pwrite)\n" "\n" #: .././io/pwrite.c:244 #, c-format msgid "non-numeric skip -- %s\n" msgstr "nieliczbowy liczba bajtów do pominięcia - %s\n" #: .././io/pwrite.c:334 #, c-format msgid "wrote %lld/%lld bytes at offset %lld\n" msgstr "zapisano %lld/%lld bajtów od offsetu %lld\n" #: .././io/pwrite.c:359 msgid "[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] off len" msgstr "[-i plik_wej [-d] [-s do_pominięcia]] [-b rozm_bloku] [-S zarodek] [-wW] offset długość" #: .././io/pwrite.c:361 msgid "writes a number of bytes at a specified offset" msgstr "zapis podanej liczby bajtów od podanego offsetu" #: .././io/resblks.c:39 #, c-format msgid "non-numeric argument -- %s\n" msgstr "nieliczbowy argument - %s\n" #: .././io/resblks.c:51 #, c-format msgid "reserved blocks = %llu\n" msgstr "zarezerwowane bloki = %llu\n" #: .././io/resblks.c:53 #, c-format msgid "available reserved blocks = %llu\n" msgstr "dostępne zarezerwowane bloki = %llu\n" #: .././io/resblks.c:66 msgid "[blocks]" msgstr "[bloki]" #: .././io/resblks.c:68 msgid "get and/or set count of reserved filesystem blocks" msgstr "pobranie i/lub ustawienie liczby zarezerwowanych bloków w systemie plików" #: .././io/sendfile.c:32 #, c-format msgid "" "\n" " transfer a range of bytes from the given offset between files\n" "\n" " Example:\n" " 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Copies data between one file descriptor and another. Because this copying\n" " is done within the kernel, sendfile does not need to transfer data to and\n" " from user space.\n" " -f -- specifies an input file from which to source data to write\n" " -i -- specifies an input file name from which to source data to write.\n" " An offset and length in the source file can be optionally specified.\n" "\n" msgstr "" "\n" " przesłanie między plikami przedziału bajtów od podanego offsetu\n" "\n" " Przykład:\n" " 'send -f 2 512 20' - zapisanie 20 bajtów od 512 bajtu do otwartego pliku\n" "\n" " sendfile kopiuje dane między jednym deskryptorem pliku a innym. Ponieważ to\n" " kopiowanie jest wykonywane przez jądro, sendfile nie potrzebuje przesyłać\n" " danych do i z przestrzeni użytkownika.\n" " -f - podanie plików wejściowego z którego dane mają być czytane\n" " -i - podanie nazwy pliku wejściowego z którego dane mają być czytane\n" " Opcjonalnie można podać offset i długość danych w pliku źródłowym.\n" "\n" #: .././io/sendfile.c:161 #, c-format msgid "sent %lld/%lld bytes from offset %lld\n" msgstr "przesłano %lld/%lld bajtów od offsetu %lld\n" #: .././io/sendfile.c:186 msgid "-i infile | -f N [off len]" msgstr "-i plik_wej | -f N [offset długość]" #: .././io/sendfile.c:188 msgid "Transfer data directly between file descriptors" msgstr "Przesłanie danych bezpośrednio między deskryptorami plików" #: .././io/shutdown.c:59 msgid "[-f]" msgstr "[-f]" #: .././io/shutdown.c:61 msgid "shuts down the filesystem where the current file resides" msgstr "wyłączenie systemu plików na którym znajduje się bieżący plik" #: .././io/truncate.c:38 #, c-format msgid "non-numeric truncate argument -- %s\n" msgstr "nieliczbowy argument truncate - %s\n" #: .././io/truncate.c:58 msgid "off" msgstr "offset" #: .././io/truncate.c:60 msgid "truncates the current file at the given offset" msgstr "ucięcie bieżącego pliku na podanym offsecie" #: .././io/attr.c:59 #, c-format msgid "" "\n" " displays the set of extended inode flags associated with the current file\n" "\n" " Each individual flag is displayed as a single character, in this order:\n" " r -- file data is stored in the realtime section\n" " p -- file has preallocated extents (cannot be changed using chattr)\n" " i -- immutable, file cannot be modified\n" " a -- append-only, file can only be appended to\n" " s -- all updates are synchronous\n" " A -- the access time is not updated for this inode\n" " d -- do not include this file in a dump of the filesystem\n" " t -- child created in this directory has realtime bit set by default\n" " P -- child created in this directory has parents project ID by default\n" " n -- symbolic links cannot be created in this directory\n" " e -- for non-realtime files, observe the inode extent size value\n" " E -- children created in this directory inherit the extent size value\n" " f -- do not include this file when defragmenting the filesystem\n" " S -- enable filestreams allocator for this directory\n" "\n" " Options:\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, but only list attributes on directories\n" " -a -- show all flags which can be set alongside those which are set\n" " -v -- verbose mode; show long names of flags, not single characters\n" "\n" msgstr "" "\n" " wyświetlanie zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" "\n" " Każda flaga jest wyświetlana jako pojedynczy znak, w tej kolejności:\n" " r - dane pliku są zapisane w sekcji realtime\n" " p - plik ma już przydzielone ekstenty (nie do zmiany przez chattr)\n" " i - niezmienny, pliku nie można modyfikować\n" " a - tylko do dopisywania, do pliku można tylko dopisywać\n" " s - wszystkie uaktualnienia są synchroniczne\n" " A - czas dostępu nie jest uaktualniany dla tego i-węzła\n" " d - nie dołączanie pliku do zrzutu systemu plików\n" " t - wpisy tworzone w tym katalogu mają domyślnie ustawiony bit realtime\n" " P - wpisy tworzone w tym katalogu mają domyślnie ID projektu rodzica\n" " n - w tym katalogu nie można tworzyć dowiązań symbolicznych\n" " e - dla plików nie-realtime - przestrzeganie wartości rozmiaru ekstentu i-węzła\n" " E - wpisy tworzone w tym katalogu dziedziczą wartość rozmiaru ekstentu\n" " f - nie uwzględnianie tego pliku przy defragmentacji systemu plików\n" " S - włączenie przydzielania strumieni plikowych dla tego katalogu\n" "\n" " Opcje:\n" " -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" " -D - rekurencyjne zagłębianie się, ale wypisywanie atrybutów tylko katalogów\n" " -a - pokazywanie wszystkich flag, które można ustawić, obok ustawionych\n" " -v - tryb szczegółowy; pokazywanie długich nazw flag zamiast pojedynczych znaków\n" "\n" #: .././io/attr.c:90 #, c-format msgid "" "\n" " modifies the set of extended inode flags associated with the current file\n" "\n" " Examples:\n" " 'chattr +a' - sets the append-only flag\n" " 'chattr -a' - clears the append-only flag\n" "\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, only modifying attributes on directories\n" " +/-r -- set/clear the realtime flag\n" " +/-i -- set/clear the immutable flag\n" " +/-a -- set/clear the append-only flag\n" " +/-s -- set/clear the sync flag\n" " +/-A -- set/clear the no-atime flag\n" " +/-d -- set/clear the no-dump flag\n" " +/-t -- set/clear the realtime inheritance flag\n" " +/-P -- set/clear the project ID inheritance flag\n" " +/-n -- set/clear the no-symbolic-links flag\n" " +/-e -- set/clear the extent-size flag\n" " +/-E -- set/clear the extent-size inheritance flag\n" " +/-f -- set/clear the no-defrag flag\n" " +/-S -- set/clear the filestreams allocator flag\n" " Note1: user must have certain capabilities to modify immutable/append-only.\n" " Note2: immutable/append-only files cannot be deleted; removing these files\n" " requires the immutable/append-only flag to be cleared first.\n" " Note3: the realtime flag can only be set if the filesystem has a realtime\n" " section, and the (regular) file must be empty when the flag is set.\n" "\n" msgstr "" "\n" " zmiana zbioru rozszerzonych flag i-węzłów związanych z bieżącym plikiem\n" "\n" " Przykłady:\n" " 'chattr +a' - ustawia flagę tylko do dopisywania\n" " 'chattr -a' - zdejmuje flagę tylko do dopisywania\n" "\n" " -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" " -D - rekurencyjne zagłębianie się, ale zmiana atrybutów tylko katalogów\n" " +/-r - ustawienie/zdjęcie flagi realtime\n" " +/-i - ustawienie/zdjęcie flagi immutable (niezmienności)\n" " +/-a - ustawienie/zdjęcie flagi append-only (tylko do dopisywania)\n" " +/-s - ustawienie/zdjęcie flagi sync (synchronicznego zapisu)\n" " +/-A - ustawienie/zdjęcie flagi no-atime\n" " +/-d - ustawienie/zdjęcie flagi no-dump\n" " +/-t - ustawienie/zdjęcie flagi dziedziczenia realtime\n" " +/-P - ustawienie/zdjęcie flagi dziedziczenia ID projektu\n" " +/-n - ustawienie/zdjęcie flagi braku dowiązań symbolicznych\n" " +/-e - ustawienie/zdjęcie flagi rozmiaru ekstentu\n" " +/-E - ustawienie/zdjęcie flagi dziedziczenia rozmiaru ekstentu\n" " +/-f - ustawienie/zdjęcie flagi no-defrag\n" " +/-S - ustawienie/zdjęcie flagi przydzielania strumieni plikowych\n" " Uwaga1: użytkownik musi mieć pewne uprawnienia do zmiany flag\n" " immutable/append-only\n" " Uwaga2: plików immutable/append-only nie można usuwać; usuwanie tych plików\n" " wymaga zdjęcia flag immutable/append-only przed usunięciem.\n" " Uwaga3: flagę realtime można ustawić tylko jeśli system plików ma sekcję\n" " realtime i (zwykły) plik musi być pusty przy ustawianiu flagi.\n" "\n" #: .././io/attr.c:256 .././io/attr.c:327 #, c-format msgid "%s: cannot set flags on %s: %s\n" msgstr "%s: nie można ustawić flag %s: %s\n" #: .././io/attr.c:291 .././io/attr.c:305 #, c-format msgid "%s: unknown flag\n" msgstr "%s: nieznana flaga\n" #: .././io/attr.c:311 #, c-format msgid "%s: bad chattr command, not +/-X\n" msgstr "%s: złe polecenie chattr - nie +/-X\n" #: .././io/attr.c:338 msgid "[-R|-D] [+/-" msgstr "[-R|-D] [+/-" #: .././io/attr.c:343 msgid "change extended inode flags on the currently open file" msgstr "zmiana rozszerzonych flag i-węzłów aktualnie otwartego pliku" #: .././io/attr.c:348 msgid "[-R|-D|-a|-v]" msgstr "[-R|-D|-a|-v]" #: .././io/attr.c:353 msgid "list extended inode flags set on the currently open file" msgstr "wypisanie rozszerzonych flag i-węzłów aktualnie otwartego pliku" #: .././io/bmap.c:30 #, c-format msgid "" "\n" " prints the block mapping for an XFS file's data or attribute forks\n" " Example:\n" " 'bmap -vp' - tabular format verbose map, including unwritten extents\n" "\n" " bmap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -p -- obtain all unwritten extents as well (w/ -v show which are unwritten.)\n" " -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" " Note: the bmap for non-regular files can be obtained provided the file\n" " was opened appropriately (in particular, must be opened read-only).\n" "\n" msgstr "" "\n" " wypisanie mapowania bloków dla danych lub atrybutów pliku na XFS-ie\n" " Przykład:\n" " 'bmap -vp' - szczegółowa mapa w formacie tabeli wraz z nie zapisanymi\n" " ekstentami\n" "\n" " bmap wypisuje mapę bloków dysku używanych przez bieżący plik.\n" " Mapa opisuje każdy ekstent użyty przez plik, a także regiony w pliku\n" " nie mające przypisanych bloków (dziury).\n" " Domyślnie każda linia listingu przyjmuje następującą postać:\n" " ekstent: [offsetpocz..offsetkońc]: blokpocz..blokkońc\n" " Dziury są oznaczane przez zastąpienie blokpocz..blokkońc przez 'dziura'.\n" " Wszystkie offsety w plikach i bloki dysku są w jednostkach 512-bajtowych.\n" " -a - wypisanie mapy gałęzi atrybutów zamiast gałęzi danych.\n" " -d - pominięcie zdarzenia odczytu DMAPI, pokazanie części offline jako dziur.\n" " -l - wyświetlenie także długości każdego fragmentu w 512-bajtowych blokach.\n" " -n - odpytanie n ekstentów.\n" " -p - wypisanie także nie zapisanych ekstentów (z -v pokazuje, które są nie\n" " zapisane).\n" " -v - szczegółowe informacje z podaniem informacji ag; legenda drugim -v\n" " Uwaga: bmap dla plików nie będących plikami zwykłymi można uzyskać pod\n" " warunkiem, że plik został otwarty odpowiednio (w szczególności musi być\n" " otwarty tylko do odczytu).\n" "\n" #: .././io/bmap.c:123 #, c-format msgid "%s: can't get geometry [\"%s\"]: %s\n" msgstr "%s: nie można uzyskać geometrii [\"%s\"]: %s\n" #: .././io/bmap.c:131 #, c-format msgid "%s: cannot read attrs on \"%s\": %s\n" msgstr "%s: nie można odczytać atrybutów \"%s\": %s\n" #: .././io/bmap.c:197 #, c-format msgid "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" msgstr "%s: xfsctl(XFS_IOC_GETBMAPX) iflags=0x%x [\"%s\"]: %s\n" #: .././io/bmap.c:228 #, c-format msgid "%s: cannot realloc %d bytes\n" msgstr "%s: nie można wykonać realloc na %d bajtów\n" #: .././io/bmap.c:237 #, c-format msgid "%s: no extents\n" msgstr "%s: brak ekstentów\n" #: .././io/bmap.c:260 #, c-format msgid " %lld blocks\n" msgstr " %lld bloków\n" #: .././io/bmap.c:341 msgid "RT-BLOCK-RANGE" msgstr "ZAKRES-BLOKÓW-RT" #: .././io/bmap.c:342 msgid "AG" msgstr "AG" #: .././io/bmap.c:343 msgid "AG-OFFSET" msgstr "OFFSET-AG" #: .././io/bmap.c:345 msgid " FLAGS" msgstr " FLAGI" #: .././io/bmap.c:413 #, c-format msgid " FLAG Values:\n" msgstr " Wartości FLAG:\n" #: .././io/bmap.c:414 #, c-format msgid " %*.*o Unwritten preallocated extent\n" msgstr " %*.*o Nie zapisany, już przydzielony ekstent\n" #: .././io/bmap.c:416 #, c-format msgid " %*.*o Doesn't begin on stripe unit\n" msgstr " %*.*o Nie zaczyna się od jednostki pasa\n" #: .././io/bmap.c:418 #, c-format msgid " %*.*o Doesn't end on stripe unit\n" msgstr " %*.*o Nie kończy się na jednostce pasa\n" #: .././io/bmap.c:420 #, c-format msgid " %*.*o Doesn't begin on stripe width\n" msgstr " %*.*o Nie zaczyna się na szerokości pasa\n" #: .././io/bmap.c:422 #, c-format msgid " %*.*o Doesn't end on stripe width\n" msgstr " %*.*o Nie kończy się na szerokości pasa\n" #: .././io/bmap.c:438 msgid "[-adlpv] [-n nx]" msgstr "[-adlpv] [-n nx]" #: .././io/bmap.c:439 msgid "print block mapping for an XFS file" msgstr "wypisanie mapowania bloków dla pliku na XFS-ie" #: .././io/fadvise.c:31 #, c-format msgid "" "\n" " advise the page cache about expected I/O patterns on the current file\n" "\n" " Modifies kernel page cache behaviour when operating on the current file.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" " -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" " -r -- expect random page references (POSIX_FADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" " Notes: these interfaces are not supported in Linux kernels before 2.6.\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" "\n" msgstr "" "\n" " doradzenie buforowi stron w sprawie oczekiwanych schematów we/wy na bieżącym\n" " pliku\n" "\n" " fadvise modyfikuje zachowanie bufora stron przy operacjach na bieżącym pliku.\n" " Niektóre polecenia fadvise ([*] poniżej) wymagają podania zakresu.\n" " Bez argumentów zakłada się doradzenie POSIX_FADV_NORMAL.\n" " -d - podane strony nie są wymagane (POSIX_FADV_DONTNEED) [*]\n" " -n - dostęp do danych będzie jednokrotny (POSIX_FADV_NOREUSE) [*]\n" " -r - należy oczekiwać losowych odwołań do stron (POSIX_FADV_RANDOM)\n" " -s - należy oczekiwać sekwencyjnych odwołań do stron (POSIX_FADV_SEQUENTIAL)\n" " -w - podane strony będą potrzebne (POSIX_FADV_WILLNEED) [*]\n" " Uwagi: te interfejsy nie były obsługiwane przez jądra Linuksa przed 2.6.\n" " NORMAL ustawia domyślną wartość czytania z wyprzedzeniem dla pliku.\n" " RANDOM ustawia czytanie z wyprzedzeniem dla pliku na zero.\n" " SEQUENTIAL ustawia podwójną domyślną wartość czytania z wyprzedzeniem.\n" " WILLNEED i NOREUSE są równoznaczne i wymuszają maksymalne czytanie\n" " z wyprzedzeniem.\n" "\n" #: .././io/fadvise.c:122 msgid "[-dnrsw] [off len]" msgstr "[-dnrsw] [offset długość]" #: .././io/fadvise.c:123 msgid "advisory commands for sections of a file" msgstr "polecenia doradcze dla sekcji pliku" #: .././io/fsync.c:59 msgid "calls fsync(2) to flush all in-core file state to disk" msgstr "wywołanie fsync(2) aby zrzucić cały stan pliku z pamięci na dysk" #: .././io/fsync.c:66 msgid "calls fdatasync(2) to flush the files in-core data to disk" msgstr "wywołanie fdatasync(2) aby zrzucić dane pliku z pamięci na dysk" #: .././io/file.c:39 #, c-format msgid "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" msgstr "%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n" #: .././io/file.c:41 msgid "foreign" msgstr "obcy" #: .././io/file.c:41 msgid "xfs" msgstr "xfs" #: .././io/file.c:42 .././io/open.c:82 msgid "sync" msgstr "synchr" #: .././io/file.c:42 .././io/open.c:82 msgid "non-sync" msgstr "niesynchr" #: .././io/file.c:43 .././io/open.c:83 msgid "direct" msgstr "bezpośredni" #: .././io/file.c:43 .././io/open.c:83 msgid "non-direct" msgstr "niebezpośredni" #: .././io/file.c:44 .././io/open.c:84 msgid "read-only" msgstr "tylko do odczytu" #: .././io/file.c:44 .././io/open.c:84 msgid "read-write" msgstr "odczyt i zapis" #: .././io/file.c:45 .././io/open.c:85 msgid ",real-time" msgstr ",real-time" #: .././io/file.c:46 .././io/open.c:86 msgid ",append-only" msgstr ",tylko dopisywanie" #: .././io/file.c:47 .././io/open.c:87 msgid ",non-block" msgstr ",nieblokujący" #: .././io/file.c:99 msgid "set the current file" msgstr "ustawienie bieżącego pliku" #: .././io/file.c:108 msgid "list current open files and memory mappings" msgstr "wypisanie aktualnie otwartych plików i odwzorowań w pamięci" #: .././io/init.c:35 #, c-format msgid "Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n" msgstr "Składnia: %s [-adfmrRstx] [-p program] [-c polecenie]... plik\n" #: .././io/init.c:111 #, c-format msgid "foreign file active, %s command is for XFS filesystems only\n" msgstr "aktywny jest plik obcy, polecenie %s jest tylko dla systemów plików XFS\n" #: .././io/init.c:156 .././io/open.c:295 #, c-format msgid "non-numeric mode -- %s\n" msgstr "tryb nieliczbowy - %s\n" #: .././io/open.c:53 msgid "socket" msgstr "gniazdo" #: .././io/open.c:55 msgid "directory" msgstr "katalog" #: .././io/open.c:57 msgid "char device" msgstr "urządzenie znakowe" #: .././io/open.c:59 msgid "block device" msgstr "urządzenie blokowe" #: .././io/open.c:61 msgid "regular file" msgstr "plik zwykły" #: .././io/open.c:63 msgid "symbolic link" msgstr "dowiązanie symboliczne" #: .././io/open.c:65 msgid "fifo" msgstr "potok" #: .././io/open.c:80 .././io/open.c:719 #, c-format msgid "fd.path = \"%s\"\n" msgstr "fd.path = \"%s\"\n" #: .././io/open.c:81 #, c-format msgid "fd.flags = %s,%s,%s%s%s%s\n" msgstr "fd.flags = %s,%s,%s%s%s%s\n" #: .././io/open.c:91 #, c-format msgid "stat.ino = %lld\n" msgstr "stat.ino = %lld\n" #: .././io/open.c:92 #, c-format msgid "stat.type = %s\n" msgstr "stat.type = %s\n" #: .././io/open.c:93 #, c-format msgid "stat.size = %lld\n" msgstr "stat.size = %lld\n" #: .././io/open.c:94 #, c-format msgid "stat.blocks = %lld\n" msgstr "stat.blocks = %lld\n" #: .././io/open.c:96 #, c-format msgid "stat.atime = %s" msgstr "stat.atime = %s" #: .././io/open.c:97 #, c-format msgid "stat.mtime = %s" msgstr "stat.mtime = %s" #: .././io/open.c:98 #, c-format msgid "stat.ctime = %s" msgstr "stat.ctime = %s" #: .././io/open.c:107 #, c-format msgid "fsxattr.xflags = 0x%x " msgstr "fsxattr.xflags = 0x%x " #: .././io/open.c:109 #, c-format msgid "fsxattr.projid = %u\n" msgstr "fsxattr.projid = %u\n" #: .././io/open.c:110 #, c-format msgid "fsxattr.extsize = %u\n" msgstr "fsxattr.extsize = %u\n" #: .././io/open.c:111 #, c-format msgid "fsxattr.nextents = %u\n" msgstr "fsxattr.nextents = %u\n" #: .././io/open.c:112 #, c-format msgid "fsxattr.naextents = %u\n" msgstr "fsxattr.naextents = %u\n" #: .././io/open.c:117 #, c-format msgid "dioattr.mem = 0x%x\n" msgstr "dioattr.mem = 0x%x\n" #: .././io/open.c:118 #, c-format msgid "dioattr.miniosz = %u\n" msgstr "dioattr.miniosz = %u\n" #: .././io/open.c:119 #, c-format msgid "dioattr.maxiosz = %u\n" msgstr "dioattr.maxiosz = %u\n" #: .././io/open.c:235 #, c-format msgid "" "\n" " opens a new file in the requested mode\n" "\n" " Example:\n" " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" "\n" " Opens a file for subsequent use by all of the other xfs_io commands.\n" " With no arguments, open uses the stat command to show the current file.\n" " -F -- foreign filesystem file, disallow XFS-specific commands\n" " -a -- open with the O_APPEND flag (append-only mode)\n" " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" " -f -- open with O_CREAT (create the file if it doesn't exist)\n" " -m -- permissions to use in case a new file is created (default 0600)\n" " -n -- open with O_NONBLOCK\n" " -r -- open with O_RDONLY, the default is O_RDWR\n" " -s -- open with O_SYNC\n" " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" " -R -- mark the file as a realtime XFS file immediately after opening it\n" " Note1: usually read/write direct IO requests must be blocksize aligned;\n" " some kernels, however, allow sectorsize alignment for direct IO.\n" " Note2: the bmap for non-regular files can be obtained provided the file\n" " was opened correctly (in particular, must be opened read-only).\n" "\n" msgstr "" "\n" " otwarcie nowego pliku w żądanym trybie\n" "\n" " Przykład:\n" " 'open -cd /tmp/data' - utworzenie/otwarcie pliku danych do odczytu i zapisu\n" " z bezpośrednim we/wy\n" "\n" " open otwiera plik do późniejszego wykorzystania przez wszystkie inne polecenia\n" " xfs_io.\n" " Bez argumentów używa polecenia stat do pokazania bieżącego pliku.\n" " -F - plik na obcym systemie plików, zabronienie używania poleceń dla XFS-a\n" " -a - otwarcie z flagą O_APPEND (w trybie tylko dopisywania)\n" " -d - otwarcie z flagą O_DIRECT (niebuforowane we/wy, ograniczenia wyrównania)\n" " -f - otwarcie z flagą O_CREAT (utworzenie pliku jeśli nie istnieje)\n" " -m - uprawnienia do użycia w przypadku tworzenia pliku (domyślnie 0600)\n" " -n - otwarcie z flagą O_NONBLOCK\n" " -r - otwarcie z flagą O_RDONLY (domyślne jest O_RDWR)\n" " -s - otwarcie z flagą O_SYNC\n" " -t - otwarcie z flagą O_TRUNC (ucięcie do zerowej długości jeśli istnieje)\n" " -R - oznaczenie pliku jako realtime na XFS-ie zaraz po otwarciu\n" " Uwaga1: zwykle żądania bezpośredniego we/wy muszą być wyrównane do rozmiaru\n" " bloku; niektóre jądra pozwalają na wyrównanie do rozmiaru sektora\n" " Uwaga2: bmap dla plików innych niż zwykłe można uzyskać pod warunkiem, że\n" " plik zostanie poprawnie otwarty (w szczególności tylko do odczytu).\n" #: .././io/open.c:374 #, c-format msgid "" "\n" " displays the project identifier associated with the current path\n" "\n" " Options:\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, but only list projects on directories\n" "\n" msgstr "" "\n" " wyświetlenie identyfikatora projektu związanego z bieżącą ścieżką\n" "\n" " Opcje:\n" " -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" " -D - rekurencyjne zagłębianie się, ale wypisywanie projektów tylko katalogów\n" "\n" #: .././io/open.c:440 #, c-format msgid "projid = %u\n" msgstr "projid = %u\n" #: .././io/open.c:448 #, c-format msgid "" "\n" " modifies the project identifier associated with the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying projects on directories\n" "\n" msgstr "" "\n" " modyfikacja identyfikatora projektu związanego z bieżącą ścieżką\n" "\n" " -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" " -D - rekurencyjne zagłębianie się, ale zmiana projektów tylko katalogów\n" "\n" #: .././io/open.c:507 #, c-format msgid "invalid project ID -- %s\n" msgstr "nieprawidłowy ID projektu - %s\n" #: .././io/open.c:523 #, c-format msgid "" "\n" " report or modify preferred extent size (in bytes) for the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying extsize on directories\n" "\n" msgstr "" "\n" " odczyt lub zmiana preferowanego rozmiaru ekstentu (w bajtach) dla bieżącej\n" " ścieżki\n" "\n" " -R - rekurencyjne zagłębianie się (przydatne kiedy bieżący plik jest katalogiem)\n" " -D - rekurencyjne zagłębianie się, ale zmiana extsize tylko katalogów\n" "\n" #: .././io/open.c:566 #, c-format msgid "invalid target file type - file %s\n" msgstr "nieprawidłowy rodzaj bliku docelowego - plik %s\n" #: .././io/open.c:652 #, c-format msgid "non-numeric extsize argument -- %s\n" msgstr "nieliczbowy argument extsize - %s\n" #: .././io/open.c:699 #, c-format msgid "invalid setfl argument -- '%c'\n" msgstr "nieprawidłowy argument setfl - '%c'\n" #: .././io/open.c:723 #, c-format msgid "statfs.f_bsize = %lld\n" msgstr "statfs.f_bsize = %lld\n" #: .././io/open.c:724 #, c-format msgid "statfs.f_blocks = %lld\n" msgstr "statfs.f_blocks = %lld\n" #: .././io/open.c:726 #, c-format msgid "statfs.f_frsize = %lld\n" msgstr "statfs.f_frsize = %lld\n" #: .././io/open.c:728 #, c-format msgid "statfs.f_bavail = %lld\n" msgstr "statfs.f_bavail = %lld\n" #: .././io/open.c:730 #, c-format msgid "statfs.f_files = %lld\n" msgstr "statfs.f_files = %lld\n" #: .././io/open.c:731 #, c-format msgid "statfs.f_ffree = %lld\n" msgstr "statfs.f_ffree = %lld\n" #: .././io/open.c:738 #, c-format msgid "geom.bsize = %u\n" msgstr "geom.bsize = %u\n" #: .././io/open.c:739 #, c-format msgid "geom.agcount = %u\n" msgstr "geom.agcount = %u\n" #: .././io/open.c:740 #, c-format msgid "geom.agblocks = %u\n" msgstr "geom.agblocks = %u\n" #: .././io/open.c:741 #, c-format msgid "geom.datablocks = %llu\n" msgstr "geom.datablocks = %llu\n" #: .././io/open.c:743 #, c-format msgid "geom.rtblocks = %llu\n" msgstr "geom.rtblocks = %llu\n" #: .././io/open.c:745 #, c-format msgid "geom.rtextents = %llu\n" msgstr "geom.rtextents = %llu\n" #: .././io/open.c:747 #, c-format msgid "geom.rtextsize = %u\n" msgstr "geom.rtextsize = %u\n" #: .././io/open.c:748 #, c-format msgid "geom.sunit = %u\n" msgstr "geom.sunit = %u\n" #: .././io/open.c:749 #, c-format msgid "geom.swidth = %u\n" msgstr "geom.swidth = %u\n" #: .././io/open.c:754 #, c-format msgid "counts.freedata = %llu\n" msgstr "counts.freedata = %llu\n" #: .././io/open.c:756 #, c-format msgid "counts.freertx = %llu\n" msgstr "counts.freertx = %llu\n" #: .././io/open.c:758 #, c-format msgid "counts.freeino = %llu\n" msgstr "counts.freeino = %llu\n" #: .././io/open.c:760 #, c-format msgid "counts.allocino = %llu\n" msgstr "counts.allocino = %llu\n" #: .././io/open.c:775 msgid "[-acdrstx] [path]" msgstr "[-acdrstx] [ścieżka]" #: .././io/open.c:776 msgid "open the file specified by path" msgstr "otwarcie pliku określonego ścieżką" #: .././io/open.c:784 msgid "[-v]" msgstr "[-v]" #: .././io/open.c:785 msgid "statistics on the currently open file" msgstr "statystyki dla aktualnie otwartego pliku" #: .././io/open.c:793 msgid "close the current open file" msgstr "zamknięcie bieżącego otwartego pliku" #: .././io/open.c:797 msgid "[-adx]" msgstr "[-adx]" #: .././io/open.c:800 msgid "set/clear append/direct flags on the open file" msgstr "ustawienie/zdjęcie flag dopisywania/bezpośredniego we/wy dla otwartego pliku" #: .././io/open.c:806 msgid "statistics on the filesystem of the currently open file" msgstr "statystyki dla systemu plików aktualnie otwartego pliku" #: .././io/open.c:810 msgid "[-D | -R] projid" msgstr "[-D | -R] projid" #: .././io/open.c:815 msgid "change project identifier on the currently open file" msgstr "zmiana identyfikatora projektu aktualnie otwartego pliku" #: .././io/open.c:820 msgid "[-D | -R]" msgstr "[-D | -R]" #: .././io/open.c:825 msgid "list project identifier set on the currently open file" msgstr "wypisanie identyfikatora projektu aktualnie otwartego pliku" #: .././io/open.c:830 msgid "[-D | -R] [extsize]" msgstr "[-D | -R] [rozmiar_fragmentu]" #: .././io/open.c:835 msgid "get/set preferred extent size (in bytes) for the open file" msgstr "pobranie/ustawienie preferowanego rozmiaru ekstentu (w bajtach) dla otwartego pliku" #: .././growfs/xfs_growfs.c:34 #, c-format msgid "" "Usage: %s [options] mountpoint\n" "\n" "Options:\n" "\t-d grow data/metadata section\n" "\t-l grow log section\n" "\t-r grow realtime section\n" "\t-n don't change anything, just show geometry\n" "\t-I allow inode numbers to exceed %d significant bits\n" "\t-i convert log from external to internal format\n" "\t-t alternate location for mount table (/etc/mtab)\n" "\t-x convert log from internal to external format\n" "\t-D size grow data/metadata section to size blks\n" "\t-L size grow/shrink log section to size blks\n" "\t-R size grow realtime section to size blks\n" "\t-e size set realtime extent size to size blks\n" "\t-m imaxpct set inode max percent to imaxpct\n" "\t-V print version information\n" msgstr "" "Składnia: %s [opcje] punkt_montowania\n" "\n" "Opcje:\n" "\t-d powiększenie sekcji danych/metadanych\n" "\t-l powiększenie sekcji logu\n" "\t-r powiększenie sekcji realtime\n" "\t-n bez zmian, tylko pokazanie geometrii\n" "\t-I zezwolenie na przekroczenie %d bitów przez numery i-węzłów\n" "\t-i przekształcenie logu z formatu zewnętrznego na wewnętrzny\n" "\t-t inne położenie tabeli montowań (/etc/mtab)\n" "\t-x przekształcenie logu z formatu wewnętrznego na zewnętrzny\n" "\t-D rozmiar powiększenie sekcji danych/metadanych do rozmiaru w blokach\n" "\t-L rozmiar powiększenie/zmniejszenie sekcji logu do rozmiaru w blokach\n" "\t-R rozmiar powiększenie sekcji realtime do rozmiaru w blokach\n" "\t-e rozmiar stawienie rozmiaru ekstentu realtime na rozmiar w blokach\n" "\t-m imaxpct ustawienie maksymalnego procentu i-węzłów na imaxpct\n" "\t-V wypisanie informacji o wersji\n" #: .././growfs/xfs_growfs.c:68 #, c-format msgid "" "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" msgstr "" "metadane=%-22s isize=%-6u agcount=%u, agsize=%u bloków\n" " =%-22s sectsz=%-5u attr=%u\n" "dane =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u bloków\n" "nazwy =wersja %-14u bsize=%-6u\n" " ascii-ci=%d\n" "log =%-22s bsize=%-6u blocks=%u, wersja=%u\n" " =%-22s sectsz=%-5u sunit=%u bloków, lazy-count=%u\n" "realtime=%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:444 #: .././growfs/xfs_growfs.c:445 msgid "internal" msgstr "wewnętrzny" #: .././growfs/xfs_growfs.c:83 .././growfs/xfs_growfs.c:86 #: .././growfs/xfs_growfs.c:444 .././growfs/xfs_growfs.c:445 msgid "external" msgstr "zewnętrzny" #: .././growfs/xfs_growfs.c:199 #, c-format msgid "%s: %s is not a mounted XFS filesystem\n" msgstr "%s: %s nie jest podmontowanym systemem plików XFS\n" #: .././growfs/xfs_growfs.c:216 #, c-format msgid "%s: specified file [\"%s\"] is not on an XFS filesystem\n" msgstr "%s: podany plik [\"%s\"] nie jest na systemie plików XFS\n" #: .././growfs/xfs_growfs.c:233 #, c-format msgid "%s: cannot determine geometry of filesystem mounted at %s: %s\n" msgstr "%s: nie można określić geometrii systemu plików podmontowanego pod %s: %s\n" #: .././growfs/xfs_growfs.c:268 #, c-format msgid "%s: failed to access data device for %s\n" msgstr "%s: nie udało się uzyskać dostępu do urządzenia z danymi dla %s\n" #: .././growfs/xfs_growfs.c:273 #, c-format msgid "%s: failed to access external log for %s\n" msgstr "%s: nie udało się uzyskać dostępu do zewnętrznego logu dla %s\n" #: .././growfs/xfs_growfs.c:279 #, c-format msgid "%s: failed to access realtime device for %s\n" msgstr "%s: nie udało się uzyskać dostępu do urządzenia realtime dla %s\n" #: .././growfs/xfs_growfs.c:314 #, c-format msgid "data size %lld too large, maximum is %lld\n" msgstr "rozmiar danych %lld zbyt duży, maksymalny to %lld\n" #: .././growfs/xfs_growfs.c:321 #, c-format msgid "data size %lld too small, old size is %lld\n" msgstr "rozmiar danych %lld zbyt mały, stary rozmiar to %lld\n" #: .././growfs/xfs_growfs.c:329 #, c-format msgid "data size unchanged, skipping\n" msgstr "rozmiar danych nie zmieniony, pominięto\n" #: .././growfs/xfs_growfs.c:332 #, c-format msgid "inode max pct unchanged, skipping\n" msgstr "maksymalny procent i-węzłów nie zmieniony, pominięto\n" #: .././growfs/xfs_growfs.c:339 .././growfs/xfs_growfs.c:378 #: .././growfs/xfs_growfs.c:413 #, c-format msgid "%s: growfs operation in progress already\n" msgstr "%s: operacja growfs już trwa\n" #: .././growfs/xfs_growfs.c:343 #, c-format msgid "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n" msgstr "%s: xfsctl XFS_IOC_FSGROWFSDATA nie powiodło się: %s\n" #: .././growfs/xfs_growfs.c:359 #, c-format msgid "realtime size %lld too large, maximum is %lld\n" msgstr "rozmiar realtime %lld zbyt duży, maksymalny to %lld\n" #: .././growfs/xfs_growfs.c:365 #, c-format msgid "realtime size %lld too small, old size is %lld\n" msgstr "rozmiar realtime %lld zbyt mały, stary rozmiar to %lld\n" #: .././growfs/xfs_growfs.c:371 #, c-format msgid "realtime size unchanged, skipping\n" msgstr "rozmiar realtime nie zmieniony, pominięto\n" #: .././growfs/xfs_growfs.c:382 #, c-format msgid "%s: realtime growth not implemented\n" msgstr "%s: powiększanie realtime nie jest zaimplementowane\n" #: .././growfs/xfs_growfs.c:386 #, c-format msgid "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n" msgstr "%s: xfsctl XFS_IOC_FSGROWFSRT nie powiodło się: %s\n" #: .././growfs/xfs_growfs.c:407 #, c-format msgid "log size unchanged, skipping\n" msgstr "rozmiar logu nie zmieniony, pominięto\n" #: .././growfs/xfs_growfs.c:417 #, c-format msgid "%s: log growth not supported yet\n" msgstr "%s: powiększanie logu nie jest jeszcze obsługiwane\n" #: .././growfs/xfs_growfs.c:421 #, c-format msgid "%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n" msgstr "%s: xfsctl XFS_IOC_FSGROWFSLOG nie powiodło się: %s\n" #: .././growfs/xfs_growfs.c:429 #, c-format msgid "%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n" msgstr "%s: xfsctl XFS_IOC_FSGEOMETRY nie powiodło się: %s\n" #: .././growfs/xfs_growfs.c:434 #, c-format msgid "data blocks changed from %lld to %lld\n" msgstr "bloki danych zmienione z %lld na %lld\n" #: .././growfs/xfs_growfs.c:437 #, c-format msgid "inode max percent changed from %d to %d\n" msgstr "maksymalny procent i-węzłów zmieniony z %d na %d\n" #: .././growfs/xfs_growfs.c:440 #, c-format msgid "log blocks changed from %d to %d\n" msgstr "bloki logu zmienione z %d na %d\n" #: .././growfs/xfs_growfs.c:443 #, c-format msgid "log changed from %s to %s\n" msgstr "log zmieniony - był %s, jest %s\n" #: .././growfs/xfs_growfs.c:447 #, c-format msgid "realtime blocks changed from %lld to %lld\n" msgstr "bloki realtime zmienione z %lld na %lld\n" #: .././growfs/xfs_growfs.c:450 #, c-format msgid "realtime extent size changed from %d to %d\n" msgstr "rozmiar ekstentu realtime zmieniony z %d na %d\n" #: .././fsr/xfs_fsr.c:196 #, c-format msgid "%s: cannot read %s\n" msgstr "%s: nie można odczytać %s\n" #: .././fsr/xfs_fsr.c:275 #, c-format msgid "%s: Stats not yet supported for XFS\n" msgstr "%s: statystyki nie są jeszcze obsługiwane dla XFS-a\n" #: .././fsr/xfs_fsr.c:339 #, c-format msgid "%s: could not stat: %s: %s\n" msgstr "%s: nie można wykonać stat: %s: %s\n" #: .././fsr/xfs_fsr.c:358 #, c-format msgid "%s: char special not supported: %s\n" msgstr "%s: urządzenia znakowe nie są obsługiwane: %s\n" #: .././fsr/xfs_fsr.c:364 #, c-format msgid "%s: cannot defragment: %s: Not XFS\n" msgstr "%s: nie można zdefragmentować: %s: to nie jest XFS\n" #: .././fsr/xfs_fsr.c:374 #, c-format msgid "%s: not fsys dev, dir, or reg file, ignoring\n" msgstr "%s: nie jest urządzeniem z systemem plików, katalogiem ani zwykłym plikiem, zignorowano\n" #: .././fsr/xfs_fsr.c:389 #, c-format msgid "" "Usage: %s [-d] [-v] [-n] [-s] [-g] [-t time] [-p passes] [-f leftf] [-m mtab]\n" " %s [-d] [-v] [-n] [-s] [-g] xfsdev | dir | file ...\n" "\n" "Options:\n" " -n Do nothing, only interesting with -v. Not\n" " effective with in mtab mode.\n" " -s\t\tPrint statistics only.\n" " -g Print to syslog (default if stdout not a tty).\n" " -t time How long to run in seconds.\n" " -p passes\tNumber of passes before terminating global re-org.\n" " -f leftoff Use this instead of %s.\n" " -m mtab Use something other than /etc/mtab.\n" " -d Debug, print even more.\n" " -v\t\tVerbose, more -v's more verbose.\n" msgstr "" "Składnia: %s [-d] [-v] [-n] [-s] [-g] [-t czas] [-p przebiegi] [-f leftf] [-m mtab]\n" " %s [-d] [-v] [-n] [-s] [-g] xfsdev | katalog | plik ...\n" "\n" "Opcje:\n" " -n Nie robienie niczego, przydatne tylko z -v.\n" " Nieprzydatne w trybie mtab.\n" " -s Tylko wypisanie statystyk.\n" " -g Pisanie do sysloga (domyślne jeśli stdout to nie tty).\n" " -t czas Czas działania w sekundach.\n" " -p przebiegi Liczba przebiegów przed zakończeniem reorganizacji.\n" " -f leftoff Użycie tego pliku zamiast %s.\n" " -m mtab Użycie pliku innego niż /etc/mtab.\n" " -d Diagnostyka, dużo więcej informacji.\n" " -v Tym więcej szczegółów, im więcej opcji -v.\n" #: .././fsr/xfs_fsr.c:420 #, c-format msgid "could not open mtab file: %s\n" msgstr "nie udało się otworzyć pliku mtab: %s\n" #: .././fsr/xfs_fsr.c:426 .././fsr/xfs_fsr.c:458 #, c-format msgid "out of memory: %s\n" msgstr "brak pamięci: %s\n" #: .././fsr/xfs_fsr.c:449 #, c-format msgid "Skipping %s: not mounted rw\n" msgstr "Pominięto %s: nie zamontowany rw\n" #: .././fsr/xfs_fsr.c:463 #, c-format msgid "out of memory on realloc: %s\n" msgstr "brak pamięci przy realloc: %s\n" #: .././fsr/xfs_fsr.c:474 #, c-format msgid "strdup(%s) failed\n" msgstr "strdup(%s) nie powiodło się\n" #: .././fsr/xfs_fsr.c:484 #, c-format msgid "no rw xfs file systems in mtab: %s\n" msgstr "brak w pliku mtab systemów plików xfs w trybie rw: %s\n" #: .././fsr/xfs_fsr.c:488 #, c-format msgid "Found %d mounted, writable, XFS filesystems\n" msgstr "Liczba znalezionych zamontowanych, zapisywalnych systemów plików XFS: %d\n" #: .././fsr/xfs_fsr.c:518 #, c-format msgid "%s: open failed\n" msgstr "%s: open nie powiodło się\n" #: .././fsr/xfs_fsr.c:533 #, c-format msgid "Can't use %s: mode=0%o own=%d nlink=%d\n" msgstr "Nie można użyć %s: mode=0%o own=%d nlink=%d\n" #: .././fsr/xfs_fsr.c:553 #, c-format msgid "could not read %s, starting with %s\n" msgstr "nie można odczytać %s, rozpoczęcie z %s\n" #: .././fsr/xfs_fsr.c:590 #, c-format msgid "START: pass=%d ino=%llu %s %s\n" msgstr "START: przebieg=%d i-węzeł=%llu %s %s\n" #: .././fsr/xfs_fsr.c:607 #, c-format msgid "Completed all %d passes\n" msgstr "Zakończono wszystkie przebiegi w liczbie %d\n" #: .././fsr/xfs_fsr.c:617 msgid "couldn't fork sub process:" msgstr "nie udało się uruchomić podprocesu:" #: .././fsr/xfs_fsr.c:654 #, c-format msgid "open(%s) failed: %s\n" msgstr "open(%s) nie powiodło się: %s\n" #: .././fsr/xfs_fsr.c:661 #, c-format msgid "write(%s) failed: %s\n" msgstr "write(%s) nie powiodło się: %s\n" #: .././fsr/xfs_fsr.c:668 #, c-format msgid "%s startpass %d, endpass %d, time %d seconds\n" msgstr "%s pocz. przebieg %d, końc. przebieg %d, czas %d sekund\n" #: .././fsr/xfs_fsr.c:690 #, c-format msgid "%s start inode=%llu\n" msgstr "%s pocz. i-węzeł=%llu\n" #: .././fsr/xfs_fsr.c:695 #, c-format msgid "unable to get handle: %s: %s\n" msgstr "nie udało się uzyskać uchwytu: %s: %s\n" #: .././fsr/xfs_fsr.c:701 #, c-format msgid "unable to open: %s: %s\n" msgstr "nie udało się otworzyć: %s: %s\n" #: .././fsr/xfs_fsr.c:707 #, c-format msgid "Skipping %s: could not get XFS geometry\n" msgstr "Pominięto %s: nie można odczytać geometrii XFS\n" #: .././fsr/xfs_fsr.c:739 #, c-format msgid "could not open: inode %llu\n" msgstr "nie udało się otworzyć: i-węzeł %llu\n" #: .././fsr/xfs_fsr.c:769 #, c-format msgid "%s: xfs_bulkstat: %s\n" msgstr "%s: xfs_bulkstat: %s\n" #: .././fsr/xfs_fsr.c:795 #, c-format msgid "%s: Directory defragmentation not supported\n" msgstr "%s: Defragmentacja katalogów nie jest obsługiwana\n" #: .././fsr/xfs_fsr.c:814 #, c-format msgid "unable to construct sys handle for %s: %s\n" msgstr "nie udało się utworzyć uchwytu systemowego dla %s: %s\n" #: .././fsr/xfs_fsr.c:825 #, c-format msgid "unable to open sys handle for %s: %s\n" msgstr "nie udało się otworzyć uchwytu systemowego dla %s: %s\n" #: .././fsr/xfs_fsr.c:831 #, c-format msgid "unable to get bstat on %s: %s\n" msgstr "nie udało się uzyskać bstat na %s: %s\n" #: .././fsr/xfs_fsr.c:839 #, c-format msgid "unable to open handle %s: %s\n" msgstr "nie udało się otworzyć uchwytu %s: %s\n" #: .././fsr/xfs_fsr.c:847 #, c-format msgid "Unable to get geom on fs for: %s\n" msgstr "Nie udało się odczytać geometrii systemu plików dla: %s\n" #: .././fsr/xfs_fsr.c:896 #, c-format msgid "sync failed: %s: %s\n" msgstr "sync nie powiodło się: %s: %s\n" #: .././fsr/xfs_fsr.c:902 #, c-format msgid "%s: zero size, ignoring\n" msgstr "%s: zerowy rozmiar, zignorowano\n" #: .././fsr/xfs_fsr.c:921 #, c-format msgid "locking check failed: %s\n" msgstr "sprawdzenie blokowania nie powiodło się: %s\n" #: .././fsr/xfs_fsr.c:928 #, c-format msgid "mandatory lock: %s: ignoring\n" msgstr "obowiązkowa blokada: %s: zignorowano\n" #: .././fsr/xfs_fsr.c:941 #, c-format msgid "unable to get fs stat on %s: %s\n" msgstr "nie udało się uzyskać stat fs na %s: %s\n" #: .././fsr/xfs_fsr.c:948 #, c-format msgid "insufficient freespace for: %s: size=%lld: ignoring\n" msgstr "niewystarczająca ilość miejsca dla: %s: rozmiar=%lld: zignorowano\n" #: .././fsr/xfs_fsr.c:955 #, c-format msgid "failed to get inode attrs: %s\n" msgstr "nie udało się uzyskać atrybutów i-węzła: %s\n" #: .././fsr/xfs_fsr.c:960 #, c-format msgid "%s: immutable/append, ignoring\n" msgstr "%s: niezmienny/tylko do dołączania, zignorowano\n" #: .././fsr/xfs_fsr.c:965 #, c-format msgid "%s: marked as don't defrag, ignoring\n" msgstr "%s: oznaczony jako nie do defragmentacji, zignorowano\n" #: .././fsr/xfs_fsr.c:971 #, c-format msgid "cannot get realtime geometry for: %s\n" msgstr "nie można uzyskać geometrii realtime dla: %s\n" #: .././fsr/xfs_fsr.c:976 #, c-format msgid "low on realtime free space: %s: ignoring file\n" msgstr "mało wolnego miejsca realtime: %s: plik zignorowany\n" #: .././fsr/xfs_fsr.c:983 #, c-format msgid "cannot open: %s: Permission denied\n" msgstr "nie można otworzyć: %s: brak uprawnień\n" #: .././fsr/xfs_fsr.c:1040 .././fsr/xfs_fsr.c:1085 .././fsr/xfs_fsr.c:1131 msgid "could not set ATTR\n" msgstr "nie udało się ustawić ATTR\n" #: .././fsr/xfs_fsr.c:1049 #, c-format msgid "unable to stat temp file: %s\n" msgstr "nie udało się wykonać stat na pliku tymczasowym: %s\n" #: .././fsr/xfs_fsr.c:1068 #, c-format msgid "unable to get bstat on temp file: %s\n" msgstr "nie udało się uzyskać bstat pliku tymczasowego: %s\n" #: .././fsr/xfs_fsr.c:1073 #, c-format msgid "orig forkoff %d, temp forkoff %d\n" msgstr "orig forkoff %d, temp forkoff %d\n" #: .././fsr/xfs_fsr.c:1105 #, c-format msgid "forkoff diff %d too large!\n" msgstr "różnica forkoff %d zbyt duża!\n" #: .././fsr/xfs_fsr.c:1139 msgid "set temp attr\n" msgstr "ustawianie atrybutów pliku tymczasowego\n" #: .././fsr/xfs_fsr.c:1178 #, c-format msgid "%s already fully defragmented.\n" msgstr "%s jest już całkowicie zdefragmentowany.\n" #: .././fsr/xfs_fsr.c:1183 #, c-format msgid "%s extents=%d can_save=%d tmp=%s\n" msgstr "%s extents=%d can_save=%d tmp=%s\n" #: .././fsr/xfs_fsr.c:1189 #, c-format msgid "could not open tmp file: %s: %s\n" msgstr "nie udało się otworzyć pliku tymczasowego: %s: %s\n" #: .././fsr/xfs_fsr.c:1197 #, c-format msgid "failed to set ATTR fork on tmp: %s:\n" msgstr "nie udało się ustawić odgałęzienia ATTR na tmp: %s\n" #: .././fsr/xfs_fsr.c:1205 #, c-format msgid "could not set inode attrs on tmp: %s\n" msgstr "nie udało się ustawić atrybutów i-węzła na tmp: %s\n" #: .././fsr/xfs_fsr.c:1213 #, c-format msgid "could not get DirectIO info on tmp: %s\n" msgstr "nie udało się uzyskać informacji o bezpośrednim we/wy na tmp: %s\n" #: .././fsr/xfs_fsr.c:1229 #, c-format msgid "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" msgstr "DEBUG: fsize=%lld blsz_dio=%d d_min=%d d_max=%d pgsz=%d\n" #: .././fsr/xfs_fsr.c:1236 #, c-format msgid "could not allocate buf: %s\n" msgstr "nie udało się przydzielić bufora: %s\n" #: .././fsr/xfs_fsr.c:1247 #, c-format msgid "could not open fragfile: %s : %s\n" msgstr "nie udało się otworzyć pliku frag: %s: %s\n" #: .././fsr/xfs_fsr.c:1264 #, c-format msgid "could not trunc tmp %s\n" msgstr "nie udało się uciąć tmp %s\n" #: .././fsr/xfs_fsr.c:1279 #, c-format msgid "could not pre-allocate tmp space: %s\n" msgstr "nie udało się wstępnie przydzielić miejsca tmp: %s\n" #: .././fsr/xfs_fsr.c:1290 msgid "Couldn't rewind on temporary file\n" msgstr "Nie udało się przewinąć pliku tymczasowego\n" #: .././fsr/xfs_fsr.c:1299 #, c-format msgid "Temporary file has %d extents (%d in original)\n" msgstr "Plik tymczasowy ma ekstentów: %d (%d w oryginale)\n" #: .././fsr/xfs_fsr.c:1302 #, c-format msgid "No improvement will be made (skipping): %s\n" msgstr "Nie nastąpi poprawa (pominięto): %s\n" #: .././fsr/xfs_fsr.c:1346 #, c-format msgid "bad read of %d bytes from %s: %s\n" msgstr "błędny odczyt %d bajtów z %s: %s\n" #: .././fsr/xfs_fsr.c:1350 .././fsr/xfs_fsr.c:1384 #, c-format msgid "bad write of %d bytes to %s: %s\n" msgstr "błędny zapis %d bajtów do %s: %s\n" #: .././fsr/xfs_fsr.c:1367 #, c-format msgid "bad write2 of %d bytes to %s: %s\n" msgstr "błędny zapis 2 %d bajtów do %s: %s\n" #: .././fsr/xfs_fsr.c:1372 #, c-format msgid "bad copy to %s\n" msgstr "błędna kopia do %s\n" #: .././fsr/xfs_fsr.c:1407 #, c-format msgid "failed to fchown tmpfile %s: %s\n" msgstr "nie udało się wykonać fchown na pliku tymczasowym %s: %s\n" #: .././fsr/xfs_fsr.c:1418 #, c-format msgid "%s: file type not supported\n" msgstr "%s: tym pliku nie obsługiwany\n" #: .././fsr/xfs_fsr.c:1422 #, c-format msgid "%s: file modified defrag aborted\n" msgstr "%s: plik zmodyfikowany, defragmentacja przerwana\n" #: .././fsr/xfs_fsr.c:1427 #, c-format msgid "%s: file busy\n" msgstr "%s: plik zajęty\n" #: .././fsr/xfs_fsr.c:1429 #, c-format msgid "XFS_IOC_SWAPEXT failed: %s: %s\n" msgstr "XFS_IOC_SWAPEXT nie powiodło się: %s: %s\n" #: .././fsr/xfs_fsr.c:1438 #, c-format msgid "extents before:%d after:%d %s %s\n" msgstr "ekstentów przed: %d po: %d %s %s\n" #: .././fsr/xfs_fsr.c:1464 #, c-format msgid "tmp file name too long: %s\n" msgstr "nazwa pliku tymczasowego zbyt długa: %s\n" #: .././fsr/xfs_fsr.c:1513 #, c-format msgid "realloc failed: %s\n" msgstr "realloc nie powiodło się: %s\n" #: .././fsr/xfs_fsr.c:1526 #, c-format msgid "malloc failed: %s\n" msgstr "malloc nie powiodło się: %s\n" #: .././fsr/xfs_fsr.c:1556 #, c-format msgid "failed reading extents: inode %llu" msgstr "nie udało się odczytać ekstentów: i-węzeł %llu" #: .././fsr/xfs_fsr.c:1606 msgid "failed reading extents" msgstr "nie udało się odczytać ekstentów" #: .././fsr/xfs_fsr.c:1694 .././fsr/xfs_fsr.c:1708 #, c-format msgid "tmpdir already exists: %s\n" msgstr "katalog tymczasowy już istnieje: %s\n" #: .././fsr/xfs_fsr.c:1697 #, c-format msgid "could not create tmpdir: %s: %s\n" msgstr "nie udało się utworzyć katalogu tymczasowego: %s: %s\n" #: .././fsr/xfs_fsr.c:1710 #, c-format msgid "cannot create tmpdir: %s: %s\n" msgstr "nie można utworzyć katalogu tymczasowego: %s: %s\n" #: .././fsr/xfs_fsr.c:1748 .././fsr/xfs_fsr.c:1756 #, c-format msgid "could not remove tmpdir: %s: %s\n" msgstr "nie udało się usunąć katalogu tymczasowego: %s: %s\n" #: .././estimate/xfs_estimate.c:76 #, c-format msgid "" "Usage: %s [opts] directory [directory ...]\n" "\t-b blocksize (fundamental filesystem blocksize)\n" "\t-i logsize (internal log size)\n" "\t-e logsize (external log size)\n" "\t-v prints more verbose messages\n" "\t-h prints this usage message\n" "\n" "Note:\tblocksize may have 'k' appended to indicate x1024\n" "\tlogsize may also have 'm' appended to indicate (1024 x 1024)\n" msgstr "" "Składnia: %s [opcje] katalog [katalog ...]\n" "\t-b rozmiar_bloku (rozmiar bloku zasadniczego systemu plików)\n" "\t-i rozmiar_logu (rozmiar logu wewnętrznego)\n" "\t-e rozmiar_logu (rozmiar logu zewnętrznego)\n" "\t-v wypisywanie bardziej szczegółowych komunikatów\n" "\t-h wypisanie tej informacji o sposobie użycia\n" "\n" #: .././estimate/xfs_estimate.c:106 #, c-format msgid "blocksize %llu too small\n" msgstr "rozmiar bloku %llu jest zbyt mały\n" #: .././estimate/xfs_estimate.c:111 #, c-format msgid "blocksize %llu too large\n" msgstr "rozmiar bloku %llu jest zbyt duży\n" #: .././estimate/xfs_estimate.c:118 #, c-format msgid "already have external log noted, can't have both\n" msgstr "już jest przypisany zewnętrzny log, nie mogą istnieć oba\n" #: .././estimate/xfs_estimate.c:127 #, c-format msgid "already have internal log noted, can't have both\n" msgstr "już jest przypisany wewnętrzny log, nie mogą istnieć oba\n" #: .././estimate/xfs_estimate.c:157 #, c-format msgid "directory bsize blocks megabytes logsize\n" msgstr "katalog rozmb bloków megabajtów rozm.logu\n" #: .././estimate/xfs_estimate.c:171 #, c-format msgid "dirsize=%llu\n" msgstr "dirsize=%llu\n" #: .././estimate/xfs_estimate.c:172 #, c-format msgid "fullblocks=%llu\n" msgstr "fullblocks=%llu\n" #: .././estimate/xfs_estimate.c:173 #, c-format msgid "isize=%llu\n" msgstr "isize=%llu\n" #: .././estimate/xfs_estimate.c:175 #, c-format msgid "%llu regular files\n" msgstr "%llu plików zwykłych\n" #: .././estimate/xfs_estimate.c:176 #, c-format msgid "%llu symbolic links\n" msgstr "%llu dowiązań symbolicznych\n" #: .././estimate/xfs_estimate.c:177 #, c-format msgid "%llu directories\n" msgstr "%llu katalogów\n" #: .././estimate/xfs_estimate.c:178 #, c-format msgid "%llu special files\n" msgstr "%llu plików specjalnych\n" #: .././estimate/xfs_estimate.c:191 #, c-format msgid "%s will take about %.1f megabytes\n" msgstr "%s zajmie około %.1f megabajtów\n" #: .././estimate/xfs_estimate.c:198 #, c-format msgid "%-39s %5llu %8llu %10.1fMB %10llu\n" msgstr "%-39s %5llu %8llu %10.1fMB %10llu\n" #: .././estimate/xfs_estimate.c:204 #, c-format msgid "\twith the external log using %llu blocks " msgstr "\tz zewnętrznym logiem zajmującym %llu bloków " #: .././estimate/xfs_estimate.c:206 #, c-format msgid "or about %.1f megabytes\n" msgstr "lub około %.1f megabajtów\n" #: .././db/convert.c:171 #, c-format msgid "bad argument count %d to convert, expected 3,5,7,9 arguments\n" msgstr "błędna liczba argumentów %d do konwersji, oczekiwano 3,5,7,9 argumentów\n" #: .././db/convert.c:176 .././db/convert.c:183 #, c-format msgid "unknown conversion type %s\n" msgstr "nieznany rodzaj konwersji %s\n" #: .././db/convert.c:187 msgid "result type same as argument\n" msgstr "typ wyniku taki sam jak argument\n" #: .././db/convert.c:191 #, c-format msgid "conflicting conversion type %s\n" msgstr "konflikt typu konwersji %s\n" #: .././db/convert.c:270 #, c-format msgid "%s is not a number\n" msgstr "%s nie jest liczbą\n" #: .././db/check.c:372 msgid "free block usage information" msgstr "informacje o wykorzystaniu wolnych bloków" #: .././db/check.c:375 msgid "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." msgstr "[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..." #: .././db/check.c:376 msgid "get block usage and check consistency" msgstr "uzyskanie informacji o wykorzystaniu bloków i sprawdzenie spójności" #: .././db/check.c:379 msgid "[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..." msgstr "[-n liczba] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t typ] ..." #: .././db/check.c:380 msgid "trash randomly selected block(s)" msgstr "zaśmiecenie losowo wybranych bloków" #: .././db/check.c:383 msgid "[-n] [-c blockcount]" msgstr "[-n] [-c liczba-bloków]" #: .././db/check.c:384 msgid "print usage for current block(s)" msgstr "wypisanie wykorzystania bieżących bloków" #: .././db/check.c:387 msgid "[-s] [-i ino] ..." msgstr "[-s] [-i ino] ..." #: .././db/check.c:388 msgid "print inode-name pairs" msgstr "wypisanie par i-węzeł - nazwa" #: .././db/check.c:408 #, c-format msgid "-i %lld bad inode number\n" msgstr "-i %lld - błędny numer i-węzła\n" #: .././db/check.c:420 #, c-format msgid "inode %lld add link, now %u\n" msgstr "i-węzeł %lld - dodano dowiązanie, teraz %u\n" #: .././db/check.c:447 #, c-format msgid "inode %lld parent %lld\n" msgstr "i-węzeł %lld - rodzic %lld\n" #: .././db/check.c:760 msgid "block usage information not allocated\n" msgstr "informacja o wykorzystaniu bloków nie przydzielona\n" #: .././db/check.c:798 msgid "already have block usage information\n" msgstr "już istnieje informacja o wykorzystaniu bloków\n" #: .././db/check.c:814 .././db/check.c:922 msgid "WARNING: this may be a newer XFS filesystem.\n" msgstr "UWAGA: to może być nowszy system plików XFS.\n" #: .././db/check.c:850 #, c-format msgid "sb_icount %lld, counted %lld\n" msgstr "sb_icount %lld, naliczono %lld\n" #: .././db/check.c:856 #, c-format msgid "sb_ifree %lld, counted %lld\n" msgstr "sb_ifree %lld, naliczono %lld\n" #: .././db/check.c:862 #, c-format msgid "sb_fdblocks %lld, counted %lld\n" msgstr "sb_fdblocks %lld, naliczono %lld\n" #: .././db/check.c:868 #, c-format msgid "sb_fdblocks %lld, aggregate AGF count %lld\n" msgstr "sb_fdblocks %lld, łączny licznik AGF %lld\n" #: .././db/check.c:874 #, c-format msgid "sb_frextents %lld, counted %lld\n" msgstr "sb_frextents %lld, naliczono %lld\n" #: .././db/check.c:881 #, c-format msgid "sb_features2 (0x%x) not same as sb_bad_features2 (0x%x)\n" msgstr "sb_features2 (0x%x) różni się od sb_bad_features2 (0x%x)\n" #: .././db/check.c:890 #, c-format msgid "sb versionnum missing attr bit %x\n" msgstr "sb versionnum - brak bitu atrybutu %x\n" #: .././db/check.c:897 #, c-format msgid "sb versionnum missing nlink bit %x\n" msgstr "sb versionnum - brak bitu nlink %x\n" #: .././db/check.c:904 #, c-format msgid "sb versionnum missing quota bit %x\n" msgstr "sb versionnum - brak bitu quota %x\n" #: .././db/check.c:911 #, c-format msgid "sb versionnum extra align bit %x\n" msgstr "sb versionnum - nadmiarowy bit align %x\n" #: .././db/check.c:951 msgid "zeroed" msgstr "wyzerowano" #: .././db/check.c:951 msgid "set" msgstr "ustawiono" #: .././db/check.c:951 msgid "flipped" msgstr "przełączono" #: .././db/check.c:951 msgid "randomized" msgstr "ulosowiono" #: .././db/check.c:961 #, c-format msgid "can't read block %u/%u for trashing\n" msgstr "nie można odczytać bloku %u/%u w celu zaśmiecenia\n" #: .././db/check.c:991 #, c-format msgid "blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n" msgstr "blocktrash: %u/%u %s blok %d bit%s początek %d:%d %s\n" #: .././db/check.c:1023 .././db/check.c:1180 msgid "must run blockget first\n" msgstr "najpierw trzeba wykonać blockget\n" #: .././db/check.c:1067 #, c-format msgid "bad blocktrash count %s\n" msgstr "błędna liczba bloków do zaśmiecenia %s\n" #: .././db/check.c:1081 #, c-format msgid "bad blocktrash type %s\n" msgstr "błędny typ zaśmiecania %s\n" #: .././db/check.c:1090 #, c-format msgid "bad blocktrash min %s\n" msgstr "błędny początek zaśmiecania %s\n" #: .././db/check.c:1098 #, c-format msgid "bad blocktrash max %s\n" msgstr "błędny koniec zaśmiecania %s\n" #: .././db/check.c:1103 msgid "bad option for blocktrash command\n" msgstr "błędna opcja polecenia blocktrash\n" #: .././db/check.c:1108 msgid "bad min/max for blocktrash command\n" msgstr "błędny początek/koniec polecenia blocktrash\n" #: .././db/check.c:1134 msgid "blocktrash: no matching blocks\n" msgstr "blocktrash: brak pasujących bloków\n" #: .././db/check.c:1138 #, c-format msgid "blocktrash: seed %u\n" msgstr "blocktash: zarodek %u\n" #: .././db/check.c:1196 #, c-format msgid "bad blockuse count %s\n" msgstr "błędna liczba bloków dla blockuse: %s\n" #: .././db/check.c:1202 .././db/check.c:1887 msgid "must run blockget -n first\n" msgstr "najpierw trzeba wykonać blockget -n\n" #: .././db/check.c:1208 msgid "bad option for blockuse command\n" msgstr "błędna opcja dla polecenia blockuse\n" #: .././db/check.c:1215 #, c-format msgid "block %llu (%u/%u) type %s" msgstr "blok %llu (%u/%u) typu %s" #: .././db/check.c:1219 #, c-format msgid " inode %lld" msgstr " i-węzeł %lld" #: .././db/check.c:1257 #, c-format msgid "block %u/%u expected type %s got %s\n" msgstr "blok %u/%u: oczekiwano typu %s, otrzymano %s\n" #: .././db/check.c:1289 #, c-format msgid "blocks %u/%u..%u claimed by inode %lld\n" msgstr "blok %u/%u..%u przypisany do i-węzła %lld\n" #: .././db/check.c:1297 #, c-format msgid "block %u/%u claimed by inode %lld, previous inum %lld\n" msgstr "blok %u/%u przypisany do i-węzła %lld, poprzedni inum %lld\n" #: .././db/check.c:1326 #, c-format msgid "link count mismatch for inode %lld (name %s), nlink %d, counted %d\n" msgstr "niezgodność liczby dowiązań dla i-węzła %lld (nazwa %s), nlink %d, naliczono %d\n" #: .././db/check.c:1334 #, c-format msgid "disconnected inode %lld, nlink %d\n" msgstr "odłączony i-węzeł %lld, nlink %d\n" #: .././db/check.c:1338 #, c-format msgid "allocated inode %lld has 0 link count\n" msgstr "przydzielony i-węzeł %lld ma zerową liczbę dowiązań\n" #: .././db/check.c:1348 #, c-format msgid "inode %lld name %s\n" msgstr "i-węzeł %lld o nazwie %s\n" #: .././db/check.c:1382 .././db/check.c:1397 #, c-format msgid "block %u/%u out of range\n" msgstr "blok %u/%u poza zakresem\n" #: .././db/check.c:1385 .././db/check.c:1400 #, c-format msgid "blocks %u/%u..%u out of range\n" msgstr "bloki %u/%u..%u poza zakresem\n" #: .././db/check.c:1423 #, c-format msgid "rtblock %llu expected type %s got %s\n" msgstr "rtblok %llu - oczekiwano typu %s, otrzymano %s\n" #: .././db/check.c:1443 #, c-format msgid "rtblocks %llu..%llu claimed by inode %lld\n" msgstr "rtbloki %llu..%llu przypisane do i-węzła %lld\n" #: .././db/check.c:1452 #, c-format msgid "rtblock %llu claimed by inode %lld, previous inum %lld\n" msgstr "rtblok %llu przypisany do i-węzłą %lld, poprzedni inum %lld\n" #: .././db/check.c:1470 #, c-format msgid "root inode %lld is missing\n" msgstr "brak głównego i-węzła %lld\n" #: .././db/check.c:1475 #, c-format msgid "root inode %lld is not a directory\n" msgstr "główny i-węzeł %lld nie jest katalogiem\n" #: .././db/check.c:1491 #, c-format msgid "rtblock %llu out of range\n" msgstr "rtblok %llu poza zakresem\n" #: .././db/check.c:1515 #, c-format msgid "blocks %u/%u..%u claimed by block %u/%u\n" msgstr "bloki %u/%u..%u przypisane do bloku %u/%u\n" #: .././db/check.c:1524 #, c-format msgid "setting block %u/%u to %s\n" msgstr "ustawianie bloku %u/%u na %s\n" #: .././db/check.c:1547 #, c-format msgid "setting rtblock %llu to %s\n" msgstr "ustawianie rtbloku %llu na %s\n" #: .././db/check.c:1593 #, c-format msgid "block %u/%u type %s not expected\n" msgstr "blok %u/%u typu %s nie oczekiwany\n" #: .././db/check.c:1614 #, c-format msgid "rtblock %llu type %s not expected\n" msgstr "rtblok %llu typu %s nie oczekiwany\n" #: .././db/check.c:1651 #, c-format msgid "dir ino %lld missing leaf entry for %x/%x\n" msgstr "i-węzeł katalogu %lld - brak wpisu liścia dla %x/%x\n" #: .././db/check.c:1770 #, c-format msgid "bad superblock magic number %x, giving up\n" msgstr "błędna liczba magiczna superbloku %x, poddaję się\n" #: .././db/check.c:1824 msgid "bad option for blockget command\n" msgstr "błędna opcja dla polecenia blockget\n" #: .././db/check.c:1904 #, c-format msgid "bad option -%c for ncheck command\n" msgstr "błędna opcja -%c dla polecenia ncheck\n" #: .././db/check.c:1977 .././db/check.c:2946 #, c-format msgid "block 0 for directory inode %lld is missing\n" msgstr "brak bloku 0 dla i-węzła katalogu %lld\n" #: .././db/check.c:1997 .././db/check.c:2957 #, c-format msgid "can't read block 0 for directory inode %lld\n" msgstr "nie można odczytać bloku 0 dla i-węzła katalogu %lld\n" #: .././db/check.c:2043 #, c-format msgid "inode %lld extent [%lld,%lld,%lld,%d]\n" msgstr "ekstent i-węzła %lld [%lld,%lld,%lld,%d]\n" #: .././db/check.c:2046 #, c-format msgid "bmap rec out of order, inode %lld entry %d\n" msgstr "błędna kolejność bmap rec - i-węzeł %lld, wpis %d\n" #: .././db/check.c:2052 #, c-format msgid "inode %lld bad rt block number %lld, offset %lld\n" msgstr "i-węzeł %lld - błędny numer bloku rt %lld, offset %lld\n" #: .././db/check.c:2062 .././db/check.c:2068 #, c-format msgid "inode %lld bad block number %lld [%d,%d], offset %lld\n" msgstr "i-węzeł %lld - błędny numer bloku %lld [%d,%d], offset %lld\n" #: .././db/check.c:2086 .././db/check.c:2100 #, c-format msgid "inode %lld block %lld at offset %lld\n" msgstr "i-węzeł %lld: blok %lld pod offsetem %lld\n" #: .././db/check.c:2127 #, c-format msgid "level for ino %lld %s fork bmap root too large (%u)\n" msgstr "i-węzeł %lld: poziom bmap root odgałęzienia %s zbyt duży (%u)\n" #: .././db/check.c:2139 #, c-format msgid "numrecs for ino %lld %s fork bmap root too large (%u)\n" msgstr "i-węzeł %lld: liczba rekordów bmap root odgałęzienia %s zbyt duża (%u)\n" #: .././db/check.c:2166 #, c-format msgid "extent count for ino %lld %s fork too low (%d) for file format\n" msgstr "i-węzeł %lld: liczba ekstentów dla odgałęzienia %s zbyt mała (%d) dla formatu pliku\n" #: .././db/check.c:2216 .././db/check.c:3297 #, c-format msgid "bad directory data magic # %#x for dir ino %lld block %d\n" msgstr "błędna liczba magiczna danych katalogu %#x dla i-węzła katalogu %lld, blok %d\n" #: .././db/check.c:2233 #, c-format msgid "bad block directory tail for dir ino %lld\n" msgstr "błędny koniec katalogu bloku dla i-węzła katalogu %lld\n" #: .././db/check.c:2278 #, c-format msgid "dir %lld block %d bad free entry at %d\n" msgstr "katalog %lld, blok %d: błędny wolny wpis pod %d\n" #: .././db/check.c:2302 #, c-format msgid "dir %lld block %d zero length entry at %d\n" msgstr "katalog %lld, blok %d: wpis zerowej długości pod %d\n" #: .././db/check.c:2311 #, c-format msgid "dir %lld block %d bad entry at %d\n" msgstr "katalog %lld, blok %d: błędny wpis pod %d\n" #: .././db/check.c:2329 #, c-format msgid "dir %lld block %d entry %*.*s %lld\n" msgstr "katalog %lld, blok %d, wpis %*.*s %lld\n" #: .././db/check.c:2336 #, c-format msgid "dir %lld block %d entry %*.*s bad inode number %lld\n" msgstr "katalog %lld, blokd %d, epis %*.*s: błędny number i-węzła %lld\n" #: .././db/check.c:2346 .././db/check.c:3020 #, c-format msgid "multiple .. entries in dir %lld (%lld, %lld)\n" msgstr "wiele wpisów .. w katalogu %lld (%lld, %lld)\n" #: .././db/check.c:2363 .././db/check.c:3037 #, c-format msgid "dir %lld entry . inode number mismatch (%lld)\n" msgstr "katalog %lld, wpis .: niezgodność numeru i-węzła (%lld)\n" #: .././db/check.c:2376 #, c-format msgid "dir %lld block %d bad count %u\n" msgstr "katalog %lld, blok %d: błędny licznik %u\n" #: .././db/check.c:2387 .././db/check.c:3311 #, c-format msgid "dir %lld block %d extra leaf entry %x %x\n" msgstr "katalog %lld, blok %d: nadmiarowy wpis liścia %x %x\n" #: .././db/check.c:2399 #, c-format msgid "dir %lld block %d bad bestfree data\n" msgstr "katalog %lld, blok %d: błędne dane bestfree\n" #: .././db/check.c:2407 #, c-format msgid "dir %lld block %d bad block tail count %d (stale %d)\n" msgstr "katalog %lld, blok %d: błędny licznik końca bloku %d (stale %d)\n" #: .././db/check.c:2416 #, c-format msgid "dir %lld block %d bad stale tail count %d\n" msgstr "katalog %lld, blok %d: błędny licznik końca stale %d\n" #: .././db/check.c:2422 #, c-format msgid "dir %lld block %d consecutive free entries\n" msgstr "katalog %lld, blok %d: kolejne wolne wpisy\n" #: .././db/check.c:2428 #, c-format msgid "dir %lld block %d entry/unused tag mismatch\n" msgstr "katalog %lld, blok %d: niezgodność znacznika wpis/nieużywany\n" #: .././db/check.c:2481 #, c-format msgid "no . entry for directory %lld\n" msgstr "brak wpisu . dla katalogu %lld\n" #: .././db/check.c:2486 #, c-format msgid "no .. entry for directory %lld\n" msgstr "brak wpisu .. dla katalogu %lld\n" #: .././db/check.c:2490 #, c-format msgid ". and .. same for non-root directory %lld\n" msgstr ". i .. są takie same dla katalogu %lld (nie będącego głównym)\n" #: .././db/check.c:2495 #, c-format msgid "root directory %lld has .. %lld\n" msgstr "główny katalog %lld ma .. %lld\n" #: .././db/check.c:2525 .././db/check.c:2560 #, c-format msgid "bad size (%lld) or format (%d) for directory inode %lld\n" msgstr "błędny rozmiar (%lld) lub format (%d) dla i-węzła katalogu %lld\n" #: .././db/check.c:2588 #, c-format msgid "bad number of extents %d for inode %lld\n" msgstr "błędna liczba ekstentów %d dla i-węzła %lld\n" #: .././db/check.c:2660 #, c-format msgid "bad magic number %#x for inode %lld\n" msgstr "błędna liczba magiczna %#x dla i-węzła %lld\n" #: .././db/check.c:2667 #, c-format msgid "bad version number %#x for inode %lld\n" msgstr "błędny numer wersji %#x dla i-węzła %lld\n" #: .././db/check.c:2675 #, c-format msgid "bad nblocks %lld for free inode %lld\n" msgstr "błędna liczba bloków %lld dla wolnego i-węzła %lld\n" #: .././db/check.c:2686 #, c-format msgid "bad nlink %d for free inode %lld\n" msgstr "błądna liczba dowiązań %d dla wolnego i-węzła %lld\n" #: .././db/check.c:2692 #, c-format msgid "bad mode %#o for free inode %lld\n" msgstr "błędne uprawnienia %#o dla wolnego i-węzła %lld\n" #: .././db/check.c:2701 #, c-format msgid "bad next unlinked %#x for inode %lld\n" msgstr "błędny następny niedowiązany %#x dla i-węzła %lld\n" #: .././db/check.c:2711 #, c-format msgid "bad format %d for inode %lld type %#o\n" msgstr "błędny format %d dla i-węzła %lld typu %#o\n" #: .././db/check.c:2718 #, c-format msgid "bad fork offset %d for inode %lld\n" msgstr "błędny offset odgałęzienia %d dla i-węzła %lld\n" #: .././db/check.c:2725 #, c-format msgid "bad attribute format %d for inode %lld\n" msgstr "błędny format atrybutu %d dla i-węzła %lld\n" #: .././db/check.c:2731 #, c-format msgid "inode %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" msgstr "i-węzeł %lld mode %#o fmt %s afmt %s nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n" #: .././db/check.c:2851 #, c-format msgid "bad nblocks %lld for inode %lld, counted %lld\n" msgstr "błędna liczba bloków %lld dla i-węzła %lld, naliczono %lld\n" #: .././db/check.c:2858 #, c-format msgid "bad nextents %d for inode %lld, counted %d\n" msgstr "błędna liczba ekstentów %d dla i-węzła %lld, naliczono %d\n" #: .././db/check.c:2864 #, c-format msgid "bad anextents %d for inode %lld, counted %d\n" msgstr "błędne anextents %d dla i-węzła %lld, naliczono %d\n" #: .././db/check.c:2916 #, c-format msgid "local inode %lld data is too large (size %lld)\n" msgstr "dane lokalnego i-węzła %lld zbyt duże (rozmiar %lld)\n" #: .././db/check.c:2925 #, c-format msgid "local inode %lld attr is too large (size %d)\n" msgstr "atrybuty lokalnego i-węzła %lld zbyt duże (rozmiar %d)\n" #: .././db/check.c:2990 #, c-format msgid "bad directory leaf magic # %#x for dir ino %lld\n" msgstr "błędna liczba magiczna liścia katalogu %#x dla i-węzła katalogu %lld\n" #: .././db/check.c:3003 .././db/check.c:3768 #, c-format msgid "dir %lld entry %*.*s %lld\n" msgstr "katalog %lld wpis %*.*s %lld\n" #: .././db/check.c:3010 .././db/check.c:3664 .././db/check.c:3756 #, c-format msgid "dir %lld entry %*.*s bad inode number %lld\n" msgstr "katalog %lld wpis %*.*s: błędny numer i-węzła %lld\n" #: .././db/check.c:3089 .././db/check.c:3358 #, c-format msgid "dir inode %lld block %u=%llu\n" msgstr "i-węzeł katalogu %lld, blok %u=%llu\n" #: .././db/check.c:3101 .././db/check.c:3368 #, c-format msgid "can't read block %u for directory inode %lld\n" msgstr "nie można odczytać bloku %u dla i-węzła katalogu %lld\n" #: .././db/check.c:3115 .././db/check.c:3381 #, c-format msgid "multiple .. entries in dir %lld\n" msgstr "wiele wpisów .. w katalogu %lld\n" #: .././db/check.c:3137 #, c-format msgid "missing free index for data block %d in dir ino %lld\n" msgstr "brak indeksu wolnego miejsca dla bloku danych %d w i-węźle katalogu %lld\n" #: .././db/check.c:3163 #, c-format msgid "bad free block magic # %#x for dir ino %lld block %d\n" msgstr "błędna liczba magiczna wolnego bloku %#x dla i-węzła katalogu %lld, blok %d\n" #: .././db/check.c:3173 #, c-format msgid "bad free block firstdb %d for dir ino %lld block %d\n" msgstr "błędne firstdb wolnego bloku %d dla i-węzła katalogu %lld, blok %d\n" #: .././db/check.c:3186 #, c-format msgid "bad free block nvalid/nused %d/%d for dir ino %lld block %d\n" msgstr "błędne liczby nvalid/nused (%d/%d) wolnych bloków w i-węźle katalogu %lld, blok %d\n" #: .././db/check.c:3200 #, c-format msgid "bad free block ent %d is %d should be %d for dir ino %lld block %d\n" msgstr "błędna liczba ent %d (równa %d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" #: .././db/check.c:3214 #, c-format msgid "bad free block nused %d should be %d for dir ino %lld block %d\n" msgstr "błędna liczba nused (%d, powinna być %d) wolnego bloku w i-węźle katalogu %lld, blok %d\n" #: .././db/check.c:3243 #, c-format msgid "bad leaf block forw/back pointers %d/%d for dir ino %lld block %d\n" msgstr "błędne wskaźniki przód/tył (%d/%d) bloku liścia w i-węźle katalogu %lld, blok %d\n" #: .././db/check.c:3252 #, c-format msgid "single leaf block for dir ino %lld block %d should be at block %d\n" msgstr "blok pojedynczego liścia dla i-węzłu katalogu %lld, blok %d powinien być w bloku %d\n" #: .././db/check.c:3264 #, c-format msgid "bestfree %d for dir ino %lld block %d doesn't match table value %d\n" msgstr "bestfree %d dla i-węzła katalogu %lld, blok %d nie zgadza się z wartością w tablicy %d\n" #: .././db/check.c:3288 #, c-format msgid "bad node block level %d for dir ino %lld block %d\n" msgstr "błędny poziom bloku węzła %d dla i-węzła katalogu %lld, blok %d\n" #: .././db/check.c:3320 #, c-format msgid "dir %lld block %d stale mismatch %d/%d\n" msgstr "katalog %lld, blok %d: niezgodność liczby stale %d/%d\n" #: .././db/check.c:3352 #, c-format msgid "can't read root block for directory inode %lld\n" msgstr "nie można odczytać głównego bloku dla i-węzła katalogu %lld\n" #: .././db/check.c:3441 #, c-format msgid "can't read block %lld for %s quota inode (fsblock %lld)\n" msgstr "nie można odczytać bloku %lld i-węzła limitów %s (blok fs %lld)\n" #: .././db/check.c:3451 #, c-format msgid "%s dqblk %lld entry %d id %u bc %lld ic %lld rc %lld\n" msgstr "%s dqblk %lld wpis %d id %u bc %lld ic %lld rc %lld\n" #: .././db/check.c:3459 #, c-format msgid "bad magic number %#x for %s dqblk %lld entry %d id %u\n" msgstr "błędna liczba magiczna %#x dla dqblk %s %lld, wpis %d, id %u\n" #: .././db/check.c:3468 #, c-format msgid "bad version number %#x for %s dqblk %lld entry %d id %u\n" msgstr "błędny numer wersji %#x dla dqblk %s %lld, wpis %d, id %u\n" #: .././db/check.c:3478 #, c-format msgid "bad flags %#x for %s dqblk %lld entry %d id %u\n" msgstr "błędne flagi %#x dla dqblk %s %lld, wpis %d, id %u\n" #: .././db/check.c:3487 #, c-format msgid "bad id %u for %s dqblk %lld entry %d id %u\n" msgstr "błędne id %u dla dqblk %s %lld, wpis %d, id %u\n" #: .././db/check.c:3533 #, c-format msgid "block %lld for rtbitmap inode is missing\n" msgstr "brak bloku %lld dla i-węzła rtbitmapy\n" #: .././db/check.c:3544 #, c-format msgid "can't read block %lld for rtbitmap inode\n" msgstr "nie można odczytać bloku %lld dla i-węzła rtbitmapy\n" #: .././db/check.c:3600 #, c-format msgid "block %lld for rtsummary inode is missing\n" msgstr "brak bloku %lld dla i-węzła rtsummary\n" #: .././db/check.c:3611 #, c-format msgid "can't read block %lld for rtsummary inode\n" msgstr "nie można odczytać bloku %lld dla i-węzła rtsummary\n" #: .././db/check.c:3644 .././db/check.c:3748 #, c-format msgid "dir %lld entry . %lld\n" msgstr "katalog %lld, wpis . %lld\n" #: .././db/check.c:3652 #, c-format msgid "dir %llu bad size in entry at %d\n" msgstr "katalog %llu: błędny rozmiar we wpisie przy %d\n" #: .././db/check.c:3676 #, c-format msgid "dir %lld entry %*.*s offset %d %lld\n" msgstr "katalog %lld wpis %*.*s offset %d %lld\n" #: .././db/check.c:3681 #, c-format msgid "dir %lld entry %*.*s bad offset %d\n" msgstr "katalog %lld wpis %*.*s błędny offset %d\n" #: .././db/check.c:3694 #, c-format msgid "dir %llu size is %lld, should be %u\n" msgstr "katalog %llu: rozmiar %lld, powinien być %u\n" #: .././db/check.c:3702 #, c-format msgid "dir %llu offsets too high\n" msgstr "katalog %llu: offsety zbyt duże\n" #: .././db/check.c:3713 .././db/check.c:3782 #, c-format msgid "dir %lld entry .. bad inode number %lld\n" msgstr "katalog %lld wpis .. - błędny numer i-węzła %lld\n" #: .././db/check.c:3718 .././db/check.c:3787 #, c-format msgid "dir %lld entry .. %lld\n" msgstr "katalog %lld wpis .. %lld\n" #: .././db/check.c:3721 #, c-format msgid "dir %lld i8count mismatch is %d should be %d\n" msgstr "katalog %lld: niezgodność i8count: jest %d, powinno być %d\n" #: .././db/check.c:3773 #, c-format msgid "dir %llu size is %lld, should be %d\n" msgstr "katalog %llu: rozmiar wynosi %lld, powinien być %d\n" #: .././db/check.c:3864 #, c-format msgid "%s quota id %u, have/exp" msgstr "limit %s id %u: jest/exp" #: .././db/check.c:3867 #, c-format msgid " bc %lld/%lld" msgstr " bc %lld/%lld" #: .././db/check.c:3871 #, c-format msgid " ic %lld/%lld" msgstr " ic %lld/%lld" #: .././db/check.c:3875 #, c-format msgid " rc %lld/%lld" msgstr " rc %lld/%lld" #: .././db/check.c:3931 #, c-format msgid "can't read superblock for ag %u\n" msgstr "nie można odczytać superbloku dla ag %u\n" #: .././db/check.c:3940 #, c-format msgid "bad sb magic # %#x in ag %u\n" msgstr "błędna liczba magiczna %#x superbloku w ag %u\n" #: .././db/check.c:3946 #, c-format msgid "bad sb version # %#x in ag %u\n" msgstr "błędny numer wersji %#x superbloku w ag %u\n" #: .././db/check.c:3956 .././db/sb.c:201 msgid "mkfs not completed successfully\n" msgstr "mkfs nie zakończony pomyślnie\n" #: .././db/check.c:3968 .././db/frag.c:365 #, c-format msgid "can't read agf block for ag %u\n" msgstr "nie można odczytać bloku agf dla ag %u\n" #: .././db/check.c:3974 #, c-format msgid "bad agf magic # %#x in ag %u\n" msgstr "błędna liczba magiczna agf %#x w ag %u\n" #: .././db/check.c:3980 #, c-format msgid "bad agf version # %#x in ag %u\n" msgstr "błędny numer wersji agf %#x w ag %u\n" #: .././db/check.c:3996 .././db/frag.c:374 #, c-format msgid "can't read agi block for ag %u\n" msgstr "nie można odczytać bloku agi w ag %u\n" #: .././db/check.c:4002 #, c-format msgid "bad agi magic # %#x in ag %u\n" msgstr "błędna liczba magiczna agi %#x w ag %u\n" #: .././db/check.c:4008 #, c-format msgid "bad agi version # %#x in ag %u\n" msgstr "błędny numer wersji agi # %#x w ag %u\n" #: .././db/check.c:4048 #, c-format msgid "agf_btreeblks %u, counted %u in ag %u\n" msgstr "agf_btreeblks %u, naliczono %u w ag %u\n" #: .././db/check.c:4072 #, c-format msgid "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" msgstr "agi unlinked bucket %d is %u in ag %u (inode=%lld)\n" #: .././db/check.c:4109 #, c-format msgid "can't read agfl block for ag %u\n" msgstr "nie można odczytać bloku agfl dla ag %u\n" #: .././db/check.c:4128 #, c-format msgid "freeblk count %u != flcount %u in ag %u\n" msgstr "liczba freeblk %u != flcount %u w ag %u\n" #: .././db/check.c:4157 .././db/check.c:4185 .././db/frag.c:397 #: .././db/frag.c:420 .././db/freesp.c:270 #, c-format msgid "can't read btree block %u/%u\n" msgstr "nie można odczytać bloku b-drzewa %u/%u\n" #: .././db/check.c:4218 #, c-format msgid "bad magic # %#x in inode %lld bmbt block %u/%u\n" msgstr "błędna liczba magiczna %#x w i-węźle %lld, blok bmbt %u/%u\n" #: .././db/check.c:4225 #, c-format msgid "expected level %d got %d in inode %lld bmbt block %u/%u\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w i-węźle %lld, blok bmbt %u/%u\n" #: .././db/check.c:4237 .././db/check.c:4254 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inode %lld bmap block %lld\n" msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w i-węźle %lld, blok bitmapy %lld\n" #: .././db/check.c:4282 #, c-format msgid "bad magic # %#x in btbno block %u/%u\n" msgstr "błędna liczba magiczna %#x w bloku btbno %u/%u\n" #: .././db/check.c:4291 #, c-format msgid "expected level %d got %d in btbno block %u/%u\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btbno %u/%u\n" #: .././db/check.c:4300 .././db/check.c:4328 .././db/check.c:4373 #: .././db/check.c:4404 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in btbno block %u/%u\n" msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku btbno %u/%u\n" #: .././db/check.c:4355 #, c-format msgid "bad magic # %#x in btcnt block %u/%u\n" msgstr "błędna liczba magiczna %#x w bloku btcbt %u/%u\n" #: .././db/check.c:4364 #, c-format msgid "expected level %d got %d in btcnt block %u/%u\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku btcnt %u/%u\n" #: .././db/check.c:4435 #, c-format msgid "bad magic # %#x in inobt block %u/%u\n" msgstr "błędna liczba magiczna %#x w bloku inobt %u/%u\n" #: .././db/check.c:4442 #, c-format msgid "expected level %d got %d in inobt block %u/%u\n" msgstr "oczekiwano poziomu %d, a uzyskano %d w bloku inobt %u/%u\n" #: .././db/check.c:4451 .././db/check.c:4517 #, c-format msgid "bad btree nrecs (%u, min=%u, max=%u) in inobt block %u/%u\n" msgstr "błędna liczba rekordów b-drzewa (%u, min=%u, max=%u) w bloku inobt %u/%u\n" #: .././db/check.c:4486 .././db/frag.c:489 #, c-format msgid "can't read inode block %u/%u\n" msgstr "nie można odczytać bloku i-węzła %u/%u\n" #: .././db/check.c:4504 #, c-format msgid "ir_freecount/free mismatch, inode chunk %u/%u, freecount %d nfree %d\n" msgstr "niezgodność ir_freecount/free, porcja i-węzłów %u/%u, freecount %d nfree %d\n" #: .././db/check.c:4559 #, c-format msgid "setting inode to %lld for block %u/%u\n" msgstr "ustawianie i-węzła na %lld dla bloku %u/%u\n" #: .././db/check.c:4591 #, c-format msgid "setting inode to %lld for rtblock %llu\n" msgstr "ustawianie i-węzła na %lld dla rtbloku %llu\n" #: .././db/check.c:4607 #, c-format msgid "inode %lld nlink %u %s dir\n" msgstr "i-węzeł %lld nlink %u katalog %s\n" #: .././db/attrset.c:38 msgid "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name" msgstr "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] nazwa" #: .././db/attrset.c:39 msgid "set the named attribute on the current inode" msgstr "ustawienie atrybutu o podanej nazwie w bieżącym i-węźle" #: .././db/attrset.c:42 msgid "[-r|-s|-p|-u] [-n] name" msgstr "[-r|-s|-p|-u] [-n] nazwa" #: .././db/attrset.c:43 msgid "remove the named attribute from the current inode" msgstr "usunięcie atrybutu o podanej nazwie z bieżącego i-węzła" #: .././db/attrset.c:49 msgid "" "\n" " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" " the extended attribute allocation and removal code.\n" " Both commands require an attribute name to be specified, and the attr_set\n" " command allows an optional value length (-v) to be provided as well.\n" " There are 4 namespace flags:\n" " -r -- 'root'\n" " -u -- 'user'\t\t(default)\n" " -s -- 'secure'\n" "\n" " For attr_set, these options further define the type of set operation:\n" " -C -- 'create' - create attribute, fail if it already exists\n" " -R -- 'replace' - replace attribute, fail if it does not exist\n" " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" "\n" msgstr "" "\n" " Polecenia 'attr_set' i 'attr_remove' udostępniają interfejsy do diagnostyki\n" " kodu przydzielania i usuwania rozszerzonych atrybutów.\n" " Oba polecenia wymagają podania nazwy atrybutu, a polecenie attr_set\n" " pozwala dodatkowo podać opcjonalną długość wartości (-v).\n" " Są 4 flagi przestrzeni nazw:\n" " -r - 'root'\n" " -u - 'user' (domyślna)\n" " -s - 'secure'\n" "\n" " Dla attr_set poniższe opcje określają rodzaj operacji ustawiania:\n" " -C - 'create' - utworzenie atrybutu; nie powiedzie się, jeśli już istnieje\n" " -R - 'replace' - zastąpienie atrybutu; nie powiedzie się, jeśli nie istnieje\n" " Możliwa jest także emulacja trybu kompatybilności wstecznej 'noattr2' (-n).\n" "\n" #: .././db/attrset.c:86 .././db/attrset.c:189 .././db/addr.c:72 #: .././db/print.c:74 .././db/type.c:102 .././db/write.c:101 msgid "no current type\n" msgstr "brak bieżącego typu\n" #: .././db/attrset.c:90 .././db/attrset.c:193 msgid "current type is not inode\n" msgstr "bieżący typ nie jest i-węzłem\n" #: .././db/attrset.c:125 #, c-format msgid "bad attr_set valuelen %s\n" msgstr "błędna długość wartości %s dla attr_set\n" #: .././db/attrset.c:131 msgid "bad option for attr_set command\n" msgstr "błędna opcja dla polecenia attr_set\n" #: .././db/attrset.c:137 msgid "too few options for attr_set (no name given)\n" msgstr "za mało opcji dla attr_set (nie podano nazwy)\n" #: .././db/attrset.c:146 #, c-format msgid "cannot allocate buffer (%d)\n" msgstr "nie udało się przydzielić bufora (%d)\n" #: .././db/attrset.c:155 .././db/attrset.c:230 #, c-format msgid "failed to iget inode %llu\n" msgstr "operacja iget na i-węźle %llu nie powiodła się\n" #: .././db/attrset.c:162 #, c-format msgid "failed to set attr %s on inode %llu\n" msgstr "ustawianie atrybutu %s w i-węźle %llu nie powiodło się\n" #: .././db/attrset.c:217 msgid "bad option for attr_remove command\n" msgstr "błędna opcja dla polecenia attr_remove\n" #: .././db/attrset.c:223 msgid "too few options for attr_remove (no name given)\n" msgstr "za mało opcji dla attr_remove (nie podano nazwy)\n" #: .././db/attrset.c:236 #, c-format msgid "failed to remove attr %s from inode %llu\n" msgstr "usunięcie atrybutu %s z i-węzła %llu nie powiodło się\n" #: .././db/bmap.c:39 msgid "[-ad] [block [len]]" msgstr "[-ad] [blok [długość]]" #: .././db/bmap.c:40 msgid "show block map for current file" msgstr "pokazanie mapy bloków dla bieżącego pliku" #: .././db/bmap.c:153 .././db/inode.c:390 msgid "no current inode\n" msgstr "brak bieżącego i-węzła\n" #: .././db/bmap.c:166 msgid "bad option for bmap command\n" msgstr "błędna opcja dla polecenia bmap\n" #: .././db/bmap.c:183 #, c-format msgid "bad block number for bmap %s\n" msgstr "błędny numer bloku dla bmap %s\n" #: .././db/bmap.c:191 #, c-format msgid "bad len for bmap %s\n" msgstr "błędna długość dla bmap %s\n" #: .././db/bmap.c:214 #, c-format msgid "%s offset %lld startblock %llu (%u/%u) count %llu flag %u\n" msgstr "%s oofset %lld blok-pocz %llu (%u/%u) liczba %llu flaga %u\n" #: .././db/addr.c:35 msgid "[field-expression]" msgstr "[wyrażenie-pól]" #: .././db/addr.c:36 msgid "set current address" msgstr "ustawienie bieżącego adresu" #: .././db/addr.c:42 msgid "" "\n" " 'addr' uses the given field to set the filesystem address and type\n" "\n" " Examples:\n" "\n" " sb\n" " a rootino - set the type to inode and set position to the root inode\n" " a u.bmx[0].startblock (for inode with blockmap)\n" "\n" msgstr "" "\n" " 'addr' wykorzystuje podane pole do ustawienia adresu w systemie plików i typu\n" "\n" " Przykłady:\n" "\n" " sb\n" " a rootino - ustawienie typu na i-węzeł i pozycji na i-węzeł główny\n" " a u.bmx[0].startblock (dla i-węzła z mapą bloków)\n" "\n" #: .././db/addr.c:82 #, c-format msgid "no fields for type %s\n" msgstr "brak pól dla typu %s\n" #: .././db/addr.c:95 msgid "array not allowed for addr command\n" msgstr "tablica nie jest dozwolona dla polecenia addr\n" #: .././db/addr.c:105 #, c-format msgid "no next type for field %s\n" msgstr "brak następnego typu dla pola %s\n" #: .././db/addr.c:112 #, c-format msgid "no addr function for field %s (type %s)\n" msgstr "brak funkcji addr dla pola %s (typu %s)\n" #: .././db/agf.c:35 .././db/agfl.c:36 .././db/agi.c:35 .././db/sb.c:42 msgid "[agno]" msgstr "[agno]" #: .././db/agf.c:36 msgid "set address to agf header" msgstr "ustawienie adresu na nagłówek agf" #: .././db/agf.c:79 msgid "" "\n" " set allocation group free block list\n" "\n" " Example:\n" "\n" " agf 2 - move location to AGF in 2nd filesystem allocation group\n" "\n" " Located in the second sector of each allocation group, the AGF\n" " contains the root of two different freespace btrees:\n" " The 'cnt' btree keeps track freespace indexed on section size.\n" " The 'bno' btree tracks sections of freespace indexed on block number.\n" msgstr "" "\n" " ustawienie listy wolnych bloków grupy alokacji\n" "\n" " Przykład:\n" "\n" " agf 2 - zmiana pozycji na AGF w 2. grupie alokacji systemu plików\n" "\n" " Położony w drugim sektorze każdej grupy alokacji AGF zawiera korzeń\n" " dwóch różnych b-drzew wolnej przestrzeni:\n" " b-drzewo 'cnt' śledzi wolne miejsce indeksowane rozmiarem sekcji\n" " b-drzewo 'bno' śledzi sekcje wolnego miejsca indeksowane numerem bloku.\n" #: .././db/agf.c:104 .././db/agfl.c:90 .././db/agi.c:89 .././db/sb.c:151 #, c-format msgid "bad allocation group number %s\n" msgstr "błędny numer grupy alokacji %s\n" #: .././db/agfl.c:37 msgid "set address to agfl block" msgstr "ustawienie adresu na blok agfl" #: .././db/agfl.c:63 msgid "" "\n" " set allocation group freelist\n" "\n" " Example:\n" "\n" " agfl 5\n" " Located in the fourth sector of each allocation group,\n" " the agfl freelist for internal btree space allocation is maintained\n" " for each allocation group. This acts as a reserved pool of space\n" " separate from the general filesystem freespace (not used for user data).\n" "\n" msgstr "" "\n" " ustawienie listy wolnego miejsca grupy alokacji\n" "\n" " Przykład:\n" "\n" " agfl 5\n" " Położona w 4. sektorze każdej grupy alokacji lista wolnego miejsca agfl\n" " służąca do wewnętrznego przydzielania miejsca dla b-drzew jest utrzymywana\n" " dla każdej grupy alokacji. Działa jako zarezerwowana pula miejsca oddzielona\n" " od ogólnego wolnego miejsca w systemie plików (nie używana dla danych\n" " użytkownika).\n" "\n" #: .././db/agi.c:36 msgid "set address to agi header" msgstr "ustawienie adresu na nagłówek agi" #: .././db/agi.c:64 msgid "" "\n" " set allocation group inode btree\n" "\n" " Example:\n" "\n" " agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" "\n" " Located in the 3rd 512 byte block of each allocation group,\n" " the agi inode btree tracks all used/free inodes in the allocation group.\n" " Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" "\n" msgstr "" "\n" " ustawienie b-drzewa i-węzła grupy alokacji\n" "\n" " Przykład:\n" "\n" " agi 3 (ustawienie położenia na b-drzewo i-węzła 3. grupy alokacji i typu na 'agi')\n" "\n" " Położone w 3. 512-bajtowym bloku każdej grupy alokacji, b-drzewo i-węzła agi\n" " śledzi wszystkie używane i wolne i-węzły w grupie alokacji.\n" " I-węzły są przydzielane w 16k porcjach (chunk), każdy wpis b-drzewa śledzi\n" " jedną.\n" "\n" #: .././db/block.c:43 .././db/block.c:49 msgid "filoff" msgstr "filoff" #: .././db/block.c:44 msgid "set address to file offset (attr fork)" msgstr "ustawienie adresu na offset w pliku (gałąź atrybutów)" #: .././db/block.c:46 msgid "[d]" msgstr "[d]" #: .././db/block.c:47 msgid "set address to daddr value" msgstr "ustawienie adresu na wartość daddr" #: .././db/block.c:50 msgid "set address to file offset (data fork)" msgstr "ustawienie adresu na offset w pliku (gałąź danych)" #: .././db/block.c:52 msgid "[fsb]" msgstr "[fsb]" #: .././db/block.c:53 msgid "set address to fsblock value" msgstr "ustawienie adresu na wartość fsblock" #: .././db/block.c:59 msgid "" "\n" " Example:\n" "\n" " 'ablock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's attribute fork. The filesystem block size is specified in\n" " the superblock.\n" "\n" msgstr "" "\n" " Przykład:\n" "\n" " 'ablock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" " atrybutów i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" "\n" #: .././db/block.c:82 .././db/block.c:177 #, c-format msgid "bad block number %s\n" msgstr "błędny numer bloku %s\n" #: .././db/block.c:90 msgid "no attribute data for file\n" msgstr "brak danych atrybutów dla pliku\n" #: .././db/block.c:96 msgid "file attr block is unmapped\n" msgstr "blok atrybutów pliku nie ma odwzorowania\n" #: .././db/block.c:119 msgid "" "\n" " Example:\n" "\n" " 'daddr 102' - sets position to the 102nd absolute disk block\n" " (512 byte block).\n" msgstr "" "\n" " Przykład:\n" "\n" " 'daddr 102' ustawia pozycję na 102. (bezwzględnie) blok dysku\n" " (blok 512-bajtowy).\n" #: .././db/block.c:135 #, c-format msgid "current daddr is %lld\n" msgstr "bieżący daddr to %lld\n" #: .././db/block.c:141 #, c-format msgid "bad daddr %s\n" msgstr "błędny daddr %s\n" #: .././db/block.c:153 msgid "" "\n" " Example:\n" "\n" " 'dblock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's data fork. The filesystem block size is specified in the\n" " superblock.\n" "\n" msgstr "" "\n" " Przykład:\n" "\n" " 'dblock 23' ustawia pozycję w pliku na 23. blok systemu plików w gałęzi\n" " danych i-węzła. Rozmiar bloku systemu plików jest określony w superbloku.\n" "\n" #: .././db/block.c:185 msgid "no type for file data\n" msgstr "brak typu dla danych pliku\n" #: .././db/block.c:192 msgid "file data block is unmapped\n" msgstr "blok danych plików nie ma odwzorowania\n" #: .././db/block.c:210 msgid "" "\n" " Example:\n" "\n" " 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" " The filesystem block size is specified in the superblock and set during\n" " mkfs time. Offset is absolute (not AG relative).\n" "\n" msgstr "" "\n" " Przykład:\n" "\n" " 'fsblock 1023' ustawia pozycję w pliku na 1023. blok systemu plików.\n" " Rozmiar bloku systemu plików jest określony w superbloku i ustawiany w\n" " trakcie wykonywania mkfs. Offset jest bezwzględny (nie względem AG).\n" "\n" #: .././db/block.c:229 #, c-format msgid "current fsblock is %lld\n" msgstr "bieżący fsblock to %lld\n" #: .././db/block.c:235 .././db/block.c:241 #, c-format msgid "bad fsblock %s\n" msgstr "błędny fsblock %s\n" #: .././db/command.c:86 #, c-format msgid "bad argument count %d to %s, expected " msgstr "błędny argument liczby %d dla %s, oczekiwano " #: .././db/command.c:88 #, c-format msgid "at least %d" msgstr "przynajmniej %d" #: .././db/command.c:92 #, c-format msgid "between %d and %d" msgstr "od %d do %d" #: .././db/command.c:93 msgid " arguments\n" msgstr " argumentów\n" #: .././db/debug.c:27 msgid "[flagbits]" msgstr "[bity flag]" #: .././db/debug.c:28 msgid "set debug option bits" msgstr "ustawienie bitów opcji diagnostycznych" #: .././db/debug.c:42 #, c-format msgid "bad value for debug %s\n" msgstr "błędna wartość diagnostyki %s\n" #: .././db/dquot.c:37 msgid "[projid|gid|uid]" msgstr "[projid|gid|uid]" #: .././db/dquot.c:38 msgid "set current address to project, group or user quota block" msgstr "ustawienie bieżącego adresu na blok limitu projektu, grupy lub użytkownika" #: .././db/dquot.c:124 msgid "bad option for dquot command\n" msgstr "błędna opcja dla polecenia dquot\n" #: .././db/dquot.c:128 msgid "project" msgstr "projekt" #: .././db/dquot.c:128 msgid "group" msgstr "grupę" #: .././db/dquot.c:128 msgid "user" msgstr "użytkownika" #: .././db/dquot.c:130 #, c-format msgid "dquot command requires one %s id argument\n" msgstr "polecenie dquot wymaga jednego argumentu identyfikującego %s\n" #: .././db/dquot.c:137 #, c-format msgid "no %s quota inode present\n" msgstr "i-węzeł limitów na %s nie jest dostępny\n" #: .././db/dquot.c:142 #, c-format msgid "bad %s id for dquot %s\n" msgstr "błędna liczba identyfikująca %s dla dquot %s\n" #: .././db/dquot.c:154 #, c-format msgid "no %s quota data for id %d\n" msgstr "brak danych limitów na %s dla id %d\n" #: .././db/echo.c:27 msgid "[args]..." msgstr "[argumenty]..." #: .././db/echo.c:28 msgid "echo arguments" msgstr "wypisanie argumentów" #: .././db/faddr.c:40 .././db/faddr.c:63 msgid "no current allocation group, cannot set new addr\n" msgstr "brak bieżącej grupy alokacji, nie można ustawić nowego adresu\n" #: .././db/faddr.c:45 .././db/faddr.c:117 .././db/faddr.c:148 #: .././db/faddr.c:180 .././db/faddr.c:202 .././db/faddr.c:232 #: .././db/faddr.c:262 .././db/faddr.c:316 .././db/faddr.c:335 msgid "null block number, cannot set new addr\n" msgstr "pusty numer bloku, nie można ustawić nowego adresu\n" #: .././db/faddr.c:68 .././db/faddr.c:353 .././db/faddr.c:371 #: .././db/faddr.c:389 msgid "null inode number, cannot set new addr\n" msgstr "pusty numer i-węzła, nie można ustawić nowego adresu\n" #: .././db/faddr.c:88 msgid "null attribute block number, cannot set new addr\n" msgstr "pusty number bloku atrybutów, nie można ustawić nowego adresu\n" #: .././db/faddr.c:94 msgid "attribute block is unmapped\n" msgstr "blok atrybutów jest nieodwzorowany\n" #: .././db/faddr.c:123 .././db/faddr.c:155 .././db/faddr.c:208 #: .././db/faddr.c:239 msgid "file block is unmapped\n" msgstr "blok pliku jest nieodwzorowany\n" #: .././db/faddr.c:285 msgid "null directory block number, cannot set new addr\n" msgstr "pusty numer bloku katalogu, nie można ustawić nowego adresu\n" #: .././db/faddr.c:292 msgid "directory block is unmapped\n" msgstr "blok katalogu jest nieodwzorowany\n" #: .././db/flist.c:149 #, c-format msgid "field %s not found\n" msgstr "nie znaleziono pola %s\n" #: .././db/flist.c:159 #, c-format msgid "no elements in %s\n" msgstr "brak elementów w %s\n" #: .././db/flist.c:165 #, c-format msgid "indices %d-%d for field %s out of range %d-%d\n" msgstr "indeksy %d-%d dla pola %s są poza zakresem %d-%d\n" #: .././db/flist.c:173 #, c-format msgid "index %d for field %s out of range %d-%d\n" msgstr "indeks %d dla pola %s jest poza zakresem %d-%d\n" #: .././db/flist.c:187 #, c-format msgid "field %s is not an array\n" msgstr "pole %s nie jest tablicą\n" #: .././db/flist.c:200 #, c-format msgid "field %s has no subfields\n" msgstr "pole %s nie ma podpól\n" #: .././db/flist.c:220 #, c-format msgid "fl@%p:\n" msgstr "fl@%p:\n" #: .././db/flist.c:221 #, c-format msgid "\tname=%s, fld=%p, child=%p, sibling=%p\n" msgstr "\tnazwa=%s, fld=%p, child=%p, sibling=%p\n" #: .././db/flist.c:223 #, c-format msgid "\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n" msgstr "\tlow=%d, high=%d, flagi=%d (%s%s), offset=%d\n" #: .././db/flist.c:225 msgid "oklow " msgstr "oklow " #: .././db/flist.c:226 msgid "okhigh" msgstr "okhigh" #: .././db/flist.c:227 #, c-format msgid "\tfld->name=%s, fld->ftyp=%d (%s)\n" msgstr "\tfld->name=%s, fld->ftyp=%d (%s)\n" #: .././db/flist.c:230 #, c-format msgid "\tfld->flags=%d (%s%s%s%s%s)\n" msgstr "\tfld->flags=%d (%s%s%s%s%s)\n" #: .././db/flist.c:322 #, c-format msgid "bad syntax in field name %s\n" msgstr "błędna składnia w nazwie pola %s\n" #: .././db/flist.c:378 #, c-format msgid "missing closing quote %s\n" msgstr "brak cudzysłowu zamykającego %s\n" #: .././db/flist.c:395 #, c-format msgid "bad character in field %s\n" msgstr "błędny znak w polu %s\n" #: .././db/fprint.c:98 msgid "null" msgstr "nic" #: .././db/hash.c:30 msgid "string" msgstr "łańcuch" #: .././db/hash.c:31 msgid "calculate hash value" msgstr "obliczenie wartości skrótu" #: .././db/hash.c:37 msgid "" "\n" " 'hash' prints out the calculated hash value for a string using the\n" "directory/attribute code hash function.\n" "\n" " Usage: \"hash \"\n" "\n" msgstr "" "\n" " 'hash' wypisuje wartość skrótu dla łańcucha obliczoną przy użyciu funkcji\n" " haszującej dla katalogów/atrybutów.\n" "\n" " Składnia: \"hash <łańcuch>\"\n" "\n" #: .././db/help.c:89 #, c-format msgid "(or %s) " msgstr "(lub %s) " #: .././db/init.c:46 #, c-format msgid "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" msgstr "Składnia: %s [-fFrxV] [-p prog] [-l urz-log] [-c polecenie]... urządzenie\n" #: .././db/init.c:112 msgid "" "\n" "fatal error -- couldn't initialize XFS library\n" msgstr "" "\n" "błąd krytyczny - nie udało się zainicjować biblioteki XFS\n" #: .././db/init.c:118 #, c-format msgid "%s: %s is invalid (cannot read first 512 bytes)\n" msgstr "%s: %s jest nieprawidłowy (nie można odczytać pierwszych 512 bajtów)\n" #: .././db/init.c:129 #, c-format msgid "%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n" msgstr "%s: %s nie jest poprawnym systemem plików XFS (nieoczekiwana liczba magiczna SB 0x%08x)\n" #: .././db/init.c:141 #, c-format msgid "%s: device %s unusable (not an XFS filesystem?)\n" msgstr "%s: urządzenie %s nie nadaje się do użycia (to nie jest system plików XFS?)\n" #: .././db/input.c:43 msgid "source-file" msgstr "plik-źródłowy" #: .././db/input.c:44 msgid "get commands from source-file" msgstr "odczyt poleceń z pliku-źródłowego" #: .././db/input.c:320 #, c-format msgid "can't open %s\n" msgstr "nie można otworzyć %s\n" #: .././db/io.c:46 msgid "pop location from the stack" msgstr "odtworzenie pozycji ze stosu" #: .././db/io.c:49 msgid "push location to the stack" msgstr "zapisanie pozycji na stos" #: .././db/io.c:52 msgid "view the location stack" msgstr "podejrzenie stosu pozycji" #: .././db/io.c:55 msgid "move forward to next entry in the position ring" msgstr "przejście na następną pozycję w kręgu" #: .././db/io.c:58 msgid "move to the previous location in the position ring" msgstr "przejście na poprzednią pozycję w kręgu" #: .././db/io.c:61 msgid "show position ring or move to a specific entry" msgstr "pokazanie kręgu pozycji lub przejście do określonego wpisu" #: .././db/io.c:91 #, c-format msgid "can't set block offset to %d\n" msgstr "nie można ustawić offsetu bloku na %d\n" #: .././db/io.c:104 msgid "can't pop anything from I/O stack\n" msgstr "nie można pobrać nic ze stosu we/wy\n" #: .././db/io.c:132 msgid "" "\n" " Changes the address and data type to the first entry on the stack.\n" "\n" msgstr "" "\n" " Zmiana adresu i typu danych na pierwszy wpis ze stosu.\n" "\n" #: .././db/io.c:146 #, c-format msgid "\tbyte offset %lld, length %d\n" msgstr "\toffset w bajtach %lld, długość %d\n" #: .././db/io.c:147 #, c-format msgid "\tbuffer block %lld (fsbno %lld), %d bb%s\n" msgstr "\tblok bufora %lld (fsbno %lld), %d bb%s\n" #: .././db/io.c:151 msgid "\tblock map" msgstr "\tmapa bloków" #: .././db/io.c:156 #, c-format msgid "\tinode %lld, dir inode %lld, type %s\n" msgstr "\ti-węzeł %lld, i-węzeł katalogu %lld, typ %s\n" #: .././db/io.c:167 msgid "no entries in location ring.\n" msgstr "brak wpisów w kręgu pozycji.\n" #: .././db/io.c:171 msgid " type bblock bblen fsbno inode\n" msgstr " typ bblok bblen fsbno i-węzeł\n" #: .././db/io.c:225 #, c-format msgid "no such command %s\n" msgstr "nieznane polecenie %s\n" #: .././db/io.c:229 #, c-format msgid "no push form allowed for %s\n" msgstr "forma push niedozwolona dla %s\n" #: .././db/io.c:253 msgid "" "\n" " Allows you to push the current address and data type on the stack for\n" " later return. 'push' also accepts an additional command to execute after\n" " storing the current address (ex: 'push a rootino' from the superblock).\n" "\n" msgstr "" "\n" " Pozwala zapisać bieżący adres i typ danych na stos w celu późniejszego\n" " powrotu. 'push' akceptuje także dodatkowe polecenie do wykonania po zapisaniu\n" " bieżącego adresu (np. 'push a rootino' z superbloku).\n" "\n" #: .././db/io.c:269 .././db/io.c:310 msgid "ring is empty\n" msgstr "krąg jest pusty\n" #: .././db/io.c:273 msgid "no further entries\n" msgstr "brak dalszych wpisów\n" #: .././db/io.c:293 msgid "" "\n" " The 'forward' ('f') command moves to the next location in the position\n" " ring, updating the current position and data type. If the current location\n" " is the top entry in the ring, then the 'forward' command will have\n" " no effect.\n" "\n" msgstr "" "\n" " Polecenie 'forward' ('f') przechodzi do następnej pozycji w kręgu,\n" " uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" " jest szczytowym wpisem w kręgu, polecenie nie przyniesie efektu.\n" "\n" #: .././db/io.c:314 msgid "no previous entries\n" msgstr "brak poprzednich wpisów\n" #: .././db/io.c:334 msgid "" "\n" " The 'back' ('b') command moves to the previous location in the position\n" " ring, updating the current position and data type. If the current location\n" " is the last entry in the ring, then the 'back' command will have no effect.\n" "\n" msgstr "" "\n" " Polecenie 'back' ('b') przechodzi do poprzedniej pozycji w kręgu,\n" " uaktualniając bieżącą pozycję i typ danych. Jeśli bieżąca pozycja\n" " jest ostatnim wpisem w kręgu, polecenie nie przyniesie efektu.\n" "\n" #: .././db/io.c:357 #, c-format msgid "invalid entry: %d\n" msgstr "błędny wpis: %d\n" #: .././db/io.c:374 #, c-format msgid "" "\n" " The position ring automatically keeps track of each disk location and\n" " structure type for each change of position you make during your xfs_db\n" " session. The last %d most recent entries are kept in the ring.\n" "\n" " To display the current list of ring entries type 'ring' by itself on\n" " the command line. The entry highlighted by an asterisk ('*') is the\n" " current entry.\n" "\n" " To move to another entry in the ring type 'ring ' where is\n" " your desired entry from the ring position list.\n" "\n" " You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" " to the previous or next entry in the ring, respectively.\n" "\n" " Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" " location implicitly. Use the 'push' and 'pop' commands if you wish to\n" " store a specific location explicitly for later return.\n" "\n" msgstr "" "\n" " Krąg pozycji automatycznie śledzi każde położenie na dysku i typ struktury\n" " dla każdej zmiany pozycji wykonywanej podczas sesji xfs_db. Ostatenie %d\n" " pozycji jest trzymane w kręgu.\n" "\n" " Aby wyświetlić bieżącą listę wpisów w kręgu należy napisać w linii poleceń\n" " po prostu 'ring'. Wpis oznaczony gwiazdką ('*') jest wpisem bieżącym.\n" "\n" " Aby przejść do innego wpisu w kręgu, należy wpisać 'ring ', gdzie\n" " jest numerem pożądanego wpisu na liście pozycji.\n" "\n" " Można także używać poleceń 'forward' ('f') i 'back' ('b'), aby przenieść\n" " się odpowiednio na poprzedni lub następny wpis w kręgu.\n" "\n" " Uwaga: w przeciwieństwie do poleceń 'stack', 'push' i 'pop', krąg śledzi\n" " pozycje niejawnie. Aby zapisać jawnie dane położenie w celu późniejszego\n" " powrotu, należy użyć poleceń 'push' i 'pop'.\n" "\n" #: .././db/io.c:438 .././db/io.c:481 #, c-format msgid "can't seek in filesystem at bb %lld\n" msgstr "nie można wykonać seek w systemie plików na bb %lld\n" #: .././db/io.c:515 msgid "nothing to write\n" msgstr "nie ma nic do zapisania\n" #: .././db/io.c:521 #, c-format msgid "incomplete write, block: %lld\n" msgstr "zapis niekompletny, blok: %lld\n" #: .././db/io.c:524 #, c-format msgid "write error: %s\n" msgstr "błąd zapisu: %s\n" #: .././db/io.c:529 #, c-format msgid "incomplete read, block: %lld\n" msgstr "odczyt niekompletny, blok: %lld\n" #: .././db/io.c:532 #, c-format msgid "read error: %s\n" msgstr "błąd odczytu: %s\n" #: .././db/io.c:548 msgid "set_cur no stack element to set\n" msgstr "set_cur: brak elementu stosu do ustawienia\n" #: .././db/io.c:554 #, c-format msgid "xfs_db got a bbmap for %lld\n" msgstr "xfs_db ma bbmap dla %lld\n" #: .././db/io.c:585 msgid "" "\n" " The stack is used to explicitly store your location and data type\n" " for later return. The 'push' operation stores the current address\n" " and type on the stack, the 'pop' operation returns you to the\n" " position and datatype of the top entry on the stack.\n" "\n" " The 'stack' allows explicit location saves, see 'ring' for implicit\n" " position tracking.\n" "\n" msgstr "" "\n" " Stos służy do jawnego zapisania pozycji i typu danych w celu późniejszego\n" " powrotu. Operacja 'push' zapisuje bieżący adres i typ na stosie, a operacja\n" " 'pop' odtwarza bieżący adres i typ danych z wierzchu stosu.\n" "\n" " Stos ('stack') pozwala na jawne zapisywanie pozycji; domyślnie pozycje są\n" " śledzone poprzez krąg (p. 'ring').\n" "\n" #: .././db/malloc.c:27 #, c-format msgid "%s: out of memory\n" msgstr "%s: brak pamięci\n" #: .././db/output.c:30 msgid "[stop|start ]" msgstr "[stop|start ]" #: .././db/output.c:31 msgid "start or stop logging to a file" msgstr "rozpoczęcie lub zakończenie logowania do pliku" #: .././db/output.c:68 #, c-format msgid "logging to %s\n" msgstr "logowanie do %s\n" #: .././db/output.c:70 .././db/output.c:77 msgid "no log file\n" msgstr "brak pliku logu\n" #: .././db/output.c:80 #, c-format msgid "already logging to %s\n" msgstr "już ustawiono logowanie do %s\n" #: .././db/output.c:84 #, c-format msgid "can't open %s for writing\n" msgstr "nie można otworzyć %s do zapisu\n" #: .././db/output.c:90 msgid "bad log command, ignored\n" msgstr "błędne polecenie logowania, zignorowano\n" #: .././db/print.c:41 msgid "[value]..." msgstr "[wartość]..." #: .././db/print.c:42 msgid "print field values" msgstr "wypisanie wartości pól" #: .././db/print.c:79 #, c-format msgid "no print function for type %s\n" msgstr "brak funkcji wypisującej dla typu %s\n" #: .././db/print.c:153 msgid "(empty)\n" msgstr "(puste)\n" #: .././db/print.c:215 msgid "(empty)" msgstr "(puste)" #: .././db/print.c:275 msgid "no arguments allowed\n" msgstr "argumenty nie są dozwolone\n" #: .././db/quit.c:27 msgid "exit xfs_db" msgstr "zakończenie xfs_db" #: .././db/type.c:50 msgid "[newtype]" msgstr "[nowy-typ]" #: .././db/type.c:51 msgid "set/show current data type" msgstr "ustawienie/wyświetlenie bieżącego typu danych" #: .././db/type.c:104 #, c-format msgid "current type is \"%s\"\n" msgstr "bieżący typ to \"%s\"\n" #: .././db/type.c:106 msgid "" "\n" " supported types are:\n" " " msgstr "" "\n" " obsługiwane typy to:\n" " " #: .././db/type.c:121 #, c-format msgid "no such type %s\n" msgstr "nie ma typu %s\n" #: .././db/type.c:124 msgid "no current object\n" msgstr "brak bieżącego obiektu\n" #: .././db/write.c:41 msgid "[field or value]..." msgstr "[pole lub wartość]..." #: .././db/write.c:42 msgid "write value to disk" msgstr "zapis wartości na dysk" #: .././db/write.c:58 msgid "" "\n" " The 'write' command takes on different personalities depending on the\n" " type of object being worked with.\n" "\n" " Write has 3 modes:\n" " 'struct mode' - is active anytime you're looking at a filesystem object\n" " which contains individual fields (ex: an inode).\n" " 'data mode' - is active anytime you set a disk address directly or set\n" " the type to 'data'.\n" " 'string mode' - only used for writing symlink blocks.\n" "\n" " Examples:\n" " Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" " 'write fname \"hello\\000\"' - write superblock fname.\n" " (note: in struct mode strings are not null terminated)\n" " 'write fname #6669736800' - write superblock fname with hex.\n" " 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" " - write superblock uuid.\n" " Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" " 'write lshift 3' - shift the block 3 bytes to the left\n" " 'write sequence 1 5' - write a cycle of number [1-5] through\n" " the entire block.\n" " String mode: 'write \"This_is_a_filename\" - write null terminated string.\n" "\n" " In data mode type 'write' by itself for a list of specific commands.\n" "\n" msgstr "" "\n" " Polecenie 'write' ma różne osobowości w zależności od rodzaju obiektu,\n" " na jakim pracuje.\n" "\n" " Zapis ma trzy tryby:\n" " 'struct' (strukturalny) - aktywny w przypadku oglądania obiektu systemu\n" " plików zawierającego poszczególne pola (np. i-węzeł).\n" " 'data' (danych) - aktywny w przypadku bezpośredniego ustawienia adresu\n" " na dysku lub ustawienia typu na 'data'.\n" " 'string' (znakowy) - używany tylko przy zapisie bloków dowiązań\n" " symbolicznych.\n" "\n" " Przykłady:\n" " Tryb strukturalny: 'write core.uid 23' - ustawienie pola uid i-węzła na 23\n" " 'write fname \"hello\\000\"' - zapis nazwy pliku sb\n" " (uwaga: w trybie strukturalnym łańcuchy nie są zakańczane)\n" " 'write fname #6669736800' - zapis nazwy pliku sb w hex.\n" " 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" " - zapis UUID-a superbloku.\n" " Tryb danych: 'write fill 0xff' - wypełnienie bloku bajtam 0xff\n" " 'write lshift 3' - przesunięcie bloku o 3 bajty w lewo\n" " 'write sequence 1 5' zapis cyklicznie liczb [1-5] przez\n" " cały blok.\n" " Tryb znakowy: 'write \"To_jest_nazwa_pliku\" - zapis łańcucha\n" " zakończonego znakiem NUL.\n" "\n" " W trybie danych samo 'write' wypisze listę bardziej specyficznych poleceń.\n" "\n" #: .././db/write.c:95 #, c-format msgid "%s started in read only mode, writing disabled\n" msgstr "%s uruchomiono w trybie tylko do odczytu, zapis wyłączony\n" #: .././db/write.c:107 #, c-format msgid "no handler function for type %s, write unsupported.\n" msgstr "brak funkcji obsługującej dla typu %s, zapis nie obsługiwany.\n" #: .././db/write.c:167 .././db/write.c:196 .././db/write.c:226 #: .././db/write.c:258 .././db/write.c:293 .././db/write.c:342 #: .././db/write.c:371 #, c-format msgid "length (%d) too large for data block size (%d)" msgstr "długość (%d) zbyt duża dla rozmiaru bloku danych (%d)" #: .././db/write.c:559 msgid "usage: write fieldname value\n" msgstr "składnia: write nazwa-pola wartość\n" #: .././db/write.c:565 #, c-format msgid "unable to parse '%s'.\n" msgstr "nie można przeanalizować '%s'.\n" #: .././db/write.c:579 msgid "parsing error\n" msgstr "błąd składni\n" #: .././db/write.c:598 #, c-format msgid "unable to convert value '%s'.\n" msgstr "nie można przekonwertować wartości '%s'.\n" #: .././db/write.c:621 msgid "usage (in string mode): write \"string...\"\n" msgstr "składnia (w trybie znakowym): write \"łańcuch...\"\n" #: .././db/write.c:663 msgid "write: invalid subcommand\n" msgstr "write: błędne podpolecenie\n" #: .././db/write.c:668 #, c-format msgid "write %s: invalid number of arguments\n" msgstr "write %s: błędna liczba argumentów\n" #: .././db/write.c:692 msgid "usage: write (in data mode)\n" msgstr "składnia: write (w trybie danych)\n" #: .././db/frag.c:173 #, c-format msgid "actual %llu, ideal %llu, fragmentation factor %.2f%%\n" msgstr "obecnie %llu, idealnie %llu, współczynnik fragmentacji %.2f%%\n" #: .././db/frag.c:214 msgid "bad option for frag command\n" msgstr "błędna opcja dla polecenia frag\n" #: .././db/frag.c:349 #, c-format msgid "inode %lld actual %lld ideal %lld\n" msgstr "i-węzeł %lld obecnie %lld idealnie %lld\n" #: .././db/frag.c:443 .././db/frag.c:453 #, c-format msgid "invalid numrecs (%u) in %s block\n" msgstr "błędne numrecs (%u) w bloku %s\n" #: .././db/metadump.c:55 msgid "[-e] [-g] [-m max_extent] [-w] [-o] filename" msgstr "[-e] [-g] [-m max_extent] [-w] [-o] nazwa-pliku" #: .././db/metadump.c:56 msgid "dump metadata to a file" msgstr "zrzut metadanych do pliku" #: .././db/metadump.c:86 #, c-format msgid "" "\n" " The 'metadump' command dumps the known metadata to a compact file suitable\n" " for compressing and sending to an XFS maintainer for corruption analysis \n" " or xfs_repair failures.\n" "\n" " Options:\n" " -e -- Ignore read errors and keep going\n" " -g -- Display dump progress\n" " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" " -o -- Don't obfuscate names and extended attributes\n" " -w -- Show warnings of bad metadata information\n" "\n" msgstr "" "\n" " Polecenie 'metadump' zrzuca znane metadane do zwięzłego pliku nadającego się\n" " do skompresowania i wysłania prowadzącym projekt XFS w celu analizy uszkodzeń\n" " lub błędów xfs_repair.\n" "\n" " Opcje:\n" " -e - ignorowanie błędów odczytu i kontynuowanie\n" " -g - wyświetlanie postępu\n" " -m - określenie maksymalnego rozmiaru ekstentu (w blokach) do skopiowania\n" " (domyślnie %d bloków)\n" " -o - bez zaciemniania nazw i rozszerzonych atrybutów\n" " -w - wyświetlanie ostrzeżeń o błędnych metadanych\n" "\n" #: .././db/freesp.c:106 #, c-format msgid "total free extents %lld\n" msgstr "razem wolnych ekstentów: %lld\n" #: .././db/freesp.c:107 #, c-format msgid "total free blocks %lld\n" msgstr "razem wolnych bloków: %lld\n" #: .././db/freesp.c:108 #, c-format msgid "average free extent size %g\n" msgstr "średni rozmiar wolnego ekstentu: %g\n" #: .././db/freesp.c:199 msgid "freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" msgstr "argumenty freesp: [-bcds] [-a agno] [-e binsize] [-h h1]... [-m binmult]\n" #: .././db/freesp.c:406 msgid "from" msgstr "od" #: .././db/freesp.c:406 msgid "to" msgstr "do" #: .././db/freesp.c:406 msgid "pct" msgstr "proc." #: .././db/inode.c:385 #, c-format msgid "bad value for inode number %s\n" msgstr "błędna wartość numeru i-węzła %s\n" #: .././db/inode.c:392 #, c-format msgid "current inode number is %lld\n" msgstr "numer bieżącego i-węzła to %lld\n" #: .././db/inode.c:614 #, c-format msgid "bad inode number %lld\n" msgstr "błędny numer i-węzła %lld\n" #: .././db/sb.c:43 msgid "set current address to sb header" msgstr "ustawienie bieżącego adresu na nagłówek sb" #: .././db/sb.c:45 msgid "[uuid]" msgstr "[uuid]" #: .././db/sb.c:46 msgid "write/print FS uuid" msgstr "zapisanie/wypisanie uuida FS" #: .././db/sb.c:48 msgid "[label]" msgstr "[etykieta]" #: .././db/sb.c:49 msgid "write/print FS label" msgstr "zapisanie/wypisanie etykiety FS" #: .././db/sb.c:51 msgid "[feature | [vnum fnum]]" msgstr "[cecha | [vnum fnum]]" #: .././db/sb.c:52 msgid "set feature bit(s) in the sb version field" msgstr "ustawienie bitów cech w polu wersji sb" #: .././db/sb.c:124 msgid "" "\n" " set allocation group superblock\n" "\n" " Example:\n" "\n" " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" "\n" " Located in the first sector of each allocation group, the superblock\n" " contains the base information for the filesystem.\n" " The superblock in allocation group 0 is the primary. The copies in the\n" " remaining allocation groups only serve as backup for filesystem recovery.\n" " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" "\n" msgstr "" "\n" " ustawienie superbloku grupy alokacji\n" "\n" " Przykład:\n" "\n" " 'sb 7' - ustawienie pozycji na superblok 7. grupy alokacji i typu na 'sb'\n" "\n" " Położony w 1. sektorze każdej grupy alokacji superblok zawiera podstawowe\n" " informacje o systemie plików.\n" " Superblok w grupie alokacji 0 jest główny. Kopie w pozostałych grupach\n" " alokacji służą tylko jako kopie zapasowe do odtwarzania systemu plików.\n" " Liczby icount/ifree/fdblocks/frextents są uaktualniane tylko w superbloku 0.\n" "\n" #: .././db/sb.c:183 #, c-format msgid "can't read superblock for AG %u\n" msgstr "nie można odczytać superbloku dla AG %u\n" #: .././db/sb.c:191 #, c-format msgid "bad sb magic # %#x in AG %u\n" msgstr "błędna liczba magiczna superbloku %#x w AG %u\n" #: .././db/sb.c:196 #, c-format msgid "bad sb version # %#x in AG %u\n" msgstr "błędny numer wersji superbloku %#x w AG %u\n" #: .././db/sb.c:218 msgid "aborting - external log specified for FS with an internal log\n" msgstr "przerwano - podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" #: .././db/sb.c:224 msgid "aborting - no external log specified for FS with an external log\n" msgstr "przerwano - nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" #: .././db/sb.c:242 msgid "ERROR: cannot find log head/tail, run xfs_repair\n" msgstr "BŁĄD: nie odnaleziono początku/końca logu, proszę uruchomić xfs_repair\n" #: .././db/sb.c:247 #, c-format msgid "" "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running %s. If you are unable to mount the filesystem, then use\n" "the xfs_repair -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n" msgstr "" "BŁĄD: system plików zawiera wartościowe zmiany metadanych w logu, który\n" "musi być odtworzony. Należy podmontować system plików, aby odtworzyć log,\n" "a następnie odmontować go przed ponownym uruchomieniem %s. Jeśli\n" "systemu plików nie da się podmontować, można użyć opcji -L, aby zniszczyć\n" "log i spróbować naprawić system plików.\n" "Należy zauważyć, że zniszczenie logu może spowodować uszkodzenia danych -\n" "proszę najpierw spróbować podmontować system plików.\n" #: .././db/sb.c:264 msgid "Clearing log and setting UUID\n" msgstr "Czyszczenei logu i ustawianie UUID-a\n" #: .././db/sb.c:273 msgid "ERROR: cannot clear the log\n" msgstr "BŁĄD: nie można wyczyścić logu\n" #: .././db/sb.c:284 msgid "" "\n" " write/print FS uuid\n" "\n" " Example:\n" "\n" " 'uuid' - print UUID\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" " 'uuid generate' - generate and write\n" " 'uuid rewrite' - copy UUID from SB 0\n" "\n" "The print function checks the UUID in each SB and will warn if the UUIDs\n" "differ between AGs (the log is not checked). The write commands will\n" "set the uuid in all AGs to either a specified value, a newly generated\n" "value or the value found in the first superblock (SB 0) respectively.\n" "As a side effect of writing the UUID, the log is cleared (which is fine\n" "on a CLEANLY unmounted FS).\n" "\n" msgstr "" "\n" " zapisanie/wypisanie uuida systemu plików\n" "\n" "Przykład:\n" "\n" " 'uuid' - wypisanie UUID-a\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - zapisanie UUID-a\n" " 'uuid generate' - wygenerowanie i zapisanie\n" " 'uuid rewrite' - skopiowanie UUID-a z sb 0\n" "\n" "Funkcja wypisująca sprawdza UUID w każdym superbloku i ostrzega, jeśli UUID-y\n" "się różnią między AG (log nie jest sprawdzany). Polecenia zapisu ustawiają\n" "UUID we wszystkich AG odpowiednio na określoną wartość, nowo wygenerowaną\n" "wartość lub wartość znalezioną w pierwszym superbloku (SB 0).\n" "Jako efekt uboczny zapisu UUID-a czyszczony jest log (co nie jest problemem\n" "przy CZYSTO odmontowanym systemie plików).\n" "\n" #: .././db/sb.c:336 .././db/sb.c:488 msgid "invalid parameters\n" msgstr "błędne parametry\n" #: .././db/sb.c:343 .././db/sb.c:495 .././db/sb.c:640 #, c-format msgid "%s: not in expert mode, writing disabled\n" msgstr "%s: nie w trybie expert, zapis wyłączony\n" #: .././db/sb.c:355 msgid "failed to read UUID from AG 0\n" msgstr "nie udało się odczytać UUID-a z AG 0\n" #: .././db/sb.c:360 #, c-format msgid "old UUID = %s\n" msgstr "stary UUID = %s\n" #: .././db/sb.c:363 msgid "invalid UUID\n" msgstr "błędny UUID\n" #: .././db/sb.c:372 .././db/sb.c:500 .././db/sb.c:712 msgid "writing all SBs\n" msgstr "zapisywanie wszystkich superbloków\n" #: .././db/sb.c:375 #, c-format msgid "failed to set UUID in AG %d\n" msgstr "nie udało się ustawić UUID-a w AG %d\n" #: .././db/sb.c:380 #, c-format msgid "new UUID = %s\n" msgstr "nowy UUID = %s\n" #: .././db/sb.c:388 #, c-format msgid "failed to read UUID from AG %d\n" msgstr "nie udało się odczytać UUID-a z AG %d\n" #: .././db/sb.c:394 #, c-format msgid "warning: UUID in AG %d differs to the primary SB\n" msgstr "uwaga: UUID w AG %d różni się od głównego SB\n" #: .././db/sb.c:405 msgid "warning - external log specified for FS with an internal log\n" msgstr "uwaga: podano log zewnętrzny dla systemu plików z logiem wewnętrznym\n" #: .././db/sb.c:408 msgid "warning - no external log specified for FS with an external log\n" msgstr "uwaga: nie podano logu zewnętrznego dla systemu plików z logiem zewnętrznym\n" #: .././db/sb.c:413 #, c-format msgid "UUID = %s\n" msgstr "UUID = %s\n" #: .././db/sb.c:424 msgid "" "\n" " write/print FS label\n" "\n" " Example:\n" "\n" " 'label' - print label\n" " 'label 123456789012' - write label\n" " 'label --' - write an empty label\n" "\n" "The print function checks the label in each SB and will warn if the labels\n" "differ between AGs. The write commands will set the label in all AGs to the\n" "specified value. The maximum length of a label is 12 characters - use of a\n" "longer label will result in truncation and a warning will be issued.\n" "\n" msgstr "" "\n" " zapisanie/wypisanie etykiety systemu plików\n" "\n" " Przykład:\n" "\n" " 'label' - wypisanie etykiety\n" " 'label 123456789012' - zapisanie etykiety\n" " 'label --' - zapisanie etykiety pustej\n" "\n" "Funkcja wypisująca sprawdza etykietę w każdym superbloku i ostrzega, jeśli\n" "etykiety różnią się między AG. Polecenia zapisu ustawiają etykietw we\n" "wszystkich AG na określoną wartość. Maksymalna długość etykiety to 12 znaków;\n" "użycie etykiety dłuższej zaskutkuje ucięciem jej i wypisaniem ostrzeżenia.\n" "\n" #: .././db/sb.c:461 #, c-format msgid "%s: truncating label length from %d to %d\n" msgstr "%s: skrócono długość etykiety z %d do %d\n" #: .././db/sb.c:503 #, c-format msgid "failed to set label in AG %d\n" msgstr "nie udało się ustawić etykiety w AG %d\n" #: .././db/sb.c:506 #, c-format msgid "new label = \"%s\"\n" msgstr "nowa etykieta = \"%s\"\n" #: .././db/sb.c:513 #, c-format msgid "failed to read label in AG %d\n" msgstr "nie udało się odczytać etykiety w AG %d\n" #: .././db/sb.c:519 #, c-format msgid "warning: AG %d label differs\n" msgstr "uwaga: etykieta w AG %d różni się\n" #: .././db/sb.c:521 #, c-format msgid "label = \"%s\"\n" msgstr "etykieta = \"%s\"\n" #: .././db/sb.c:531 msgid "" "\n" " set/print feature bits in sb version\n" "\n" " Example:\n" "\n" " 'version' - print current feature bits\n" " 'version extflg' - enable unwritten extents\n" " 'version attr1' - enable v1 inline extended attributes\n" " 'version attr2' - enable v2 inline extended attributes\n" " 'version log2' - enable v2 log format\n" "\n" "The version function prints currently enabled features for a filesystem\n" "according to the version field of its primary superblock.\n" "It can also be used to enable selected features, such as support for\n" "unwritten extents. The updated version is written into all AGs.\n" "\n" msgstr "" "\n" " ustawienie/wypisanie bitów cech w wersji superbloku\n" "\n" " Przykład:\n" "\n" " 'version' - wypisanie bieżących bitów cech\n" " 'version extflg' - włączenie nie zapisanych ekstentów\n" " 'version attr1' - włączenie rozszerzonych atrybutów inline v1\n" " 'version attr2' - włączenie rozszerzonych atrybutów inline v2\n" " 'version log2' - włączenie formatu logu v2\n" "\n" "Funkcja 'version' wypisuje aktualnie włączone cechy dla systemu plików\n" "zgodnie z polem wersji w głównym superbloku.\n" "Może być używana także do włączania wybranych cech, takich jak obsługa\n" "nie zapisanych ekstentów. Uaktualniona wersja jest zapisywana we wszystkich\n" "AG.\n" "\n" #: .././db/sb.c:560 msgid "Superblock has mismatched features2 fields, skipping modification\n" msgstr "Superblok ma niepasujące pola features2, pominięto modyfikację\n" #: .././db/sb.c:659 msgid "unwritten extents flag is already enabled\n" msgstr "flaga nie zapisanych ekstentów jest już włączona\n" #: .././db/sb.c:679 msgid "version 2 log format is already in use\n" msgstr "format logu w wersji 2 jest już w użyciu\n" #: .././db/sb.c:706 #, c-format msgid "%s: invalid version change command \"%s\"\n" msgstr "%s: błędne polecenie zmiany wersji \"%s\"\n" #: .././db/sb.c:715 #, c-format msgid "failed to set versionnum in AG %d\n" msgstr "nie udało się ustawić versionnum w AG %d\n" #: .././db/sb.c:733 #, c-format msgid "versionnum [0x%x+0x%x] = %s\n" msgstr "versionnum [0x%x+0x%x] = %s\n" #: .././copy/xfs_copy.c:102 #, c-format msgid "Check logfile \"%s\" for more details\n" msgstr "Więcej szczegółów w pliku logu \"%s\"\n" #: .././copy/xfs_copy.c:108 #, c-format msgid "%s: could not write to logfile \"%s\".\n" msgstr "%s: nie udało się zapisać pliku logu \"%s\".\n" #: .././copy/xfs_copy.c:111 #, c-format msgid "Aborting XFS copy -- logfile error -- reason: %s\n" msgstr "Przerwano XFS copy - błąd pliku logu - przyczyna: %s\n" #: .././copy/xfs_copy.c:126 .././copy/xfs_copy.c:286 .././copy/xfs_copy.c:563 #: .././copy/xfs_copy.c:570 msgid "Aborting XFS copy - reason" msgstr "Przerwano XFS copy - przyczyna" #: .././copy/xfs_copy.c:140 msgid "THE FOLLOWING COPIES FAILED TO COMPLETE\n" msgstr "NASTĘPUJĄCYCH KOPII NIE UDAŁO SIĘ UKOŃCZYĆ\n" #: .././copy/xfs_copy.c:144 msgid "write error" msgstr "błąd zapisu" #: .././copy/xfs_copy.c:146 msgid "lseek64 error" msgstr "błąd lseek64" #: .././copy/xfs_copy.c:147 #, c-format msgid " at offset %lld\n" msgstr " pod offsetem %lld\n" #: .././copy/xfs_copy.c:151 #, c-format msgid "All copies completed.\n" msgstr "Wszystkie kopie ukończone.\n" #: .././copy/xfs_copy.c:154 #, c-format msgid "See \"%s\" for more details.\n" msgstr "Więcej szczegółów w \"%s\".\n" #: .././copy/xfs_copy.c:255 #, c-format msgid "%s: write error on target %d \"%s\" at offset %lld\n" msgstr "%s: błąd zapisu przy celu %d \"%s\" pod offsetem %lld\n" #: .././copy/xfs_copy.c:260 #, c-format msgid "%s: lseek64 error on target %d \"%s\" at offset %lld\n" msgstr "%s: błąd lseek64 przy celu %d \"%s\" pod offsetem %lld\n" #: .././copy/xfs_copy.c:266 #, c-format msgid "Aborting target %d - reason" msgstr "Przerywano zapis celu %d - przyczyna" #: .././copy/xfs_copy.c:270 msgid "Aborting XFS copy - no more targets.\n" msgstr "Przerwano XFS copy - nie ma więcej celów.\n" #: .././copy/xfs_copy.c:281 #, c-format msgid "%s: thread %d died unexpectedly, target \"%s\" incomplete\n" msgstr "%s: wątek %d zmarł nieoczekiwanie, cel \"%s\" niekompletny\n" #: .././copy/xfs_copy.c:283 #, c-format msgid "%s: offset was probably %lld\n" msgstr "%s: offset prawdopodobnie %lld\n" #: .././copy/xfs_copy.c:294 #, c-format msgid "%s: Unknown child died (should never happen!)\n" msgstr "%s: Nieznany potomek zmarł (nie powinno się zdarzyć!)\n" #: .././copy/xfs_copy.c:304 #, c-format msgid "Usage: %s [-bd] [-L logfile] source target [target ...]\n" msgstr "Składnia: %s [-bd] [-L plik_logu] źródło cel [cel ...]\n" #: .././copy/xfs_copy.c:386 #, c-format msgid "%s: lseek64 failure at offset %lld\n" msgstr "%s: niepowodzenie lseek64 pod offsetem %lld\n" #: .././copy/xfs_copy.c:401 #, c-format msgid "assert error: buf->length = %d, buf->size = %d\n" msgstr "błąd zapewnienia: buf->length = %d, buf->size = %d\n" #: .././copy/xfs_copy.c:408 #, c-format msgid "%s: read failure at offset %lld\n" msgstr "%s: błąd odczytu pod offsetem %lld\n" #: .././copy/xfs_copy.c:561 #, c-format msgid "%s: couldn't open log file \"%s\"\n" msgstr "%s: nie udało się otworzyć pliku logu \"%s\"\n" #: .././copy/xfs_copy.c:568 #, c-format msgid "%s: couldn't set up logfile stream\n" msgstr "%s: nie udało się ustanowić strumienia pliku logu\n" #: .././copy/xfs_copy.c:580 msgid "Couldn't allocate target array\n" msgstr "Nie udało się przydzielić tablicy celów\n" #: .././copy/xfs_copy.c:595 #, c-format msgid "%s: couldn't register atexit function.\n" msgstr "%s: nie udało się zarejestrować funkcji atexit.\n" #: .././copy/xfs_copy.c:604 #, c-format msgid "%s: couldn't open source \"%s\"\n" msgstr "%s: nie udało się otworzyć źródła \"%s\"\n" #: .././copy/xfs_copy.c:610 #, c-format msgid "%s: couldn't stat source \"%s\"\n" msgstr "%s: nie udało się wykonać stat na źródle \"%s\"\n" #: .././copy/xfs_copy.c:620 #, c-format msgid "%s: Cannot set direct I/O flag on \"%s\".\n" msgstr "%s: Nie można ustawić flagi bezpośredniego we/wy na \"%s\".\n" #: .././copy/xfs_copy.c:625 #, c-format msgid "%s: xfsctl on file \"%s\" failed.\n" msgstr "%s: xfsctl na pliku \"%s\" nie powiodło się.\n" #: .././copy/xfs_copy.c:648 #, c-format msgid "%s: Warning -- a filesystem is mounted on the source device.\n" msgstr "%s: Uwaga - system plików jest podmontowany na urządzeniu źródłowym.\n" #: .././copy/xfs_copy.c:651 msgid "\t\tGenerated copies may be corrupt unless the source is\n" msgstr "\t\tWygenerowane kopie mogą być uszkodzone o ile źródło nie jest\n" #: .././copy/xfs_copy.c:653 msgid "\t\tunmounted or mounted read-only. Copy proceeding...\n" msgstr "\t\todmontowane lub podmontowane tylko do odczytu. Kopiowanie w trakcie...\n" #: .././copy/xfs_copy.c:670 #, c-format msgid "" "%s: couldn't initialize XFS library\n" "%s: Aborting.\n" msgstr "" "%s: nie udało się zainicjować biblioteki XFS\n" "%s: Przerwano.\n" #: .././copy/xfs_copy.c:684 #, c-format msgid "" "%s: %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" "%s: Nie powiodła się inicjalizacja systemu plików %s\n" "%s: Przerwano.\n" #: .././copy/xfs_copy.c:688 #, c-format msgid "" "%s %s filesystem failed to initialize\n" "%s: Aborting.\n" msgstr "" "%s: Nie powiodła się inicjalizacja systemu plików %s\n" "%s: Przerwano.\n" #: .././copy/xfs_copy.c:692 #, c-format msgid "" "%s: %s has an external log.\n" "%s: Aborting.\n" msgstr "" "%s: %s ma zewnętrzny log.\n" "%s: Przerwano.\n" #: .././copy/xfs_copy.c:696 #, c-format msgid "" "%s: %s has a real-time section.\n" "%s: Aborting.\n" msgstr "" "%s: %s ma sekcję real-time.\n" "%s: Przerwano.\n" #: .././copy/xfs_copy.c:721 msgid "" "Error: filesystem block size is smaller than the disk sectorsize.\n" "Aborting XFS copy now.\n" msgstr "" "Błąd: rozmiar bloku systemu plików jest mniejszy niż rozmiar sektora dysku.\n" "Przerwano XFS copy.\n" #: .././copy/xfs_copy.c:742 #, c-format msgid "Creating file %s\n" msgstr "Tworzenie pliku %s\n" #: .././copy/xfs_copy.c:760 #, c-format msgid "" "%s: a filesystem is mounted on target device \"%s\".\n" "%s cannot copy to mounted filesystems. Aborting\n" msgstr "" "%s: na urządzeniu docelowym \"%s\" jest podmontowany system plików.\n" "%s nie może kopiować na podmontowane systemy plików. Przerwano.\n" #: .././copy/xfs_copy.c:771 #, c-format msgid "%s: couldn't open target \"%s\"\n" msgstr "%s: nie udało się otworzyć celu \"%s\"\n" #: .././copy/xfs_copy.c:781 #, c-format msgid "%s: cannot grow data section.\n" msgstr "%s: nie można powiększyć sekcji danych.\n" #: .././copy/xfs_copy.c:789 #, c-format msgid "%s: xfsctl on \"%s\" failed.\n" msgstr "%s: xfsctl na \"%s\" nie powiodło się.\n" #: .././copy/xfs_copy.c:808 #, c-format msgid "%s: failed to write last block\n" msgstr "%s: nie udało się zapisać ostatniego bloku\n" #: .././copy/xfs_copy.c:810 #, c-format msgid "\tIs target \"%s\" too small?\n" msgstr "\tCzy cel \"%s\" jest zbyt mały?\n" #: .././copy/xfs_copy.c:820 msgid "Couldn't initialize global thread mask\n" msgstr "Nie udało się zainicjować globalnej maski wątków\n" #: .././copy/xfs_copy.c:827 msgid "Error initializing wbuf 0\n" msgstr "Błąd inicjalizacji wbuf 0\n" #: .././copy/xfs_copy.c:835 msgid "Error initializing btree buf 1\n" msgstr "Błąd inicjalizacji btree buf 1\n" #: .././copy/xfs_copy.c:840 msgid "Error creating first semaphore.\n" msgstr "Błąd tworzenia pierwszego semafora.\n" #: .././copy/xfs_copy.c:855 msgid "Couldn't malloc space for thread args\n" msgstr "Nie udało się przydzielić miejsca na argumenty wątku\n" #: .././copy/xfs_copy.c:867 #, c-format msgid "Error creating thread mutex %d\n" msgstr "Błąd podczas tworzenia sekcji krytycznej %d wątku\n" #: .././copy/xfs_copy.c:884 #, c-format msgid "Error creating thread for target %d\n" msgstr "Błąd podczas tworzenia wątku dla celu %d\n" #: .././copy/xfs_copy.c:974 msgid "WARNING: source filesystem inconsistent.\n" msgstr "UWAGA: źródłowy system plików niespójny.\n" #: .././copy/xfs_copy.c:976 msgid " A leaf btree rec isn't a leaf. Aborting now.\n" msgstr " Liść rekordu b-drzewa nie jest liściem. Przerwano.\n" #~ msgid "Unknown inode format.\n" #~ msgstr "Nieznany format i-węzła.\n" # XXX msgid bug: "0x" prefix for decimal number #~ msgid "inode 0x% bad # of bmap records (%u, min - %u, max - %u)\n" #~ msgstr "błędna liczba rekordów bmap w i-węźle 0x% (%u, minimum - %u, maksimum - %u)\n" #~ msgid "could not allocate expanded nlink array\n" #~ msgstr "Nie udało się przydzielić rozszerzonej tablicy nlink\n" #~ msgid "bmap of block #%u of inode % failed\n" #~ msgstr "bmap bloku #%u i-węzła % nie powiodło się\n" #~ msgid "error following ag %d unlinked list\n" #~ msgstr "błąd podczas podążania za odłączoną listą ag %d\n" #~ msgid "ts_alloc: cannot allocate thread specific storage\n" #~ msgstr "ts_alloc: nie można przydzielić miejsca dla wątku\n" xfsprogs-3.1.9ubuntu2/copy/0000775000000000000000000000000012062211563012564 5ustar xfsprogs-3.1.9ubuntu2/copy/Makefile0000664000000000000000000000073211330256617014234 0ustar # # Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_copy CFILES = xfs_copy.c HFILES = xfs_copy.h LLDLIBS = $(LIBXFS) $(LIBUUID) $(LIBPTHREAD) $(LIBRT) LTDEPENDENCIES = $(LIBXFS) LLDFLAGS = -static default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/copy/xfs_copy.h0000664000000000000000000000564511140033220014565 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * An on-disk allocation group header is composed of 4 structures, * each of which is 1 disk sector long where the sector size is at * least 512 bytes long (BBSIZE). * * There's one ag_header per ag and the superblock in the first ag * is the contains the real data for the entire filesystem (although * most of the relevant data won't change anyway even on a growfs). * * The filesystem superblock specifies the number of AG's and * the AG size. That splits the filesystem up into N pieces, * each of which is an AG and has an ag_header at the beginning. */ typedef struct ag_header { xfs_dsb_t *xfs_sb; /* superblock for filesystem or AG */ xfs_agf_t *xfs_agf; /* free space info */ xfs_agi_t *xfs_agi; /* free inode info */ xfs_agfl_t *xfs_agfl; /* AG freelist */ char *residue; int residue_length; } ag_header_t; /* * The position/buf_position, length/buf_length, data/buffer pairs * exist because of alignment constraints for direct I/O and dealing * with scenarios where either the source or target or both is a file * and the blocksize of the filesystem where file resides is different * from that of the filesystem image being duplicated. You can get * alignment problems resulting from things like AG's starting on * non-aligned points in the filesystem. So you have to be able * to read from points "before" the requested starting point and * read in more data than requested. */ struct t_args; typedef struct { int id; /* buffer ID */ size_t size; /* size of buffer -- fixed */ size_t min_io_size; /* for direct I/O */ xfs_off_t position; /* requested position (bytes) */ size_t length; /* requested length (bytes) */ char *data; /* pointer to data buffer */ struct t_args *owner; /* for non-parallel writes */ } wbuf; typedef struct t_args { int id; uuid_t uuid; pthread_mutex_t wait; int fd; } thread_args; typedef struct { pthread_mutex_t mutex; int num_working; wbuf *buffer; } thread_control; typedef int thread_id; typedef int tm_index; /* index into thread mask array */ typedef __uint32_t thread_mask; /* a thread mask */ typedef struct { char *name; int fd; xfs_off_t position; pthread_t pid; int state; int error; int err_type; } target_control; xfsprogs-3.1.9ubuntu2/copy/xfs_copy.c0000664000000000000000000007127111140033220014556 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "xfs_copy.h" #define rounddown(x, y) (((x)/(y))*(y)) extern int platform_check_ismounted(char *, char *, struct stat64 *, int); int logfd; char *logfile_name; FILE *logerr; char LOGFILE_NAME[] = "/var/tmp/xfs_copy.log.XXXXXX"; char *source_name; int source_fd; unsigned int source_blocksize; /* source filesystem blocksize */ unsigned int source_sectorsize; /* source disk sectorsize */ xfs_agblock_t first_agbno; __uint64_t barcount[11]; unsigned int num_targets; target_control *target; wbuf w_buf; wbuf btree_buf; pid_t parent_pid; unsigned int kids; thread_control glob_masks; thread_args *targ; pthread_mutex_t mainwait; #define ACTIVE 1 #define INACTIVE 2 xfs_off_t write_log_trailer(int fd, wbuf *w, xfs_mount_t *mp); xfs_off_t write_log_header(int fd, wbuf *w, xfs_mount_t *mp); /* general purpose message reporting routine */ #define OUT 0x01 /* use stdout stream */ #define ERR 0x02 /* use stderr stream */ #define LOG 0x04 /* use logerr stream */ #define PRE 0x08 /* append strerror string */ #define LAST 0x10 /* final message we print */ void do_message(int flags, int code, const char *fmt, ...) { va_list ap; int eek = 0; if (flags & LOG) { va_start(ap, fmt); if (vfprintf(logerr, fmt, ap) <= 0) eek = 1; va_end(ap); } if (eek) flags |= ERR; /* failed, force stderr */ if (flags & ERR) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } else if (flags & OUT) { va_start(ap, fmt); vfprintf(stdout, fmt, ap); va_end(ap); } if (flags & PRE) { do_message(flags & ~PRE, 0, ": %s\n", strerror(code)); if (flags & LAST) fprintf(stderr, _("Check logfile \"%s\" for more details\n"), logfile_name); } /* logfile is broken, force a write to stderr */ if (eek) { fprintf(stderr, _("%s: could not write to logfile \"%s\".\n"), progname, logfile_name); fprintf(stderr, _("Aborting XFS copy -- logfile error -- reason: %s\n"), strerror(errno)); pthread_exit(NULL); } } #define do_out(args...) do_message(OUT|LOG, 0, ## args) #define do_log(args...) do_message(ERR|LOG, 0, ## args) #define do_warn(args...) do_message(LOG, 0, ## args) #define do_error(e,s) do_message(ERR|LOG|PRE, e, s) #define do_fatal(e,s) do_message(ERR|LOG|PRE|LAST, e, s) #define do_vfatal(e,s,args...) do_message(ERR|LOG|PRE|LAST, e, s, ## args) #define die_perror() \ do { \ do_message(ERR|LOG|PRE|LAST, errno, \ _("Aborting XFS copy - reason")); \ exit(1); \ } while (0) void check_errors(void) { int i, first_error = 0; for (i = 0; i < num_targets; i++) { if (target[i].state == INACTIVE) { if (first_error == 0) { first_error++; do_log( _("THE FOLLOWING COPIES FAILED TO COMPLETE\n")); } do_log(" %s -- ", target[i].name); if (target[i].err_type == 0) do_log(_("write error")); else do_log(_("lseek64 error")); do_log(_(" at offset %lld\n"), target[i].position); } } if (first_error == 0) { fprintf(stdout, _("All copies completed.\n")); fflush(NULL); } else { fprintf(stderr, _("See \"%s\" for more details.\n"), logfile_name); exit(1); } } /* * don't have to worry about alignment and mins because those * are taken care of when the buffer's read in */ int do_write(thread_args *args) { int res, error = 0; if (target[args->id].position != w_buf.position) { if (lseek64(args->fd, w_buf.position, SEEK_SET) < 0) { error = target[args->id].err_type = 1; } else { target[args->id].position = w_buf.position; } } if ((res = write(target[args->id].fd, w_buf.data, w_buf.length)) == w_buf.length) { target[args->id].position += res; } else { error = 2; } if (error) { target[args->id].error = errno; target[args->id].position = w_buf.position; } return error; } void * begin_reader(void *arg) { thread_args *args = arg; for (;;) { pthread_mutex_lock(&args->wait); if (do_write(args)) goto handle_error; pthread_mutex_lock(&glob_masks.mutex); if (--glob_masks.num_working == 0) pthread_mutex_unlock(&mainwait); pthread_mutex_unlock(&glob_masks.mutex); } /* NOTREACHED */ handle_error: /* error will be logged by primary thread */ pthread_mutex_lock(&glob_masks.mutex); target[args->id].state = INACTIVE; if (--glob_masks.num_working == 0) pthread_mutex_unlock(&mainwait); pthread_mutex_unlock(&glob_masks.mutex); pthread_exit(NULL); return NULL; } void killall(void) { int i; /* only the parent gets to kill things */ if (getpid() != parent_pid) return; for (i = 0; i < num_targets; i++) { if (target[i].state == ACTIVE) { /* kill up target threads */ pthread_kill(target[i].pid, SIGKILL); pthread_mutex_unlock(&targ[i].wait); } } } void handler(int sig) { pid_t pid = getpid(); int status, i; pid = wait(&status); kids--; for (i = 0; i < num_targets; i++) { if (target[i].pid == pid) { if (target[i].state == INACTIVE) { /* thread got an I/O error */ if (target[i].err_type == 0) { do_warn( _("%s: write error on target %d \"%s\" at offset %lld\n"), progname, i, target[i].name, target[i].position); } else { do_warn( _("%s: lseek64 error on target %d \"%s\" at offset %lld\n"), progname, i, target[i].name, target[i].position); } do_vfatal(target[i].error, _("Aborting target %d - reason"), i); if (kids == 0) { do_log( _("Aborting XFS copy - no more targets.\n")); check_errors(); pthread_exit(NULL); } signal(SIGCHLD, handler); return; } else { /* it just croaked it bigtime, log it */ do_warn( _("%s: thread %d died unexpectedly, target \"%s\" incomplete\n"), progname, i, target[i].name); do_warn(_("%s: offset was probably %lld\n"), progname, target[i].position); do_fatal(target[i].error, _("Aborting XFS copy - reason")); pthread_exit(NULL); } } } /* unknown child -- something very wrong */ do_warn(_("%s: Unknown child died (should never happen!)\n"), progname); die_perror(); pthread_exit(NULL); signal(SIGCHLD, handler); } void usage(void) { fprintf(stderr, _("Usage: %s [-bd] [-L logfile] source target [target ...]\n"), progname); exit(1); } void init_bar(__uint64_t source_blocks) { int i; for (i = 0; i < 11; i++) barcount[i] = (source_blocks/10)*i; } int bump_bar(int tenths, __uint64_t numblocks) { static char *bar[11] = { " 0% ", " ... 10% ", " ... 20% ", " ... 30% ", " ... 40% ", " ... 50% ", " ... 60% ", " ... 70% ", " ... 80% ", " ... 90% ", " ... 100%\n\n", }; if (tenths > 10) { printf("%s", bar[10]); fflush(stdout); } else { while (tenths < 10 && numblocks > barcount[tenths]) { printf("%s", bar[tenths]); fflush(stdout); tenths++; } } return tenths; } static xfs_off_t source_position = -1; wbuf * wbuf_init(wbuf *buf, int data_size, int data_align, int min_io_size, int id) { ASSERT(data_size % BBSIZE == 0); while ((buf->data = memalign(data_align, data_size)) == NULL) { data_size >>= 1; if (data_size < min_io_size) return NULL; } ASSERT(min_io_size % BBSIZE == 0); buf->min_io_size = min_io_size; buf->size = data_size; buf->id = id; return buf; } void read_wbuf(int fd, wbuf *buf, xfs_mount_t *mp) { int res = 0; xfs_off_t lres = 0; xfs_off_t newpos; size_t diff; newpos = rounddown(buf->position, (xfs_off_t) buf->min_io_size); if (newpos != buf->position) { diff = buf->position - newpos; buf->position = newpos; buf->length += diff; } if (source_position != buf->position) { lres = lseek64(fd, buf->position, SEEK_SET); if (lres < 0LL) { do_warn(_("%s: lseek64 failure at offset %lld\n"), progname, source_position); die_perror(); } source_position = buf->position; } ASSERT(source_position % source_sectorsize == 0); /* round up length for direct I/O if necessary */ if (buf->length % buf->min_io_size != 0) buf->length = roundup(buf->length, buf->min_io_size); if (buf->length > buf->size) { do_warn(_("assert error: buf->length = %d, buf->size = %d\n"), buf->length, buf->size); killall(); abort(); } if ((res = read(fd, buf->data, buf->length)) < 0) { do_warn(_("%s: read failure at offset %lld\n"), progname, source_position); die_perror(); } if (res < buf->length && source_position + res == mp->m_sb.sb_dblocks * source_blocksize) res = buf->length; else ASSERT(res == buf->length); source_position += res; buf->length = res; } void read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag, xfs_mount_t *mp, int blocksize, int sectorsize) { xfs_daddr_t off; int length; xfs_off_t newpos; size_t diff; /* initial settings */ diff = 0; off = XFS_AG_DADDR(mp, agno, XFS_SB_DADDR); buf->position = (xfs_off_t) off * (xfs_off_t) BBSIZE; length = buf->length = first_agbno * blocksize; /* handle alignment stuff */ newpos = rounddown(buf->position, (xfs_off_t) buf->min_io_size); if (newpos != buf->position) { diff = buf->position - newpos; buf->position = newpos; buf->length += diff; } /* round up length for direct I/O if necessary */ if (buf->length % buf->min_io_size != 0) buf->length = roundup(buf->length, buf->min_io_size); ASSERT(length != 0); read_wbuf(fd, buf, mp); ASSERT(buf->length >= length); ag->xfs_sb = (xfs_dsb_t *) (buf->data + diff); ASSERT(be32_to_cpu(ag->xfs_sb->sb_magicnum) == XFS_SB_MAGIC); ag->xfs_agf = (xfs_agf_t *) (buf->data + diff + sectorsize); ASSERT(be32_to_cpu(ag->xfs_agf->agf_magicnum) == XFS_AGF_MAGIC); ag->xfs_agi = (xfs_agi_t *) (buf->data + diff + 2 * sectorsize); ASSERT(be32_to_cpu(ag->xfs_agi->agi_magicnum) == XFS_AGI_MAGIC); ag->xfs_agfl = (xfs_agfl_t *) (buf->data + diff + 3 * sectorsize); } void write_wbuf(void) { int i; /* verify target threads */ for (i = 0; i < num_targets; i++) if (target[i].state != INACTIVE) glob_masks.num_working++; /* release target threads */ for (i = 0; i < num_targets; i++) if (target[i].state != INACTIVE) pthread_mutex_unlock(&targ[i].wait); /* wake up */ sigrelse(SIGCHLD); pthread_mutex_lock(&mainwait); sighold(SIGCHLD); } int main(int argc, char **argv) { int i, j; int howfar = 0; int open_flags; xfs_off_t pos, end_pos; size_t length; int c, first_residue, tmp_residue; __uint64_t size, sizeb; __uint64_t numblocks = 0; int wblocks = 0; int num_threads = 0; struct dioattr d; int wbuf_size; int wbuf_align; int wbuf_miniosize; int source_is_file = 0; int buffered_output = 0; int duplicate = 0; uint btree_levels, current_level; ag_header_t ag_hdr; xfs_mount_t *mp; xfs_mount_t mbuf; xfs_buf_t *sbp; xfs_sb_t *sb; xfs_agnumber_t num_ags, agno; xfs_agblock_t bno; xfs_daddr_t begin, next_begin, ag_begin, new_begin, ag_end; struct xfs_btree_block *block; xfs_alloc_ptr_t *ptr; xfs_alloc_rec_t *rec_ptr; extern char *optarg; extern int optind; libxfs_init_t xargs; thread_args *tcarg; struct stat64 statbuf; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt(argc, argv, "bdL:V")) != EOF) { switch (c) { case 'b': buffered_output = 1; break; case 'd': duplicate = 1; break; case 'L': logfile_name = optarg; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': usage(); } } if (argc - optind < 2) usage(); if (logfile_name) { logfd = open(logfile_name, O_CREAT|O_WRONLY|O_EXCL, 0600); } else { logfile_name = LOGFILE_NAME; logfd = mkstemp(logfile_name); } if (logfd < 0) { fprintf(stderr, _("%s: couldn't open log file \"%s\"\n"), progname, logfile_name); perror(_("Aborting XFS copy - reason")); exit(1); } if ((logerr = fdopen(logfd, "w")) == NULL) { fprintf(stderr, _("%s: couldn't set up logfile stream\n"), progname); perror(_("Aborting XFS copy - reason")); exit(1); } source_name = argv[optind]; source_fd = -1; optind++; num_targets = argc - optind; if ((target = malloc(sizeof(target_control) * num_targets)) == NULL) { do_log(_("Couldn't allocate target array\n")); die_perror(); } for (i = 0; optind < argc; i++, optind++) { target[i].name = argv[optind]; target[i].fd = -1; target[i].position = -1; target[i].state = INACTIVE; target[i].error = 0; target[i].err_type = 0; } parent_pid = getpid(); if (atexit(killall)) { do_log(_("%s: couldn't register atexit function.\n"), progname); die_perror(); } /* open up source -- is it a file? */ open_flags = O_RDONLY; if ((source_fd = open(source_name, open_flags)) < 0) { do_log(_("%s: couldn't open source \"%s\"\n"), progname, source_name); die_perror(); } if (fstat64(source_fd, &statbuf) < 0) { do_log(_("%s: couldn't stat source \"%s\"\n"), progname, source_name); die_perror(); } if (S_ISREG(statbuf.st_mode)) source_is_file = 1; if (source_is_file && platform_test_xfs_fd(source_fd)) { if (fcntl(source_fd, F_SETFL, open_flags | O_DIRECT) < 0) { do_log(_("%s: Cannot set direct I/O flag on \"%s\".\n"), progname, source_name); die_perror(); } if (xfsctl(source_name, source_fd, XFS_IOC_DIOINFO, &d) < 0) { do_log(_("%s: xfsctl on file \"%s\" failed.\n"), progname, source_name); die_perror(); } wbuf_align = d.d_mem; wbuf_size = MIN(d.d_maxiosz, 1 * 1024 * 1024); wbuf_miniosize = d.d_miniosz; } else { /* set arbitrary I/O params, miniosize at least 1 disk block */ wbuf_align = getpagesize(); wbuf_size = 1 * 1024 * 1024; wbuf_miniosize = -1; /* set after mounting source fs */ } if (!source_is_file) { /* * check to make sure a filesystem isn't mounted * on the device */ if (platform_check_ismounted(source_name, NULL, &statbuf, 0)) { do_log( _("%s: Warning -- a filesystem is mounted on the source device.\n"), progname); do_log( _("\t\tGenerated copies may be corrupt unless the source is\n")); do_log( _("\t\tunmounted or mounted read-only. Copy proceeding...\n")); } } /* prepare the libxfs_init structure */ memset(&xargs, 0, sizeof(xargs)); xargs.isdirect = LIBXFS_DIRECT; xargs.isreadonly = LIBXFS_ISREADONLY; if (source_is_file) { xargs.dname = source_name; xargs.disfile = 1; } else xargs.volname = source_name; if (!libxfs_init(&xargs)) { do_log(_("%s: couldn't initialize XFS library\n" "%s: Aborting.\n"), progname, progname); exit(1); } /* prepare the mount structure */ sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(&mbuf, 0, sizeof(xfs_mount_t)); sb = &mbuf.m_sb; libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); if (mp == NULL) { do_log(_("%s: %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_inprogress) { do_log(_("%s %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_logstart == 0) { do_log(_("%s: %s has an external log.\n%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_rextents != 0) { do_log(_("%s: %s has a real-time section.\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } source_blocksize = mp->m_sb.sb_blocksize; source_sectorsize = mp->m_sb.sb_sectsize; if (wbuf_miniosize == -1) wbuf_miniosize = source_sectorsize; ASSERT(source_blocksize % source_sectorsize == 0); ASSERT(source_sectorsize % BBSIZE == 0); if (source_blocksize > source_sectorsize) { /* get number of leftover sectors in last block of ag header */ tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) % source_blocksize; first_residue = (tmp_residue == 0) ? 0 : source_blocksize - tmp_residue; ASSERT(first_residue % source_sectorsize == 0); } else if (source_blocksize == source_sectorsize) { first_residue = 0; } else { do_log(_("Error: filesystem block size is smaller than the" " disk sectorsize.\nAborting XFS copy now.\n")); exit(1); } first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_residue) / source_blocksize; ASSERT(first_agbno != 0); ASSERT( ((((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_residue) % source_blocksize) == 0); /* now open targets */ open_flags = O_RDWR; for (i = 0; i < num_targets; i++) { int write_last_block = 0; if (stat64(target[i].name, &statbuf) < 0) { /* ok, assume it's a file and create it */ do_out(_("Creating file %s\n"), target[i].name); open_flags |= O_CREAT; if (!buffered_output) open_flags |= O_DIRECT; write_last_block = 1; } else if (S_ISREG(statbuf.st_mode)) { open_flags |= O_TRUNC; if (!buffered_output) open_flags |= O_DIRECT; write_last_block = 1; } else { /* * check to make sure a filesystem isn't mounted * on the device */ if (platform_check_ismounted(target[i].name, NULL, &statbuf, 0)) { do_log(_("%s: a filesystem is mounted " "on target device \"%s\".\n" "%s cannot copy to mounted filesystems." " Aborting\n"), progname, target[i].name, progname); exit(1); } } target[i].fd = open(target[i].name, open_flags, 0644); if (target[i].fd < 0) { do_log(_("%s: couldn't open target \"%s\"\n"), progname, target[i].name); die_perror(); } if (write_last_block) { /* ensure regular files are correctly sized */ if (ftruncate64(target[i].fd, mp->m_sb.sb_dblocks * source_blocksize)) { do_log(_("%s: cannot grow data section.\n"), progname); die_perror(); } if (platform_test_xfs_fd(target[i].fd)) { if (xfsctl(target[i].name, target[i].fd, XFS_IOC_DIOINFO, &d) < 0) { do_log( _("%s: xfsctl on \"%s\" failed.\n"), progname, target[i].name); die_perror(); } else { wbuf_align = MAX(wbuf_align, d.d_mem); wbuf_size = MIN(d.d_maxiosz, wbuf_size); wbuf_miniosize = MAX(d.d_miniosz, wbuf_miniosize); } } } else { char *lb[XFS_MAX_SECTORSIZE] = { NULL }; off64_t off; /* ensure device files are sufficiently large */ off = mp->m_sb.sb_dblocks * source_blocksize; off -= sizeof(lb); if (pwrite64(target[i].fd, lb, sizeof(lb), off) < 0) { do_log(_("%s: failed to write last block\n"), progname); do_log(_("\tIs target \"%s\" too small?\n"), target[i].name); die_perror(); } } } /* initialize locks and bufs */ if (pthread_mutex_init(&glob_masks.mutex, NULL) != 0) { do_log(_("Couldn't initialize global thread mask\n")); die_perror(); } glob_masks.num_working = 0; if (wbuf_init(&w_buf, wbuf_size, wbuf_align, wbuf_miniosize, 0) == NULL) { do_log(_("Error initializing wbuf 0\n")); die_perror(); } wblocks = wbuf_size / BBSIZE; if (wbuf_init(&btree_buf, MAX(source_blocksize, wbuf_miniosize), wbuf_align, wbuf_miniosize, 1) == NULL) { do_log(_("Error initializing btree buf 1\n")); die_perror(); } if (pthread_mutex_init(&mainwait,NULL) != 0) { do_log(_("Error creating first semaphore.\n")); die_perror(); exit(1); } /* need to start out blocking */ pthread_mutex_lock(&mainwait); /* set up sigchild signal handler */ signal(SIGCHLD, handler); sighold(SIGCHLD); /* make children */ if ((targ = malloc(num_targets * sizeof(thread_args))) == NULL) { do_log(_("Couldn't malloc space for thread args\n")); die_perror(); exit(1); } for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++) { if (!duplicate) platform_uuid_generate(&tcarg->uuid); else platform_uuid_copy(&tcarg->uuid, &mp->m_sb.sb_uuid); if (pthread_mutex_init(&tcarg->wait, NULL) != 0) { do_log(_("Error creating thread mutex %d\n"), i); die_perror(); exit(1); } /* need to start out blocking */ pthread_mutex_lock(&tcarg->wait); } for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++) { tcarg->id = i; tcarg->fd = target[i].fd; target[i].state = ACTIVE; num_threads++; if (pthread_create(&target[i].pid, NULL, begin_reader, (void *)tcarg)) { do_log(_("Error creating thread for target %d\n"), i); die_perror(); } } ASSERT(num_targets == num_threads); /* set up statistics */ num_ags = mp->m_sb.sb_agcount; init_bar(mp->m_sb.sb_blocksize / BBSIZE * ((__uint64_t)mp->m_sb.sb_dblocks - (__uint64_t)mp->m_sb.sb_fdblocks + 10 * num_ags)); kids = num_targets; block = (struct xfs_btree_block *) btree_buf.data; for (agno = 0; agno < num_ags && kids > 0; agno++) { /* read in first blocks of the ag */ read_ag_header(source_fd, agno, &w_buf, &ag_hdr, mp, source_blocksize, source_sectorsize); /* set the in_progress bit for the first AG */ if (agno == 0) ag_hdr.xfs_sb->sb_inprogress = 1; /* save what we need (agf) in the btree buffer */ memmove(btree_buf.data, ag_hdr.xfs_agf, source_sectorsize); ag_hdr.xfs_agf = (xfs_agf_t *) btree_buf.data; btree_buf.length = source_blocksize; /* write the ag header out */ write_wbuf(); /* traverse btree until we get to the leftmost leaf node */ bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]); current_level = 0; btree_levels = be32_to_cpu(ag_hdr.xfs_agf-> agf_levels[XFS_BTNUM_BNOi]); ag_end = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1) + source_blocksize / BBSIZE; for (;;) { /* none of this touches the w_buf buffer */ ASSERT(current_level < btree_levels); current_level++; btree_buf.position = pos = (xfs_off_t) XFS_AGB_TO_DADDR(mp,agno,bno) << BBSHIFT; btree_buf.length = source_blocksize; read_wbuf(source_fd, &btree_buf, mp); block = (struct xfs_btree_block *) ((char *)btree_buf.data + pos - btree_buf.position); ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); if (be16_to_cpu(block->bb_level) == 0) break; ptr = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); bno = be32_to_cpu(ptr[0]); } /* align first data copy but don't overwrite ag header */ pos = w_buf.position >> BBSHIFT; length = w_buf.length >> BBSHIFT; next_begin = pos + length; ag_begin = next_begin; ASSERT(w_buf.position % source_sectorsize == 0); /* handle the rest of the ag */ for (;;) { if (be16_to_cpu(block->bb_level) != 0) { do_log( _("WARNING: source filesystem inconsistent.\n")); do_log( _(" A leaf btree rec isn't a leaf. Aborting now.\n")); exit(1); } rec_ptr = XFS_ALLOC_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++, rec_ptr++) { /* calculate in daddr's */ begin = next_begin; /* * protect against pathological case of a * hole right after the ag header in a * mis-aligned case */ if (begin < ag_begin) begin = ag_begin; /* * round size up to ensure we copy a * range bigger than required */ sizeb = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock)) - begin; size = roundup(sizeb < 0) { /* copy extent */ w_buf.position = (xfs_off_t) begin << BBSHIFT; while (size > 0) { /* * let lower layer do alignment */ if (size > w_buf.size) { w_buf.length = w_buf.size; size -= w_buf.size; sizeb -= wblocks; numblocks += wblocks; } else { w_buf.length = size; numblocks += sizeb; size = 0; } read_wbuf(source_fd, &w_buf, mp); write_wbuf(); w_buf.position += w_buf.length; howfar = bump_bar( howfar, numblocks); } } /* round next starting point down */ new_begin = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock) + be32_to_cpu(rec_ptr->ar_blockcount)); next_begin = rounddown(new_begin, w_buf.min_io_size >> BBSHIFT); } if (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK) break; /* read in next btree record block */ btree_buf.position = pos = (xfs_off_t) XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu( block->bb_u.s.bb_rightsib)) << BBSHIFT; btree_buf.length = source_blocksize; /* let read_wbuf handle alignment */ read_wbuf(source_fd, &btree_buf, mp); block = (struct xfs_btree_block *) ((char *) btree_buf.data + pos - btree_buf.position); ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); } /* * write out range of used blocks after last range * of free blocks in AG */ if (next_begin < ag_end) { begin = next_begin; sizeb = ag_end - begin; size = roundup(sizeb << BBSHIFT, wbuf_miniosize); if (size > 0) { /* copy extent */ w_buf.position = (xfs_off_t) begin << BBSHIFT; while (size > 0) { /* * let lower layer do alignment */ if (size > w_buf.size) { w_buf.length = w_buf.size; size -= w_buf.size; sizeb -= wblocks; numblocks += wblocks; } else { w_buf.length = size; numblocks += sizeb; size = 0; } read_wbuf(source_fd, &w_buf, mp); write_wbuf(); w_buf.position += w_buf.length; howfar = bump_bar(howfar, numblocks); } } } } if (kids > 0) { if (!duplicate) { /* write a clean log using the specified UUID */ for (j = 0, tcarg = targ; j < num_targets; j++) { w_buf.owner = tcarg; w_buf.length = rounddown(w_buf.size, w_buf.min_io_size); pos = write_log_header( source_fd, &w_buf, mp); end_pos = write_log_trailer( source_fd, &w_buf, mp); w_buf.position = pos; memset(w_buf.data, 0, w_buf.length); while (w_buf.position < end_pos) { do_write(tcarg); w_buf.position += w_buf.length; } tcarg++; } } else { num_ags = 1; } /* reread and rewrite superblocks (UUID and in-progress) */ /* [backwards, so inprogress bit only updated when done] */ for (i = num_ags - 1; i >= 0; i--) { read_ag_header(source_fd, i, &w_buf, &ag_hdr, mp, source_blocksize, source_sectorsize); if (i == 0) ag_hdr.xfs_sb->sb_inprogress = 0; /* do each thread in turn, each has its own UUID */ for (j = 0, tcarg = targ; j < num_targets; j++) { platform_uuid_copy(&ag_hdr.xfs_sb->sb_uuid, &tcarg->uuid); do_write(tcarg); tcarg++; } } bump_bar(100, 0); } check_errors(); killall(); pthread_exit(NULL); /*NOTREACHED*/ return 0; } xfs_caddr_t next_log_chunk(xfs_caddr_t p, int offset, void *private) { wbuf *buf = (wbuf *)private; if (buf->length < (int)(p - buf->data) + offset) { /* need to flush this one, then start afresh */ do_write(buf->owner); memset(buf->data, 0, buf->length); return buf->data; } return p + offset; } /* * Writes a log header at the start of the log (with the real * filesystem UUID embedded into it), and writes to all targets. * * Returns the next buffer-length-aligned disk address. */ xfs_off_t write_log_header(int fd, wbuf *buf, xfs_mount_t *mp) { xfs_caddr_t p = buf->data; xfs_off_t logstart; int offset; logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart) << BBSHIFT; buf->position = rounddown(logstart, (xfs_off_t)buf->length); memset(p, 0, buf->size); if (logstart % buf->length) { /* unaligned */ read_wbuf(fd, buf, mp); offset = logstart - buf->position; p += offset; memset(p, 0, buf->length - offset); } offset = libxfs_log_header(p, &buf->owner->uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, next_log_chunk, buf); do_write(buf->owner); return roundup(logstart + offset, buf->length); } /* * May do an aligned read of the last buffer in the log (& zero * the start of that buffer). Returns the disk address at the * end of last aligned buffer in the log. */ xfs_off_t write_log_trailer(int fd, wbuf *buf, xfs_mount_t *mp) { xfs_off_t logend; int offset; logend = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart) << BBSHIFT; logend += XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks); buf->position = rounddown(logend, (xfs_off_t)buf->length); if (logend % buf->length) { /* unaligned */ read_wbuf(fd, buf, mp); offset = (int)(logend - buf->position); memset(buf->data, 0, offset); do_write(buf->owner); } return buf->position; } xfsprogs-3.1.9ubuntu2/release.sh0000775000000000000000000000110511650373061013572 0ustar #!/bin/bash # # Automate generation a new release # . ./VERSION version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION} date=`date +"%-d %B %Y"` echo "Updating CHANGES" sed -e "s/${version}.*/${version} (${date})/" doc/CHANGES > doc/CHANGES.tmp && \ mv doc/CHANGES.tmp doc/CHANGES echo "Commiting CHANGES update to git" git commit -s -a -m "${version} release" echo "Tagging git repository" git tag -s -a -m "${version} release" v${version} echo "Done. Please remember to push out tags using \"git push --tags\"" echo "If you wish to create a source tarball, run \"make dist\"" xfsprogs-3.1.9ubuntu2/mdrestore/0000775000000000000000000000000012062211564013617 5ustar xfsprogs-3.1.9ubuntu2/mdrestore/Makefile0000664000000000000000000000070011352300766015260 0ustar # # Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_mdrestore CFILES = xfs_mdrestore.c LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) LLDFLAGS = -static default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/mdrestore/xfs_mdrestore.c0000664000000000000000000001460411140033220016637 0ustar /* * Copyright (c) 2007 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "xfs_metadump.h" char *progname; int show_progress = 0; int progress_since_warning = 0; static void fatal(const char *msg, ...) { va_list args; va_start(args, msg); fprintf(stderr, "%s: ", progname); vfprintf(stderr, msg, args); exit(1); } static void print_progress(const char *fmt, ...) { char buf[60]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); buf[sizeof(buf)-1] = '\0'; printf("\r%-59s", buf); fflush(stdout); progress_since_warning = 1; } static void perform_restore( FILE *src_f, int dst_fd, int is_target_file) { xfs_metablock_t *metablock; /* header + index + blocks */ __be64 *block_index; char *block_buffer; int block_size; int max_indicies; int cur_index; int mb_count; xfs_metablock_t tmb; xfs_sb_t sb; __int64_t bytes_read; /* * read in first blocks (superblock 0), set "inprogress" flag for it, * read in the rest of the file, and if complete, clear SB 0's * "inprogress flag" */ if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) fatal("specified file is not a metadata dump\n"); block_size = 1 << tmb.mb_blocklog; max_indicies = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); metablock = (xfs_metablock_t *)calloc(max_indicies + 1, block_size); if (metablock == NULL) fatal("memory allocation failure\n"); mb_count = be16_to_cpu(tmb.mb_count); if (mb_count == 0 || mb_count > max_indicies) fatal("bad block count: %u\n", mb_count); block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t)); block_buffer = (char *)metablock + block_size; if (fread(block_index, block_size - sizeof(tmb), 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); if (block_index[0] != 0) fatal("first block is not the primary superblock\n"); if (fread(block_buffer, mb_count << tmb.mb_blocklog, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); libxfs_sb_from_disk(&sb, (xfs_dsb_t *)block_buffer); if (sb.sb_magicnum != XFS_SB_MAGIC) fatal("bad magic number for primary superblock\n"); ((xfs_dsb_t*)block_buffer)->sb_inprogress = 1; if (is_target_file) { /* ensure regular files are correctly sized */ if (ftruncate64(dst_fd, sb.sb_dblocks * sb.sb_blocksize)) fatal("cannot set filesystem image size: %s\n", strerror(errno)); } else { /* ensure device is sufficiently large enough */ char *lb[XFS_MAX_SECTORSIZE] = { NULL }; off64_t off; off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb); if (pwrite64(dst_fd, lb, sizeof(lb), off) < 0) fatal("failed to write last block, is target too " "small? (error: %s)\n", strerror(errno)); } bytes_read = 0; for (;;) { if (show_progress && (bytes_read & ((1 << 20) - 1)) == 0) print_progress("%lld MB read\n", bytes_read >> 20); for (cur_index = 0; cur_index < mb_count; cur_index++) { if (pwrite64(dst_fd, &block_buffer[cur_index << tmb.mb_blocklog], block_size, be64_to_cpu(block_index[cur_index]) << BBSHIFT) < 0) fatal("error writing block %llu: %s\n", be64_to_cpu(block_index[cur_index]) << BBSHIFT, strerror(errno)); } if (mb_count < max_indicies) break; if (fread(metablock, block_size, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); mb_count = be16_to_cpu(metablock->mb_count); if (mb_count == 0) break; if (mb_count > max_indicies) fatal("bad block count: %u\n", mb_count); if (fread(block_buffer, mb_count << tmb.mb_blocklog, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); bytes_read += block_size; } if (progress_since_warning) putchar('\n'); memset(block_buffer, 0, sb.sb_sectsize); sb.sb_inprogress = 0; libxfs_sb_to_disk((xfs_dsb_t *)block_buffer, &sb, XFS_SB_ALL_BITS); if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0) fatal("error writing primary superblock: %s\n", strerror(errno)); free(metablock); } static void usage(void) { fprintf(stderr, "Usage: %s [-bg] source target\n", progname); exit(1); } extern int platform_check_ismounted(char *, char *, struct stat64 *, int); int main( int argc, char **argv) { FILE *src_f; int dst_fd; int c; int open_flags; struct stat64 statbuf; int is_target_file; progname = basename(argv[0]); while ((c = getopt(argc, argv, "gV")) != EOF) { switch (c) { case 'g': show_progress = 1; break; case 'V': printf("%s version %s\n", progname, VERSION); exit(0); default: usage(); } } if (argc - optind != 2) usage(); /* open source */ if (strcmp(argv[optind], "-") == 0) { src_f = stdin; if (isatty(fileno(stdin))) fatal("cannot read from a terminal\n"); } else { src_f = fopen(argv[optind], "rb"); if (src_f == NULL) fatal("cannot open source dump file\n"); } optind++; /* check and open target */ open_flags = O_RDWR; is_target_file = 0; if (stat64(argv[optind], &statbuf) < 0) { /* ok, assume it's a file and create it */ open_flags |= O_CREAT; is_target_file = 1; } else if (S_ISREG(statbuf.st_mode)) { open_flags |= O_TRUNC; is_target_file = 1; } else { /* * check to make sure a filesystem isn't mounted on the device */ if (platform_check_ismounted(argv[optind], NULL, &statbuf, 0)) fatal("a filesystem is mounted on target device \"%s\"," " cannot restore to a mounted filesystem.\n", argv[optind]); } dst_fd = open(argv[optind], open_flags, 0644); if (dst_fd < 0) fatal("couldn't open target \"%s\"\n", argv[optind]); perform_restore(src_f, dst_fd, is_target_file); close(dst_fd); if (src_f != stdin) fclose(src_f); return 0; } xfsprogs-3.1.9ubuntu2/libxcmd/0000775000000000000000000000000012062211563013234 5ustar xfsprogs-3.1.9ubuntu2/libxcmd/Makefile0000664000000000000000000000127312062210562014675 0ustar # # Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTLIBRARY = libxcmd.la LT_CURRENT = 0 LT_REVISION = 0 LT_AGE = 0 CFILES = command.c input.c paths.c projects.c help.c quit.c ifeq ($(HAVE_GETMNTENT),yes) LCFLAGS += -DHAVE_GETMNTENT endif ifeq ($(HAVE_GETMNTINFO),yes) LCFLAGS += -DHAVE_GETMNTINFO endif ifeq ($(ENABLE_READLINE),yes) LCFLAGS += -DENABLE_READLINE LTLIBS += $(LIBREADLINE) $(LIBTERMCAP) endif ifeq ($(ENABLE_EDITLINE),yes) LCFLAGS += -DENABLE_EDITLINE LTLIBS += $(LIBEDITLINE) $(LIBTERMCAP) endif default: ltdepend $(LTLIBRARY) include $(BUILDRULES) install install-dev install-qa: default -include .ltdep xfsprogs-3.1.9ubuntu2/libxcmd/projects.c0000664000000000000000000000724011140033220015220 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #define PROJID "/etc/projid" #define PROJECT_PATHS "/etc/projects" char *projid_file; char *projects_file; static FILE *projects; static fs_project_t p; static char projects_buffer[512]; static FILE *project_paths; static fs_project_path_t pp; static char project_paths_buffer[1024]; void setprfiles(void) { if (!projid_file) projid_file = PROJID; if (!projects_file) projects_file = PROJECT_PATHS; } void setprent(void) { setprfiles(); projects = fopen(projid_file, "r"); } void setprpathent(void) { setprfiles(); project_paths = fopen(projects_file, "r"); } void endprent(void) { if (projects) fclose(projects); projects = NULL; } void endprpathent(void) { if (project_paths) fclose(project_paths); project_paths = NULL; } fs_project_t * getprent(void) { char *idstart, *idend; size_t size = sizeof(projects_buffer) - 1; if (!projects) return NULL; for (;;) { if (!fgets(projects_buffer, size, projects)) break; /* * /etc/projid file format -- "name:id\n", ignore "^#..." */ if (projects_buffer[0] == '#') continue; idstart = strchr(projects_buffer, ':'); if (!idstart) continue; if ((idstart + 1) - projects_buffer >= size) continue; idend = strchr(idstart+1, ':'); if (idend) *idend = '\0'; *idstart = '\0'; p.pr_prid = atoi(idstart+1); p.pr_name = &projects_buffer[0]; return &p; } return NULL; } fs_project_t * getprnam( char *name) { fs_project_t *p = NULL; setprent(); while ((p = getprent()) != NULL) if (strcmp(p->pr_name, name) == 0) break; endprent(); return p; } fs_project_t * getprprid( prid_t prid) { fs_project_t *p = NULL; setprent(); while ((p = getprent()) != NULL) if (p->pr_prid == prid) break; endprent(); return p; } fs_project_path_t * getprpathent(void) { char *nmstart, *nmend; size_t size = sizeof(project_paths_buffer) - 1; if (!project_paths) return NULL; for (;;) { if (!fgets(project_paths_buffer, size, project_paths)) break; /* * /etc/projects format -- "id:pathname\n", ignore "^#..." */ if (project_paths_buffer[0] == '#') continue; nmstart = strchr(project_paths_buffer, ':'); if (!nmstart) continue; if ((nmstart + 1) - project_paths_buffer >= size) continue; nmend = strchr(nmstart + 1, '\n'); if (nmend) *nmend = '\0'; *nmstart = '\0'; pp.pp_pathname = nmstart + 1; pp.pp_prid = atoi(&project_paths_buffer[0]); return &pp; } return NULL; } int getprojid( const char *name, int fd, prid_t *projid) { struct fsxattr fsx; if (xfsctl(name, fd, XFS_IOC_FSGETXATTR, &fsx)) { perror("XFS_IOC_FSGETXATTR"); return -1; } *projid = fsx.fsx_projid; return 0; } int setprojid( const char *name, int fd, prid_t projid) { struct fsxattr fsx; int error; if ((error = xfsctl(name, fd, XFS_IOC_FSGETXATTR, &fsx)) == 0) { fsx.fsx_projid = projid; error = xfsctl(name, fd, XFS_IOC_FSSETXATTR, &fsx); } return error; } xfsprogs-3.1.9ubuntu2/libxcmd/quit.c0000664000000000000000000000214411604735741014375 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include static cmdinfo_t quit_cmd; /* ARGSUSED */ static int quit_f( int argc, char **argv) { return 1; } void quit_init(void) { quit_cmd.name = "quit"; quit_cmd.altname = "q"; quit_cmd.cfunc = quit_f; quit_cmd.argmin = -1; quit_cmd.argmax = -1; quit_cmd.flags = CMD_FLAG_GLOBAL; quit_cmd.oneline = _("exit the program"); add_command(&quit_cmd); } xfsprogs-3.1.9ubuntu2/libxcmd/paths.c0000664000000000000000000002506611650373061014534 0ustar /* * Copyright (c) 2005-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include extern char *progname; int fs_count; struct fs_path *fs_table; struct fs_path *fs_path; char *mtab_file; #define PROC_MOUNTS "/proc/self/mounts" static int fs_device_number( const char *name, dev_t *devnum) { struct stat64 sbuf; if (stat64(name, &sbuf) < 0) return errno; /* * We want to match st_rdev if the path provided is a device * special file. Otherwise we are looking for the the * device id for the containing filesystem, in st_dev. */ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) *devnum = sbuf.st_rdev; else *devnum = sbuf.st_dev; return 0; } /* * Find the FS table entry for the given path. The "flags" argument * is a mask containing FS_MOUNT_POINT or FS_PROJECT_PATH (or both) * to indicate the type of table entry sought. */ struct fs_path * fs_table_lookup( const char *dir, uint flags) { uint i; dev_t dev = 0; if (fs_device_number(dir, &dev)) return NULL; for (i = 0; i < fs_count; i++) { if (flags && !(flags & fs_table[i].fs_flags)) continue; if (fs_table[i].fs_datadev == dev) return &fs_table[i]; } return NULL; } static int fs_table_insert( char *dir, uint prid, uint flags, char *fsname, char *fslog, char *fsrt) { dev_t datadev, logdev, rtdev; struct fs_path *tmp_fs_table; int error; datadev = logdev = rtdev = 0; error = fs_device_number(dir, &datadev); if (error) goto out_nodev; if (fslog) { error = fs_device_number(fslog, &logdev); if (error) goto out_nodev; } if (fsrt) { error = fs_device_number(fsrt, &rtdev); if (error) goto out_nodev; } /* * Make copies of the directory and data device path. * The log device and real-time device, if non-null, * are already the result of strdup() calls so we * don't need to duplicate those. In fact, this * function is assumed to "consume" both of those * pointers, meaning if an error occurs they will * both get freed. */ error = ENOMEM; dir = strdup(dir); if (!dir) goto out_nodev; fsname = strdup(fsname); if (!fsname) goto out_noname; tmp_fs_table = realloc(fs_table, sizeof(fs_path_t) * (fs_count + 1)); if (!tmp_fs_table) goto out_norealloc; fs_table = tmp_fs_table; fs_path = &fs_table[fs_count]; fs_path->fs_dir = dir; fs_path->fs_prid = prid; fs_path->fs_flags = flags; fs_path->fs_name = fsname; fs_path->fs_log = fslog; fs_path->fs_rt = fsrt; fs_path->fs_datadev = datadev; fs_path->fs_logdev = logdev; fs_path->fs_rtdev = rtdev; fs_count++; return 0; out_norealloc: free(fsname); out_noname: free(dir); out_nodev: /* "Consume" fslog and fsrt even if there's an error */ free(fslog); free(fsrt); return error; } /* * Table iteration (cursor-based) interfaces */ /* * Initialize an fs_table cursor. If a directory path is supplied, * the cursor is set up to appear as though the table contains only * a single entry which represents the directory specified. * Otherwise it is set up to prepare for visiting all entries in the * global table, starting with the first. "flags" can be either * FS_MOUNT_POINT or FS_PROJECT_PATH to limit what type of entries * will be selected by fs_cursor_next_entry(). 0 can be used as a * wild card (selecting either type). */ void fs_cursor_initialise( char *dir, uint flags, fs_cursor_t *cur) { fs_path_t *path; memset(cur, 0, sizeof(*cur)); if (dir) { if ((path = fs_table_lookup(dir, flags)) == NULL) return; cur->local = *path; cur->count = 1; cur->table = &cur->local; } else { cur->count = fs_count; cur->table = fs_table; } cur->flags = flags; } /* * Use the cursor to find the next entry in the table having the * type specified by the cursor's "flags" field. */ struct fs_path * fs_cursor_next_entry( fs_cursor_t *cur) { while (cur->index < cur->count) { fs_path_t *next = &cur->table[cur->index++]; if (!cur->flags || (cur->flags & next->fs_flags)) return next; } return NULL; } #if defined(HAVE_GETMNTENT) #include /* * Determines whether the "logdev" or "rtdev" mount options are * present for the given mount point. If so, the value for each (a * device path) is returned in the pointers whose addresses are * provided. The pointers are assigned NULL for an option not * present. Note that the path buffers returned are allocated * dynamically and it is the caller's responsibility to free them. */ static int fs_extract_mount_options( struct mntent *mnt, char **logp, char **rtp) { char *fslog, *fsrt; /* Extract log device and realtime device from mount options */ if ((fslog = hasmntopt(mnt, "logdev="))) fslog += 7; if ((fsrt = hasmntopt(mnt, "rtdev="))) fsrt += 6; /* Do this only after we've finished processing mount options */ if (fslog) { fslog = strndup(fslog, strcspn(fslog, " ,")); if (!fslog) goto out_nomem; } if (fsrt) { fsrt = strndup(fsrt, strcspn(fsrt, " ,")); if (!fsrt) { free(fslog); goto out_nomem; } } *logp = fslog; *rtp = fsrt; return 0; out_nomem: *logp = NULL; *rtp = NULL; fprintf(stderr, _("%s: unable to extract mount options for \"%s\"\n"), progname, mnt->mnt_dir); return ENOMEM; } static int fs_table_initialise_mounts( char *path) { struct mntent *mnt; FILE *mtp; char *fslog, *fsrt; int error, found; error = found = 0; fslog = fsrt = NULL; if (!mtab_file) { mtab_file = PROC_MOUNTS; if (access(mtab_file, R_OK) != 0) mtab_file = MOUNTED; } if ((mtp = setmntent(mtab_file, "r")) == NULL) return ENOENT; while ((mnt = getmntent(mtp)) != NULL) { if (strcmp(mnt->mnt_type, "xfs") != 0) continue; if (path && ((strcmp(path, mnt->mnt_dir) != 0) && (strcmp(path, mnt->mnt_fsname) != 0))) continue; if (fs_extract_mount_options(mnt, &fslog, &fsrt)) continue; (void) fs_table_insert(mnt->mnt_dir, 0, FS_MOUNT_POINT, mnt->mnt_fsname, fslog, fsrt); if (path) { found = 1; break; } } endmntent(mtp); if (path && !found) error = ENXIO; return error; } #elif defined(HAVE_GETMNTINFO) #include static int fs_table_initialise_mounts( char *path) { struct statfs *stats; int i, count, error, found; error = found = 0; if ((count = getmntinfo(&stats, 0)) < 0) { fprintf(stderr, _("%s: getmntinfo() failed: %s\n"), progname, strerror(errno)); return 0; } for (i = 0; i < count; i++) { if (strcmp(stats[i].f_fstypename, "xfs") != 0) continue; if (path && ((strcmp(path, stats[i].f_mntonname) != 0) && (strcmp(path, stats[i].f_mntfromname) != 0))) continue; /* TODO: external log and realtime device? */ (void) fs_table_insert(stats[i].f_mntonname, 0, FS_MOUNT_POINT, stats[i].f_mntfromname, NULL, NULL); if (path) { found = 1; break; } } if (path && !found) error = ENXIO; return error; } #else # error "How do I extract info about mounted filesystems on this platform?" #endif /* * Given a directory, match it up to a filesystem mount point. */ static struct fs_path * fs_mount_point_from_path( const char *dir) { fs_cursor_t cursor; fs_path_t *fs; dev_t dev = 0; if (fs_device_number(dir, &dev)) return NULL; fs_cursor_initialise(NULL, FS_MOUNT_POINT, &cursor); while ((fs = fs_cursor_next_entry(&cursor))) { if (fs->fs_datadev == dev) break; } return fs; } static void fs_table_insert_mount( char *mount) { int error; error = fs_table_initialise_mounts(mount); if (error) fprintf(stderr, _("%s: cannot setup path for mount %s: %s\n"), progname, mount, strerror(error)); } static int fs_table_initialise_projects( char *project) { fs_project_path_t *path; fs_path_t *fs; prid_t prid = 0; int error = 0, found = 0; if (project) prid = prid_from_string(project); setprpathent(); while ((path = getprpathent()) != NULL) { if (project && prid != path->pp_prid) continue; fs = fs_mount_point_from_path(path->pp_pathname); if (!fs) { fprintf(stderr, _("%s: cannot find mount point for path `%s': %s\n"), progname, path->pp_pathname, strerror(errno)); continue; } (void) fs_table_insert(path->pp_pathname, path->pp_prid, FS_PROJECT_PATH, fs->fs_name, NULL, NULL); if (project) { found = 1; break; } } endprpathent(); if (project && !found) error = ENOENT; return error; } static void fs_table_insert_project( char *project) { int error; error = fs_table_initialise_projects(project); if (error) fprintf(stderr, _("%s: cannot setup path for project %s: %s\n"), progname, project, strerror(error)); } /* * Initialize fs_table to contain the given set of mount points and * projects. If mount_count is zero, mounts is ignored and the * table is populated with mounted filesystems. If project_count is * zero, projects is ignored and the table is populated with all * projects defined in the projects file. */ void fs_table_initialise( int mount_count, char *mounts[], int project_count, char *projects[]) { int error; int i; if (mount_count) { for (i = 0; i < mount_count; i++) fs_table_insert_mount(mounts[i]); } else { error = fs_table_initialise_mounts(NULL); if (error) goto out_error; } if (project_count) { for (i = 0; i < project_count; i++) fs_table_insert_project(projects[i]); } else { error = fs_table_initialise_projects(NULL); if (error) goto out_error; } return; out_error: fprintf(stderr, _("%s: cannot initialise path table: %s\n"), progname, strerror(error)); } void fs_table_insert_project_path( char *dir, prid_t prid) { fs_path_t *fs; int error = 0; fs = fs_mount_point_from_path(dir); if (fs) error = fs_table_insert(dir, prid, FS_PROJECT_PATH, fs->fs_name, NULL, NULL); else error = ENOENT; if (error) { fprintf(stderr, _("%s: cannot setup path for project dir %s: %s\n"), progname, dir, strerror(error)); exit(1); } } xfsprogs-3.1.9ubuntu2/libxcmd/command.c0000664000000000000000000000737511140033220015016 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include cmdinfo_t *cmdtab; int ncmds; static argsfunc_t args_func; static checkfunc_t check_func; static int ncmdline; static char **cmdline; static int compare(const void *a, const void *b) { return strcmp(((const cmdinfo_t *)a)->name, ((const cmdinfo_t *)b)->name); } void add_command( const cmdinfo_t *ci) { cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); cmdtab[ncmds - 1] = *ci; qsort(cmdtab, ncmds, sizeof(*cmdtab), compare); } static int check_command( const cmdinfo_t *ci) { if (check_func) return check_func(ci); return 1; } void add_check_command( checkfunc_t cf) { check_func = cf; } int command_usage( const cmdinfo_t *ci) { printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline); return 0; } int command( const cmdinfo_t *ct, int argc, char **argv) { char *cmd = argv[0]; if (!check_command(ct)) return 0; if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) { if (ct->argmax == -1) fprintf(stderr, _("bad argument count %d to %s, expected at least %d arguments\n"), argc-1, cmd, ct->argmin); else if (ct->argmin == ct->argmax) fprintf(stderr, _("bad argument count %d to %s, expected %d arguments\n"), argc-1, cmd, ct->argmin); else fprintf(stderr, _("bad argument count %d to %s, expected between %d and %d arguments\n"), argc-1, cmd, ct->argmin, ct->argmax); return 0; } platform_getoptreset(); return ct->cfunc(argc, argv); } const cmdinfo_t * find_command( const char *cmd) { cmdinfo_t *ct; for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) { if (strcmp(ct->name, cmd) == 0 || (ct->altname && strcmp(ct->altname, cmd) == 0)) return (const cmdinfo_t *)ct; } return NULL; } void add_user_command(char *optarg) { ncmdline++; cmdline = realloc(cmdline, sizeof(char*) * (ncmdline)); if (!cmdline) { perror("realloc"); exit(1); } cmdline[ncmdline-1] = optarg; } static int args_command( int index) { if (args_func) return args_func(index); return 0; } void add_args_command( argsfunc_t af) { args_func = af; } void command_loop(void) { int c, i, j = 0, done = 0; char *input; char **v; const cmdinfo_t *ct; for (i = 0; !done && i < ncmdline; i++) { input = strdup(cmdline[i]); if (!input) { fprintf(stderr, _("cannot strdup command '%s': %s\n"), cmdline[i], strerror(errno)); exit(1); } v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) { if (ct->flags & CMD_FLAG_GLOBAL) done = command(ct, c, v); else { j = 0; while (!done && (j = args_command(j))) done = command(ct, c, v); } } else fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } doneline(input, v); } if (cmdline) { free(cmdline); return; } while (!done) { if ((input = fetchline()) == NULL) break; v = breakline(input, &c); if (c) { ct = find_command(v[0]); if (ct) done = command(ct, c, v); else fprintf(stderr, _("command \"%s\" not found\n"), v[0]); } doneline(input, v); } } xfsprogs-3.1.9ubuntu2/libxcmd/input.c0000664000000000000000000002105611466226660014556 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #if defined(ENABLE_READLINE) # include # include #elif defined(ENABLE_EDITLINE) # include #endif extern char *progname; static char * get_prompt(void) { static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ]; if (!prompt[0]) snprintf(prompt, sizeof(prompt), "%s> ", progname); return prompt; } #if defined(ENABLE_READLINE) char * fetchline(void) { char *line; line = readline(get_prompt()); if (line && *line) add_history(line); return line; } #elif defined(ENABLE_EDITLINE) static char *el_get_prompt(EditLine *e) { return get_prompt(); } char * fetchline(void) { static EditLine *el; static History *hist; HistEvent hevent; char *line; int count; if (!el) { hist = history_init(); history(hist, &hevent, H_SETSIZE, 100); el = el_init(progname, stdin, stdout, stderr); el_source(el, NULL); el_set(el, EL_SIGNAL, 1); el_set(el, EL_PROMPT, el_get_prompt); el_set(el, EL_HIST, history, (const char *)hist); } line = strdup(el_gets(el, &count)); if (line) { if (count > 0) line[count-1] = '\0'; if (*line) history(hist, &hevent, H_ENTER, line); } return line; } #else # define MAXREADLINESZ 1024 char * fetchline(void) { char *p, *line = malloc(MAXREADLINESZ); if (!line) return NULL; printf(get_prompt()); fflush(stdout); if (!fgets(line, MAXREADLINESZ, stdin)) { free(line); return NULL; } p = line + strlen(line); if (p != line && p[-1] == '\n') p[-1] = '\0'; return line; } #endif char ** breakline( char *input, int *count) { int c = 0; char *p; char **rval = calloc(sizeof(char *), 1); while (rval && (p = strsep(&input, " ")) != NULL) { if (!*p) continue; c++; rval = realloc(rval, sizeof(*rval) * (c + 1)); if (!rval) { c = 0; break; } rval[c - 1] = p; rval[c] = NULL; } *count = c; return rval; } void doneline( char *input, char **vec) { free(input); free(vec); } #define EXABYTES(x) ((long long)(x) << 60) #define PETABYTES(x) ((long long)(x) << 50) #define TERABYTES(x) ((long long)(x) << 40) #define GIGABYTES(x) ((long long)(x) << 30) #define MEGABYTES(x) ((long long)(x) << 20) #define KILOBYTES(x) ((long long)(x) << 10) long long cvtnum( size_t blocksize, size_t sectorsize, char *s) { long long i; char *sp; int c; i = strtoll(s, &sp, 0); if (i == 0 && sp == s) return -1LL; if (*sp == '\0') return i; if (sp[1] != '\0') return -1LL; c = tolower(*sp); switch (c) { case 'b': return i * blocksize; case 's': return i * sectorsize; case 'k': return KILOBYTES(i); case 'm': return MEGABYTES(i); case 'g': return GIGABYTES(i); case 't': return TERABYTES(i); case 'p': return PETABYTES(i); case 'e': return EXABYTES(i); } return -1LL; } #define TO_EXABYTES(x) ((x) / EXABYTES(1)) #define TO_PETABYTES(x) ((x) / PETABYTES(1)) #define TO_TERABYTES(x) ((x) / TERABYTES(1)) #define TO_GIGABYTES(x) ((x) / GIGABYTES(1)) #define TO_MEGABYTES(x) ((x) / MEGABYTES(1)) #define TO_KILOBYTES(x) ((x) / KILOBYTES(1)) void cvtstr( double value, char *str, size_t size) { char *fmt; int precise; precise = ((double)value * 1000 == (double)(int)value * 1000); if (value >= EXABYTES(1)) { fmt = precise ? "%.f EiB" : "%.3f EiB"; snprintf(str, size, fmt, TO_EXABYTES(value)); } else if (value >= PETABYTES(1)) { fmt = precise ? "%.f PiB" : "%.3f PiB"; snprintf(str, size, fmt, TO_PETABYTES(value)); } else if (value >= TERABYTES(1)) { fmt = precise ? "%.f TiB" : "%.3f TiB"; snprintf(str, size, fmt, TO_TERABYTES(value)); } else if (value >= GIGABYTES(1)) { fmt = precise ? "%.f GiB" : "%.3f GiB"; snprintf(str, size, fmt, TO_GIGABYTES(value)); } else if (value >= MEGABYTES(1)) { fmt = precise ? "%.f MiB" : "%.3f MiB"; snprintf(str, size, fmt, TO_MEGABYTES(value)); } else if (value >= KILOBYTES(1)) { fmt = precise ? "%.f KiB" : "%.3f KiB"; snprintf(str, size, fmt, TO_KILOBYTES(value)); } else { snprintf(str, size, "%f bytes", value); } } #define MINUTES_TO_SECONDS(m) ((m) * 60) #define HOURS_TO_SECONDS(h) ((h) * MINUTES_TO_SECONDS(60)) #define DAYS_TO_SECONDS(d) ((d) * HOURS_TO_SECONDS(24)) #define WEEKS_TO_SECONDS(w) ((w) * DAYS_TO_SECONDS(7)) unsigned long cvttime( char *s) { unsigned long i; char *sp; i = strtoul(s, &sp, 0); if (i == 0 && sp == s) return 0; if (*sp == '\0') return i; if ((*sp == 'm' && sp[1] == '\0') || (strcmp(sp, "minutes") == 0) || (strcmp(sp, "minute") == 0)) return MINUTES_TO_SECONDS(i); if ((*sp == 'h' && sp[1] == '\0') || (strcmp(sp, "hours") == 0) || (strcmp(sp, "hour") == 0)) return HOURS_TO_SECONDS(i); if ((*sp == 'd' && sp[1] == '\0') || (strcmp(sp, "days") == 0) || (strcmp(sp, "day") == 0)) return DAYS_TO_SECONDS(i); if ((*sp == 'w' && sp[1] == '\0') || (strcmp(sp, "weeks") == 0) || (strcmp(sp, "week") == 0)) return WEEKS_TO_SECONDS(i); return 0; } struct timeval tadd(struct timeval t1, struct timeval t2) { t1.tv_usec += t2.tv_usec; if (t1.tv_usec > 1000000) { t1.tv_usec -= 1000000; t1.tv_sec++; } t1.tv_sec += t2.tv_sec; return t1; } struct timeval tsub(struct timeval t1, struct timeval t2) { t1.tv_usec -= t2.tv_usec; if (t1.tv_usec < 0) { t1.tv_usec += 1000000; t1.tv_sec--; } t1.tv_sec -= t2.tv_sec; return t1; } double tdiv(double value, struct timeval tv) { return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0)); } #define HOURS(sec) ((sec) / (60 * 60)) #define MINUTES(sec) (((sec) % (60 * 60)) / 60) #define SECONDS(sec) ((sec) % 60) void timestr( struct timeval *tv, char *ts, size_t size, int format) { double usec = (double)tv->tv_usec / 1000000.0; if (format & TERSE_FIXED_TIME) { if (!HOURS(tv->tv_sec)) { snprintf(ts, size, "%u:%02u.%02u", (unsigned int) MINUTES(tv->tv_sec), (unsigned int) SECONDS(tv->tv_sec), (unsigned int) usec * 100); return; } format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */ } if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) { snprintf(ts, size, "%u:%02u:%02u.%02u", (unsigned int) HOURS(tv->tv_sec), (unsigned int) MINUTES(tv->tv_sec), (unsigned int) SECONDS(tv->tv_sec), (unsigned int) usec * 100); } else { snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000); } } /* * Convert from arbitrary user strings into a numeric ID. * If it's all numeric, we convert that inplace, else we do * the name lookup, and return the found identifier. */ prid_t prid_from_string( char *project) { fs_project_t *prj; unsigned long prid_long; char *sp; /* * Allow either a full numeric or a valid projectname, even * if it starts with a digit. */ prid_long = strtoul(project, &sp, 10); if (*project != '\0' && *sp == '\0') { if ((prid_long == ULONG_MAX && errno == ERANGE) || (prid_long > (prid_t)-1)) return -1; return (prid_t)prid_long; } prj = getprnam(project); if (prj) return prj->pr_prid; return -1; } uid_t uid_from_string( char *user) { struct passwd *pwd; unsigned long uid_long; char *sp; uid_long = strtoul(user, &sp, 10); if (sp != user) { if ((uid_long == ULONG_MAX && errno == ERANGE) || (uid_long > (uid_t)-1)) return -1; return (uid_t)uid_long; } pwd = getpwnam(user); if (pwd) return pwd->pw_uid; return -1; } gid_t gid_from_string( char *group) { struct group *grp; unsigned long gid_long; char *sp; gid_long = strtoul(group, &sp, 10); if (sp != group) { if ((gid_long == ULONG_MAX && errno == ERANGE) || (gid_long > (gid_t)-1)) return -1; return (gid_t)gid_long; } grp = getgrnam(group); if (grp) return grp->gr_gid; return -1; } #define HAVE_FTW_H 1 /* TODO: configure me */ #ifndef HAVE_FTW_H int nftw( char *dir, int (*fn)(const char *, const struct stat *, int, struct FTW *), int depth, int flags) { fprintf(stderr, "%s: not implemented, no recursion available\n", __FUNCTION__); return 0; } #endif xfsprogs-3.1.9ubuntu2/libxcmd/help.c0000664000000000000000000000403311604735741014342 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include static cmdinfo_t help_cmd; static void help_onecmd(const char *cmd, const cmdinfo_t *ct); static void help_oneline(const char *cmd, const cmdinfo_t *ct); static void help_all(void) { const cmdinfo_t *ct; for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) help_oneline(ct->name, ct); printf(_("\nUse 'help commandname' for extended help.\n")); } static int help_f( int argc, char **argv) { const cmdinfo_t *ct; if (argc == 1) { help_all(); return 0; } ct = find_command(argv[1]); if (ct == NULL) { printf(_("command %s not found\n"), argv[1]); return 0; } help_onecmd(argv[1], ct); return 0; } static void help_onecmd( const char *cmd, const cmdinfo_t *ct) { help_oneline(cmd, ct); if (ct->help) ct->help(); } static void help_oneline( const char *cmd, const cmdinfo_t *ct) { if (cmd) printf("%s ", cmd); else { printf("%s ", ct->name); if (ct->altname) printf("(or %s) ", ct->altname); } if (ct->args) printf("%s ", ct->args); printf("-- %s\n", ct->oneline); } void help_init(void) { help_cmd.name = "help"; help_cmd.altname = "?"; help_cmd.cfunc = help_f; help_cmd.argmin = 0; help_cmd.argmax = 1; help_cmd.flags = CMD_FLAG_GLOBAL; help_cmd.args = _("[command]"); help_cmd.oneline = _("help for one or all commands"); add_command(&help_cmd); } xfsprogs-3.1.9ubuntu2/growfs/0000775000000000000000000000000012062211564013122 5ustar xfsprogs-3.1.9ubuntu2/growfs/Makefile0000664000000000000000000000132511330256617014570 0ustar # # Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_growfs CFILES = xfs_growfs.c LLDLIBS = $(LIBXFS) $(LIBXCMD) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) ifeq ($(ENABLE_READLINE),yes) LLDLIBS += $(LIBREADLINE) $(LIBTERMCAP) endif ifeq ($(ENABLE_EDITLINE),yes) LLDLIBS += $(LIBEDITLINE) $(LIBTERMCAP) endif LTDEPENDENCIES = $(LIBXFS) $(LIBXCMD) LLDFLAGS = -static LSRCFILES = xfs_info.sh default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) $(INSTALL) -m 755 xfs_info.sh $(PKG_SBIN_DIR)/xfs_info install-dev: -include .dep xfsprogs-3.1.9ubuntu2/growfs/xfs_info.sh0000775000000000000000000000073011256276416015307 0ustar #!/bin/sh -f # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # OPTS="" USAGE="Usage: xfs_info [-V] [-t mtab] mountpoint" while getopts "t:V" c do case $c in t) OPTS="-t $OPTARG" ;; V) xfs_growfs -p xfs_info -V status=$? exit $status ;; *) echo $USAGE 1>&2 exit 2 ;; esac done set -- extra "$@" shift $OPTIND case $# in 1) xfs_growfs -p xfs_info -n $OPTS "$1" status=$? ;; *) echo $USAGE 1>&2 exit 2 ;; esac exit $status xfsprogs-3.1.9ubuntu2/growfs/xfs_growfs.c0000664000000000000000000003127511650373060015467 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include /* * When growing a filesystem, this is the most significant * bits we'll accept in the resulting inode numbers * without warning the user. */ #define XFS_MAX_INODE_SIG_BITS 32 static void usage(void) { fprintf(stderr, _( "Usage: %s [options] mountpoint\n\n\ Options:\n\ -d grow data/metadata section\n\ -l grow log section\n\ -r grow realtime section\n\ -n don't change anything, just show geometry\n\ -I allow inode numbers to exceed %d significant bits\n\ -i convert log from external to internal format\n\ -t alternate location for mount table (/etc/mtab)\n\ -x convert log from internal to external format\n\ -D size grow data/metadata section to size blks\n\ -L size grow/shrink log section to size blks\n\ -R size grow realtime section to size blks\n\ -e size set realtime extent size to size blks\n\ -m imaxpct set inode max percent to imaxpct\n\ -V print version information\n"), progname, XFS_MAX_INODE_SIG_BITS); exit(2); } void report_info( xfs_fsop_geom_t geo, char *mntpoint, int isint, char *logname, char *rtname, int lazycount, int dirversion, int logversion, int attrversion, int cimode) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"), mntpoint, geo.inodesize, geo.agcount, geo.agblocks, "", geo.sectsize, attrversion, "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, dirversion, geo.dirblocksize, cimode, isint ? _("internal") : logname ? logname : _("external"), geo.blocksize, geo.logblocks, logversion, "", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount, !geo.rtblocks ? _("none") : rtname ? rtname : _("external"), geo.rtextsize * geo.blocksize, (unsigned long long)geo.rtblocks, (unsigned long long)geo.rtextents); } int main(int argc, char **argv) { int aflag; /* fake flag, do all pieces */ int c; /* current option character */ long long ddsize; /* device size in 512-byte blocks */ int dflag; /* -d flag */ int attrversion;/* attribute version number */ int dirversion; /* directory version number */ int logversion; /* log version number */ long long dlsize; /* device size in 512-byte blocks */ long long drsize; /* device size in 512-byte blocks */ long long dsize; /* new data size in fs blocks */ int error; /* we have hit an error */ long esize; /* new rt extent size */ int ffd; /* mount point file descriptor */ xfs_fsop_geom_t geo; /* current fs geometry */ int iflag; /* -i flag */ int isint; /* log is currently internal */ int lflag; /* -l flag */ long long lsize; /* new log size in fs blocks */ int maxpct; /* -m flag value */ int mflag; /* -m flag */ int nflag; /* -n flag */ xfs_fsop_geom_t ngeo; /* new fs geometry */ int rflag; /* -r flag */ long long rsize; /* new rt size in fs blocks */ int ci; /* ASCII case-insensitive fs */ int lazycount; /* lazy superblock counters */ int xflag; /* -x flag */ char *fname; /* mount point name */ char *datadev; /* data device name */ char *logdev; /* log device name */ char *rtdev; /* RT device name */ fs_path_t *fs; /* mount point information */ libxfs_init_t xi; /* libxfs structure */ progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); maxpct = esize = 0; dsize = lsize = rsize = 0LL; aflag = dflag = iflag = lflag = mflag = nflag = rflag = xflag = 0; ci = 0; while ((c = getopt(argc, argv, "dD:e:ilL:m:np:rR:t:xV")) != EOF) { switch (c) { case 'D': dsize = strtoll(optarg, NULL, 10); /* fall through */ case 'd': dflag = 1; break; case 'e': esize = atol(optarg); rflag = 1; break; case 'i': lflag = iflag = 1; break; case 'L': lsize = strtoll(optarg, NULL, 10); /* fall through */ case 'l': lflag = 1; break; case 'm': mflag = 1; maxpct = atoi(optarg); break; case 'n': nflag = 1; break; case 'p': progname = optarg; break; case 'R': rsize = strtoll(optarg, NULL, 10); /* fall through */ case 'r': rflag = 1; break; case 't': mtab_file = optarg; break; case 'x': lflag = xflag = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': default: usage(); } } if (argc - optind != 1) usage(); if (iflag && xflag) usage(); if (dflag + lflag + rflag == 0) aflag = 1; fs_table_initialise(0, NULL, 0, NULL); fs = fs_table_lookup(argv[optind], FS_MOUNT_POINT); if (!fs) { fprintf(stderr, _("%s: %s is not a mounted XFS filesystem\n"), progname, argv[optind]); return 1; } fname = fs->fs_dir; datadev = fs->fs_name; logdev = fs->fs_log; rtdev = fs->fs_rt; ffd = open(fname, O_RDONLY); if (ffd < 0) { perror(fname); return 1; } if (!platform_test_xfs_fd(ffd)) { fprintf(stderr, _("%s: specified file " "[\"%s\"] is not on an XFS filesystem\n"), progname, fname); exit(1); } /* get the current filesystem size & geometry */ if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY, &geo) < 0) { /* * OK, new xfsctl barfed - back off and try earlier version * as we're probably running an older kernel version. * Only field added in the v2 geometry xfsctl is "logsunit" * so we'll zero that out for later display (as zero). */ geo.logsunit = 0; if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &geo) < 0) { fprintf(stderr, _( "%s: cannot determine geometry of filesystem" " mounted at %s: %s\n"), progname, fname, strerror(errno)); exit(1); } } isint = geo.logstart > 0; lazycount = geo.flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0; dirversion = geo.flags & XFS_FSOP_GEOM_FLAGS_DIRV2 ? 2 : 1; logversion = geo.flags & XFS_FSOP_GEOM_FLAGS_LOGV2 ? 2 : 1; attrversion = geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR2 ? 2 : \ (geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR ? 1 : 0); ci = geo.flags & XFS_FSOP_GEOM_FLAGS_DIRV2CI ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, ci); exit(0); } /* * Need root access from here on (using raw devices)... */ memset(&xi, 0, sizeof(xi)); xi.dname = datadev; xi.logname = logdev; xi.rtname = rtdev; xi.isreadonly = LIBXFS_ISREADONLY; if (!libxfs_init(&xi)) usage(); /* check we got the info for all the sections we are trying to modify */ if (!xi.ddev) { fprintf(stderr, _("%s: failed to access data device for %s\n"), progname, fname); exit(1); } if (lflag && !isint && !xi.logdev) { fprintf(stderr, _("%s: failed to access external log for %s\n"), progname, fname); exit(1); } if (rflag && !xi.rtdev) { fprintf(stderr, _("%s: failed to access realtime device for %s\n"), progname, fname); exit(1); } report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, ci); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : geo.logblocks * (geo.blocksize / BBSIZE) ); drsize = xi.rtsize; /* * Ok, Linux only has a 1024-byte resolution on device _size_, * and the sizes below are in basic 512-byte blocks, * so if we have (size % 2), on any partition, we can't get * to the last 512 bytes. Just chop it down by a block. */ ddsize -= (ddsize % 2); dlsize -= (dlsize % 2); drsize -= (drsize % 2); error = 0; if (dflag | aflag) { xfs_growfs_data_t in; if (!mflag) maxpct = geo.imaxpct; if (!dsize) dsize = ddsize / (geo.blocksize / BBSIZE); else if (dsize > ddsize / (geo.blocksize / BBSIZE)) { fprintf(stderr, _( "data size %lld too large, maximum is %lld\n"), (long long)dsize, (long long)(ddsize/(geo.blocksize/BBSIZE))); error = 1; } if (!error && dsize < geo.datablocks) { fprintf(stderr, _("data size %lld too small," " old size is %lld\n"), (long long)dsize, (long long)geo.datablocks); error = 1; } else if (!error && dsize == geo.datablocks && maxpct == geo.imaxpct) { if (dflag) fprintf(stderr, _( "data size unchanged, skipping\n")); if (mflag) fprintf(stderr, _( "inode max pct unchanged, skipping\n")); } else if (!error && !nflag) { in.newblocks = (__u64)dsize; in.imaxpct = (__u32)maxpct; if (xfsctl(fname, ffd, XFS_IOC_FSGROWFSDATA, &in) < 0) { if (errno == EWOULDBLOCK) fprintf(stderr, _( "%s: growfs operation in progress already\n"), progname); else fprintf(stderr, _( "%s: XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n"), progname, strerror(errno)); error = 1; } } } if (!error && (rflag | aflag)) { xfs_growfs_rt_t in; if (!esize) esize = (__u32)geo.rtextsize; if (!rsize) rsize = drsize / (geo.blocksize / BBSIZE); else if (rsize > drsize / (geo.blocksize / BBSIZE)) { fprintf(stderr, _( "realtime size %lld too large, maximum is %lld\n"), rsize, drsize / (geo.blocksize / BBSIZE)); error = 1; } if (!error && rsize < geo.rtblocks) { fprintf(stderr, _( "realtime size %lld too small, old size is %lld\n"), (long long)rsize, (long long)geo.rtblocks); error = 1; } else if (!error && rsize == geo.rtblocks) { if (rflag) fprintf(stderr, _( "realtime size unchanged, skipping\n")); } else if (!error && !nflag) { in.newblocks = (__u64)rsize; in.extsize = (__u32)esize; if (xfsctl(fname, ffd, XFS_IOC_FSGROWFSRT, &in) < 0) { if (errno == EWOULDBLOCK) fprintf(stderr, _( "%s: growfs operation in progress already\n"), progname); else if (errno == ENOSYS) fprintf(stderr, _( "%s: realtime growth not implemented\n"), progname); else fprintf(stderr, _( "%s: XFS_IOC_FSGROWFSRT xfsctl failed: %s\n"), progname, strerror(errno)); error = 1; } } } if (!error && (lflag | aflag)) { xfs_growfs_log_t in; if (!lsize) lsize = dlsize / (geo.blocksize / BBSIZE); if (iflag) in.isint = 1; else if (xflag) in.isint = 0; else in.isint = xi.logBBsize == 0; if (lsize == geo.logblocks && (in.isint == isint)) { if (lflag) fprintf(stderr, _("log size unchanged, skipping\n")); } else if (!nflag) { in.newblocks = (__u32)lsize; if (xfsctl(fname, ffd, XFS_IOC_FSGROWFSLOG, &in) < 0) { if (errno == EWOULDBLOCK) fprintf(stderr, _("%s: growfs operation in progress already\n"), progname); else if (errno == ENOSYS) fprintf(stderr, _("%s: log growth not supported yet\n"), progname); else fprintf(stderr, _("%s: XFS_IOC_FSGROWFSLOG xfsctl failed: %s\n"), progname, strerror(errno)); error = 1; } } } if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) { fprintf(stderr, _("%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n"), progname, strerror(errno)); exit(1); } if (geo.datablocks != ngeo.datablocks) printf(_("data blocks changed from %lld to %lld\n"), (long long)geo.datablocks, (long long)ngeo.datablocks); if (geo.imaxpct != ngeo.imaxpct) printf(_("inode max percent changed from %d to %d\n"), geo.imaxpct, ngeo.imaxpct); if (geo.logblocks != ngeo.logblocks) printf(_("log blocks changed from %d to %d\n"), geo.logblocks, ngeo.logblocks); if ((geo.logstart == 0) != (ngeo.logstart == 0)) printf(_("log changed from %s to %s\n"), geo.logstart ? _("internal") : _("external"), ngeo.logstart ? _("internal") : _("external")); if (geo.rtblocks != ngeo.rtblocks) printf(_("realtime blocks changed from %lld to %lld\n"), (long long)geo.rtblocks, (long long)ngeo.rtblocks); if (geo.rtextsize != ngeo.rtextsize) printf(_("realtime extent size changed from %d to %d\n"), geo.rtextsize, ngeo.rtextsize); exit(error); } xfsprogs-3.1.9ubuntu2/rtcp/0000775000000000000000000000000012062211564012563 5ustar xfsprogs-3.1.9ubuntu2/rtcp/Makefile0000664000000000000000000000056411330256617014235 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_rtcp CFILES = xfs_rtcp.c LLDFLAGS = -static default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/rtcp/xfs_rtcp.c0000664000000000000000000002061111650373061014562 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include int rtcp(char *, char *, int); int xfsrtextsize(char *path); int pflag; char *progname; void usage() { fprintf(stderr, _("%s [-e extsize] [-p] source target\n"), progname); exit(2); } int main(int argc, char **argv) { register int c, i, r, errflg = 0; struct stat64 s2; int extsize = - 1; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt(argc, argv, "pe:V")) != EOF) { switch (c) { case 'e': extsize = atoi(optarg); break; case 'p': pflag = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); default: errflg++; } } /* * Check for sufficient arguments or a usage error. */ argc -= optind; argv = &argv[optind]; if (argc < 2) { fprintf(stderr, _("%s: must specify files to copy\n"), progname); errflg++; } if (errflg) usage(); /* * If there is more than a source and target, * the last argument (the target) must be a directory * which really exists. */ if (argc > 2) { if (stat64(argv[argc-1], &s2) < 0) { fprintf(stderr, _("%s: stat64 of %s failed\n"), progname, argv[argc-1]); exit(2); } if (!S_ISDIR(s2.st_mode)) { fprintf(stderr, _("%s: final argument is not directory\n"), progname); usage(); } } /* * Perform a multiple argument rtcp by * multiple invocations of rtcp(). */ r = 0; for (i = 0; i < argc-1; i++) r += rtcp(argv[i], argv[argc-1], extsize); /* * Show errors by nonzero exit code. */ exit(r?2:0); } int rtcp( char *source, char *target, int fextsize) { int fromfd, tofd, readct, writect, iosz, reopen; int remove = 0, rtextsize; char *sp, *fbuf, *ptr; char tbuf[ PATH_MAX ]; struct stat64 s1, s2; struct fsxattr fsxattr; struct dioattr dioattr; /* * While source or target have trailing /, remove them * unless only "/". */ sp = source + strlen(source); if (sp) { while (*--sp == '/' && sp > source) *sp = '\0'; } sp = target + strlen(target); if (sp) { while (*--sp == '/' && sp > target) *sp = '\0'; } if ( stat64(source, &s1) ) { fprintf(stderr, _("%s: failed stat64 on %s: %s\n"), progname, source, strerror(errno)); return( -1); } /* * check for a realtime partition */ snprintf(tbuf, sizeof(tbuf), "%s", target); if ( stat64(target, &s2) ) { if (!S_ISDIR(s2.st_mode)) { /* take out target file name */ if ((ptr = strrchr(tbuf, '/')) != NULL) *ptr = '\0'; else snprintf(tbuf, sizeof(tbuf), "."); } } if ( (rtextsize = xfsrtextsize( tbuf )) <= 0 ) { fprintf(stderr, _("%s: %s filesystem has no realtime partition\n"), progname, tbuf); return( -1 ); } /* * check if target is a directory */ snprintf(tbuf, sizeof(tbuf), "%s", target); if ( !stat64(target, &s2) ) { if (S_ISDIR(s2.st_mode)) { snprintf(tbuf, sizeof(tbuf), "%s/%s", target, basename(source)); } } if ( stat64(tbuf, &s2) ) { /* * create the file if it does not exist */ if ( (tofd = open(tbuf, O_RDWR|O_CREAT|O_DIRECT, 0666)) < 0 ) { fprintf(stderr, _("%s: open of %s failed: %s\n"), progname, tbuf, strerror(errno)); return( -1 ); } remove = 1; /* * mark the file as a realtime file */ fsxattr.fsx_xflags = XFS_XFLAG_REALTIME; if (fextsize != -1 ) fsxattr.fsx_extsize = fextsize; else fsxattr.fsx_extsize = 0; if ( xfsctl(tbuf, tofd, XFS_IOC_FSSETXATTR, &fsxattr) ) { fprintf(stderr, _("%s: set attributes on %s failed: %s\n"), progname, tbuf, strerror(errno)); close( tofd ); unlink( tbuf ); return( -1 ); } } else { /* * open existing file */ if ( (tofd = open(tbuf, O_RDWR|O_DIRECT)) < 0 ) { fprintf(stderr, _("%s: open of %s failed: %s\n"), progname, tbuf, strerror(errno)); return( -1 ); } if ( xfsctl(tbuf, tofd, XFS_IOC_FSGETXATTR, &fsxattr) ) { fprintf(stderr, _("%s: get attributes of %s failed: %s\n"), progname, tbuf, strerror(errno)); close( tofd ); return( -1 ); } /* * check if the existing file is already a realtime file */ if ( !(fsxattr.fsx_xflags & XFS_XFLAG_REALTIME) ) { fprintf(stderr, _("%s: %s is not a realtime file.\n"), progname, tbuf); return( -1 ); } /* * check for matching extent size */ if ( (fextsize != -1) && (fsxattr.fsx_extsize != fextsize) ) { fprintf(stderr, _("%s: %s file extent size is %d, " "instead of %d.\n"), progname, tbuf, fsxattr.fsx_extsize, fextsize); return( -1 ); } } /* * open the source file */ reopen = 0; if ( (fromfd = open(source, O_RDONLY|O_DIRECT)) < 0 ) { fprintf(stderr, _("%s: open of %s source failed: %s\n"), progname, source, strerror(errno)); close( tofd ); if (remove) unlink( tbuf ); return( -1 ); } fsxattr.fsx_xflags = 0; fsxattr.fsx_extsize = 0; if ( xfsctl(source, fromfd, XFS_IOC_FSGETXATTR, &fsxattr) ) { reopen = 1; } else { if (! (fsxattr.fsx_xflags & XFS_XFLAG_REALTIME) ){ fprintf(stderr, _("%s: %s is not a realtime file.\n"), progname, source); reopen = 1; } } if (reopen) { close( fromfd ); if ( (fromfd = open(source, O_RDONLY )) < 0 ) { fprintf(stderr, _("%s: open of %s source failed: %s\n"), progname, source, strerror(errno)); close( tofd ); if (remove) unlink( tbuf ); return( -1 ); } } /* * get direct I/O parameters */ if ( xfsctl(tbuf, tofd, XFS_IOC_DIOINFO, &dioattr) ) { fprintf(stderr, _("%s: couldn't get direct I/O information: %s\n"), progname, strerror(errno)); close( fromfd ); close( tofd ); if ( remove ) unlink( tbuf ); return( -1 ); } if ( rtextsize % dioattr.d_miniosz ) { fprintf(stderr, _("%s: extent size %d not a multiple of %d.\n"), progname, rtextsize, dioattr.d_miniosz); close( fromfd ); close( tofd ); if ( remove ) unlink( tbuf ); return( -1 ); } /* * Check that the source file size is a multiple of the * file system block size. */ if ( s1.st_size % dioattr.d_miniosz ) { printf(_("The size of %s is not a multiple of %d.\n"), source, dioattr.d_miniosz); if ( pflag ) { printf(_("%s will be padded to %lld bytes.\n"), tbuf, (long long) (((s1.st_size / dioattr.d_miniosz) + 1) * dioattr.d_miniosz) ); } else { printf(_("Use the -p option to pad %s to a " "size which is a multiple of %d bytes.\n"), tbuf, dioattr.d_miniosz); close( fromfd ); close( tofd ); if ( remove ) unlink( tbuf ); return( -1 ); } } iosz = dioattr.d_miniosz; fbuf = memalign( dioattr.d_mem, iosz); memset(fbuf, 0, iosz); /* * read the entire source file */ while ( ( readct = read( fromfd, fbuf, iosz) ) != 0 ) { /* * if there is a read error - break */ if (readct < 0 ) { break; } /* * if there is a short read, pad to a block boundary */ if ( readct != iosz ) { if ( (readct % dioattr.d_miniosz) != 0 ) { readct = ( (readct/dioattr.d_miniosz) + 1 ) * dioattr.d_miniosz; } } /* * write to target file */ writect = write( tofd, fbuf, readct); if ( writect != readct ) { fprintf(stderr, _("%s: write error: %s\n"), progname, strerror(errno)); close(fromfd); close(tofd); free( fbuf ); return( -1 ); } memset( fbuf, 0, iosz); } close(fromfd); close(tofd); free( fbuf ); return( 0 ); } /* * Determine the realtime extent size of the XFS file system */ int xfsrtextsize( char *path) { int fd, rval, rtextsize; xfs_fsop_geom_v1_t geo; fd = open( path, O_RDONLY ); if ( fd < 0 ) { fprintf(stderr, _("%s: could not open %s: %s\n"), progname, path, strerror(errno)); return -1; } rval = xfsctl( path, fd, XFS_IOC_FSGEOMETRY_V1, &geo ); close(fd); if ( rval < 0 ) return -1; rtextsize = geo.rtextsize * geo.blocksize; return rtextsize; } xfsprogs-3.1.9ubuntu2/man/0000775000000000000000000000000012062211564012366 5ustar xfsprogs-3.1.9ubuntu2/man/man3/0000775000000000000000000000000012062211564013224 5ustar xfsprogs-3.1.9ubuntu2/man/man3/Makefile0000664000000000000000000000060411140033220014647 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = ../.. include $(TOPDIR)/include/builddefs MAN_SECTION = 3 MAN_PAGES = $(shell echo *.$(MAN_SECTION)) MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION) LSRCFILES = $(MAN_PAGES) default : $(MAN_PAGES) include $(BUILDRULES) install : install-dev : default $(INSTALL) -m 755 -d $(MAN_DEST) $(INSTALL_MAN) xfsprogs-3.1.9ubuntu2/man/man3/xfsctl.30000664000000000000000000004636111466226660014637 0ustar .TH XFSCTL 3 .SH NAME xfsctl \- control XFS filesystems and individual files .SH C SYNOPSIS .B #include .HP .BI "int\ xfsctl(const char *" path ", int " fd ", int " cmd ", void *" ptr ); .PP .BI "int platform_test_xfs_fd(int " fd ); .br .BI "int platform_test_xfs_path(const char *" path ); .SH DESCRIPTION Some functionality specific to the XFS filesystem is accessible to applications through platform-specific system call interfaces. These operations can be divided into two sections \- operations that operate on individual files, and operations that operate on the filesystem itself. Care should be taken when issuing .BR xfsctl () calls to ensure the target path and file descriptor (both must be supplied) do indeed represent a file from an XFS filesystem. The .BR statfs (2) and .BR fstatfs (2) system calls can be used to determine whether or not an arbitrary path or file descriptor belong to an XFS filesystem. These are not portable however, so the routines .BR platform_test_xfs_fd () and .BR platform_test_xfs_path () provide a platform-independent mechanism. .SS File Operations In order to effect an operation on an individual file, the pathname and descriptor arguments passed to .B xfsctl identifies the file being operated on. The final argument described below refers to the final argument of .BR xfsctl . All of the data structures and macros mentioned below are defined in the .RI < xfs/xfs_fs.h > header file. .PP .B XFS_IOC_ALLOCSP .br .B XFS_IOC_ALLOCSP64 .br .B XFS_IOC_FREESP .PD 0 .TP .B XFS_IOC_FREESP64 Alter storage space associated with a section of the ordinary file specified. The section is specified by a variable of type .BR xfs_flock64_t , pointed to by the final argument. The data type .B xfs_flock64_t contains the following members: .B l_whence is 0, 1, or 2 to indicate that the relative offset .B l_start will be measured from the start of the file, the current position, or the end of the file, respectively (i.e., .B l_start is the offset from the position specified in .BR l_whence ). If the offset specified is before the current end of file, any data previously written into this section is no longer accessible. If the offset specified is beyond the current end of file, the file is grown and filled with zeroes. The .B l_len field is currently ignored, and should be set to zero. .BR XFS_IOC_ALLOCSP , .BR XFS_IOC_ALLOCSP64 , .B XFS_IOC_FREESP and .B XFS_IOC_FREESP64 operations are all identical. .TP .B XFS_IOC_FSSETDM Set the di_dmevmask and di_dmstate fields in an XFS on-disk inode. The only legitimate values for these fields are those previously returned in the .B bs_dmevmask and .B bs_dmstate fields of the bulkstat structure. The data referred to by the final argument is a .BR "struct fsdmidata" . This structure's members are .B fsd_dmevmask and .BR fsd_dmstate . The di_dmevmask field is set to the value in .BR fsd_dmevmask . The di_dmstate field is set to the value in .BR fsd_dmstate . This command is restricted to root or to processes with device management capabilities. Its sole purpose is to allow backup and restore programs to restore the aforementioned critical on-disk inode fields. .TP .B XFS_IOC_DIOINFO Get information required to perform direct I/O on the specified file descriptor. Direct I/O is performed directly to and from a user's data buffer. Since the kernel's buffer cache is no longer between the two, the user's data buffer must conform to the same type of constraints as required for accessing a raw disk partition. The final argument points to a variable of type .BR "struct dioattr" , which contains the following members: .B d_mem is the memory alignment requirement of the user's data buffer. .B d_miniosz specifies block size, minimum I/O request size, and I/O alignment. The size of all I/O requests must be a multiple of this amount and the value of the seek pointer at the time of the I/O request must also be an integer multiple of this amount. .B d_maxiosz is the maximum I/O request size which can be performed on the file descriptor. If an I/O request does not meet these constraints, the .BR read (2) or .BR write (2) will fail with EINVAL. All I/O requests are kept consistent with any data brought into the cache with an access through a non-direct I/O file descriptor. .TP .B XFS_IOC_FSGETXATTR Get additional attributes associated with files in XFS file systems. The final argument points to a variable of type .BR "struct fsxattr" , whose fields include: .B fsx_xflags (extended flag bits), .B fsx_extsize (nominal extent size in file system blocks), .B fsx_nextents (number of data extents in the file). A .B fsx_extsize value returned indicates that a preferred extent size was previously set on the file, a .B fsx_extsize of zero indicates that the defaults for that filesystem will be used. Currently the meaningful bits for the .B fsx_xflags field are: .PD 0 .RS .TP 1.0i .SM "Bit 0 (0x1) \- XFS_XFLAG_REALTIME" The file is a realtime file. .TP .SM "Bit 1 (0x2) \- XFS_XFLAG_PREALLOC" The file has preallocated space. .TP .SM "Bit 3 (0x8) \- XFS_XFLAG_IMMUTABLE" The file is immutable - it cannot be modified, deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this flag. .TP .SM "Bit 4 (0x10) \- XFS_XFLAG_APPEND" The file is append-only - it can only be open in append mode for writing. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this flag. .TP .SM "Bit 5 (0x20) \- XFS_XFLAG_SYNC" All writes to the file are synchronous. .TP .SM "Bit 6 (0x40) \- XFS_XFLAG_NOATIME" When the file is accessed, its atime record is not modified. .TP .SM "Bit 7 (0x80) \- XFS_XFLAG_NODUMP" The file should be skipped by backup utilities. .TP .SM "Bit 8 (0x100) \- XFS_XFLAG_RTINHERIT" Realtime inheritance bit - new files created in the directory will be automatically realtime, and new directories created in the directory will inherit the inheritance bit. .TP .SM "Bit 9 (0x200) \- XFS_XFLAG_PROJINHERIT" Project inheritance bit - new files and directories created in the directory will inherit the parents project ID. New directories also inherit the project inheritance bit. .TP .SM "Bit 10 (0x400) \- XFS_XFLAG_NOSYMLINKS" Can only be set on a directory and disallows creation of symbolic links in that directory. .TP .SM "Bit 11 (0x800) \- XFS_XFLAG_EXTSIZE" Extent size bit - if a basic extent size value is set on the file then the allocator will allocate in multiples of the set size for this file (see .B XFS_IOC_FSSETXATTR below). .TP .SM "Bit 12 (0x1000) \- XFS_XFLAG_EXTSZINHERIT" Extent size inheritance bit - new files and directories created in the directory will inherit the parents basic extent size value (see .B XFS_IOC_FSSETXATTR below). Can only be set on a directory. .TP .SM "Bit 13 (0x2000) \- XFS_XFLAG_NODEFRAG" No defragment file bit - the file should be skipped during a defragmentation operation. When applied to a directory, new files and directories created will inherit the no\-defrag bit. .TP .SM "Bit 14 (0x4000) \- XFS_XFLAG_FILESTREAM" Filestream allocator bit - allows a directory to reserve an allocation group for exclusive use by files created within that directory. Files being written in other directories will not use the same allocation group and so files within different directories will not interleave extents on disk. The reservation is only active while files are being created and written into the directory. .TP .SM "Bit 31 (0x80000000) \- XFS_XFLAG_HASATTR" The file has extended attributes associated with it. .RE .PP .PD .TP .B XFS_IOC_FSGETXATTRA Identical to .B XFS_IOC_FSGETXATTR except that the .B fsx_nextents field contains the number of attribute extents in the file. .TP .B XFS_IOC_FSSETXATTR Set additional attributes associated with files in XFS file systems. The final argument points to a variable of type .BR "struct fsxattr" , but only the following fields are used in this call: .B fsx_xflags and .BR fsx_extsize . The .B fsx_xflags realtime file bit and the file's extent size may be changed only when the file is empty, except in the case of a directory where the extent size can be set at any time (this value is only used for regular file allocations, so should only be set on a directory in conjunction with the XFS_XFLAG_EXTSZINHERIT flag). .TP .B XFS_IOC_GETBMAP Get the block map for a segment of a file in an XFS file system. The final argument points to an arry of variables of type .BR "struct getbmap" . All sizes and offsets in the structure are in units of 512 bytes. The structure fields include: .B bmv_offset (file offset of segment), .B bmv_block (starting block of segment), .B bmv_length (length of segment), .B bmv_count (number of array entries, including the first), and .B bmv_entries (number of entries filled in). The first structure in the array is a header, and the remaining structures in the array contain block map information on return. The header controls iterative calls to the .B XFS_IOC_GETBMAP command. The caller fills in the .B bmv_offset and .B bmv_length fields of the header to indicate the area of interest in the file, and fills in the .B bmv_count field to indicate the length of the array. If the .B bmv_length value is set to \-1 then the length of the interesting area is the rest of the file. On return from a call, the header is updated so that the command can be reused to obtain more information, without re-initializing the structures. Also on return, the .B bmv_entries field of the header is set to the number of array entries actually filled in. The non-header structures will be filled in with .BR bmv_offset , .BR bmv_block , and .BR bmv_length . If a region of the file has no blocks (is a hole in the file) then the .B bmv_block field is set to \-1. .TP .B XFS_IOC_GETBMAPA Identical to .B XFS_IOC_GETBMAP except that information about the attribute fork of the file is returned. .PP .B XFS_IOC_RESVSP .TP .B XFS_IOC_RESVSP64 This command is used to allocate space to a file. A range of bytes is specified using a pointer to a variable of type .B xfs_flock64_t in the final argument. The blocks are allocated, but not zeroed, and the file size does not change. If the XFS filesystem is configured to flag unwritten file extents, performance will be negatively affected when writing to preallocated space, since extra filesystem transactions are required to convert extent flags on the range of the file written. If .BR xfs_info (8) reports unwritten=1, then the filesystem was made to flag unwritten extents. .PP .B XFS_IOC_UNRESVSP .TP .B XFS_IOC_UNRESVSP64 This command is used to free space from a file. A range of bytes is specified using a pointer to a variable of type .B xfs_flock64_t in the final argument. Partial filesystem blocks are zeroed, and whole filesystem blocks are removed from the file. The file size does not change. .TP .B XFS_IOC_ZERO_RANGE This command is used to convert a range of a file to zeros without issuing data IO. A range of bytes is specified using a pointer to a variable of type .B xfs_flock64_t in the final argument. Blocks are preallocated for regions that span holes in the file, and the entire range is converted to unwritten extents. This operation is a fast method of overwriting any from the range specified with zeros without removing any blocks or having to write zeros to disk. Any subsequent read in the given range will return zeros until new data is written. This functionality requires filesystems to support unwritten extents. If .BR xfs_info (8) reports unwritten=1, then the filesystem was made to flag unwritten extents. .\" .TP .\" .B XFS_IOC_GETBIOSIZE .\" This command gets information about the preferred buffered I/O .\" size used by the system when performing buffered I/O (e.g. .\" standard Unix non-direct I/O) to and from the file. .\" The information is passed back in a structure of type .\" .B "struct biosize" .\" pointed to by the final argument. .\" biosize lengths are expressed in log base 2. .\" That is if the value is 14, then the true size is 2^14 (2 raised to .\" the 14th power). .\" The .\" .B biosz_read .\" field will contain the current value used by the system when reading .\" from the file. .\" Except at the end-of-file, the system will read from the file in .\" multiples of this length. .\" The .\" .B biosz_write .\" field will contain the current value used by the system when writing .\" to the file. .\" Except at the end-of-file, the system will write to the file in .\" multiples of this length. .\" The .\" .B dfl_biosz_read .\" and .\" .B dfl_biosz_write .\" will be set to the system default values for the opened file. .\" The .\" .B biosz_flags .\" field will be set to 1 if the current read or write value has been .\" explicitly set. .\" .\" .TP .\" .B XFS_IOC_SETBIOSIZE .\" This command sets information about the preferred buffered I/O size .\" used by the system when performing buffered I/O (e.g. standard Unix .\" non-direct I/O) to and from the file. .\" The information is passed in a structure of type .\" .B "struct biosize" .\" pointed to by the final argument. .\" Using smaller preferred I/O sizes can result in performance .\" improvements if the file is typically accessed using small .\" synchronous I/Os or if only a small amount of the file is accessed .\" using small random I/Os, resulting in little or no use of the .\" additional data read in near the random I/Os. .\" .\" To explicitly set the preferred I/O sizes, the .\" .B biosz_flags .\" field should be set to zero and the .\" .B biosz_read .\" and .\" .B biosz_write .\" fields should be set to the log base 2 of the desired read and .\" write lengths, respectively (e.g. 13 for 8K bytes, 14 for 16K .\" bytes, 15 for 32K bytes, etc.). Valid values are 13-16 .\" inclusive for machines with a 4K byte pagesize and 14-16 for .\" machines with a 16K byte pagesize. The specified read and .\" write values must also result in lengths that are greater than .\" or equal to the filesystem block size. .\" The .\" .B dfl_biosz_read .\" and .\" .B dfl_biosz_write .\" fields are ignored. .\" .\" If biosizes have already been explicitly set due to a prior use .\" of .\" .BR XFS_IOC_SETBIOSIZE , .\" and the requested sizes are larger than the .\" existing sizes, the .\" .I xfsctl .\" call will return successfully and the .\" system will use the smaller of the two sizes. However, if .\" .B biosz_flags .\" is set to 1, the system will use the new values .\" regardless of whether the new sizes are larger or smaller than the old. .\" .\" To reset the biosize values to the defaults for the filesystem .\" that the file resides in, the .\" .B biosz_flags .\" field should be set to 2. .\" The remainder of the fields will be ignored in that case. .\" .\" Changes made by .\" .B XFS_IOC_SETBIOSIZE .\" are transient. .\" The sizes are reset to the default values once the reference count on the .\" file drops to zero (e.g. all open file descriptors to that file .\" have been closed). .\" See .\" .I mount(8) .\" for details on how to set the .\" default biosize values for a filesystem. .PP .nf .B XFS_IOC_PATH_TO_HANDLE .B XFS_IOC_PATH_TO_FSHANDLE .B XFS_IOC_FD_TO_HANDLE .B XFS_IOC_OPEN_BY_HANDLE .B XFS_IOC_READLINK_BY_HANDLE .B XFS_IOC_ATTR_LIST_BY_HANDLE .B XFS_IOC_ATTR_MULTI_BY_HANDLE .fi .PD 0 .TP .B XFS_IOC_FSSETDM_BY_HANDLE These are all interfaces that are used to implement various .I libhandle functions (see .BR open_by_handle (3)). They are all subject to change and should not be called directly by applications. .SS Filesystem Operations In order to effect one of the following operations, the pathname and descriptor arguments passed to .BR xfsctl () can be any open file in the XFS filesystem in question. .PP .TP .B XFS_IOC_FSINUMBERS This interface is used to extract a list of valid inode numbers from an XFS filesystem. It is intended to be called iteratively, to obtain the entire set of inodes. The information is passed in and out via a structure of type .B xfs_fsop_bulkreq_t pointed to by the final argument. .B lastip is a pointer to a variable containing the last inode number returned, initially it should be zero. .B icount is the size of the array of structures specified by .BR ubuffer . .B ubuffer is the address of an array of structures, of type .BR xfs_inogrp_t . This structure has the following elements: .B xi_startino (starting inode number), .B xi_alloccount (count of bits set in xi_allocmask), and .B xi_allocmask (mask of allocated inodes in this group). The bitmask is 64 bits long, and the least significant bit corresponds to inode .B xi_startino. Each bit is set if the corresponding inode is in use. .B ocount is a pointer to a count of returned values, filled in by the call. An output .B ocount value of zero means that the inode table has been exhausted. .TP .B XFS_IOC_FSBULKSTAT This interface is used to extract inode information (stat information) "in bulk" from a filesystem. It is intended to be called iteratively, to obtain information about the entire set of inodes in a filesystem. The information is passed in and out via a structure of type .B xfs_fsop_bulkreq_t pointed to by the final argument. .B lastip is a pointer to a variable containing the last inode number returned, initially it should be zero. .B icount indicates the size of the array of structures specified by .B ubuffer. .B ubuffer is the address of an array of structures of type .BR xfs_bstat_t . Many of the elements in the structure are the same as for the stat structure. The structure has the following elements: .B bs_ino (inode number), .B bs_mode (type and mode), .B bs_nlink (number of links), .B bs_uid (user id), .B bs_gid (group id), .B bs_rdev (device value), .B bs_blksize (block size of the filesystem), .B bs_size (file size in bytes), .B bs_atime (access time), .B bs_mtime (modify time), .B bs_ctime (inode change time), .B bs_blocks (number of blocks used by the file), .B bs_xflags (extended flags), .B bs_extsize (extent size), .B bs_extents (number of extents), .B bs_gen (generation count), .B bs_projid_lo (project id - low word), .B bs_projid_hi (project id - high word, used when projid32bit feature is enabled), .B bs_dmevmask (DMIG event mask), .B bs_dmstate (DMIG state information), and .B bs_aextents (attribute extent count). .B ocount is a pointer to a count of returned values, filled in by the call. An output .B ocount value of zero means that the inode table has been exhausted. .TP .B XFS_IOC_FSBULKSTAT_SINGLE This interface is a variant of the .B XFS_IOC_FSBULKSTAT interface, used to obtain information about a single inode. for an open file in the filesystem of interest. The same structure is used to pass information in and out of the kernel, except no output count parameter is used (should be initialized to zero). An error is returned if the inode number is invalid. .PP .nf .B XFS_IOC_THAW .B XFS_IOC_FREEZE .B XFS_IOC_GET_RESBLKS .B XFS_IOC_SET_RESBLKS .B XFS_IOC_FSGROWFSDATA .B XFS_IOC_FSGROWFSLOG .B XFS_IOC_FSGROWFSRT .fi .TP .B XFS_IOC_FSCOUNTS These interfaces are used to implement various filesystem internal operations on XFS filesystems. For .B XFS_IOC_FSGEOMETRY (get filesystem mkfs time information), the output structure is of type .BR xfs_fsop_geom_t . For .B XFS_FS_COUNTS (get filesystem dynamic global information), the output structure is of type .BR xfs_fsop_counts_t . The remainder of these operations will not be described further as they are not of general use to applications. .SH SEE ALSO .BR fstatfs (2), .BR statfs (2), .BR xfs (5), .BR xfs_info (8). xfsprogs-3.1.9ubuntu2/man/man3/handle.30000664000000000000000000001363711140033220014540 0ustar .TH HANDLE 3 .SH NAME path_to_handle, path_to_fshandle, fd_to_handle, handle_to_fshandle, open_by_handle, readlink_by_handle, attr_multi_by_handle, attr_list_by_handle, fssetdm_by_handle, free_handle, getparents_by_handle, getparentpaths_by_handle \- file handle operations .SH C SYNOPSIS .B #include .br .B #include .HP .BI "int\ path_to_handle(char *" path ", void **" hanp ", size_t *" hlen ); .HP .BI "int\ path_to_fshandle(char *" path ", void **" hanp ", size_t *" hlen ); .HP .BI "int\ fd_to_handle(int " fd ", void **" hanp ", size_t *" hlen ); .HP .BI "int\ handle_to_fshandle(void *" hanp ", size_t " hlen ", void **" fshanp , .BI "size_t *" fshlen ); .HP .BI "int\ open_by_handle(void *" hanp ", size_t " hlen ", int " oflag ); .HP .BI "int\ readlink_by_handle(void *" hanp ", size_t " hlen ", void *" buf , .BI "size_t " bs ); .HP .BI "int\ attr_multi_by_handle(void *" hanp ", size_t " hlen ", void *" buf , .BI "int " rtrvcnt ", int " flags ); .HP .BI "int\ attr_list_by_handle(void *" hanp ", size_t " hlen ", char *" buf , .BI "size_t " bufsiz ", int " flags ", struct attrlist_cursor *" cursor ); .HP .BI "int\ fssetdm_by_handle(void *" hanp ", size_t " hlen ", struct fsdmidata" .BI * fssetdm ); .HP .BI "void\ free_handle(void *" hanp ", size_t " hlen ); .HP .BI "int\ getparents_by_handle(void *" hanp ", size_t " hlen ", parent_t *" buf , .BI "size_t " bufsiz ", parent_cursor_t *" cursor ", unsigned int *" count , .BI "unsigned int *" more ); .HP .BI "int\ getparentpaths_by_handle(void *" hanp ", size_t " hlen ", parent_t" .BI * buf ", size_t " bufsiz ", parent_cursor_t *" cursor ", unsigned int " .BI * count ", unsigned int *" more ); .SH DESCRIPTION These functions provide a way to perform certain filesystem operations without using a file descriptor to access filesystem objects. They are intended for use by a limited set of system utilities such as backup programs. They are supported only by the XFS filesystem. Link with the .B libhandle library to access these functions. .PP A handle, .IR hanp , uniquely identifies a filesystem object or an entire filesystem. There is one and only one handle per filesystem or filesystem object. Handles consist of some number of bytes. The size of a handle (i.e. the number of bytes comprising it) varies by the type of handle and may vary for different objects of the same type. The content of a handle is opaque to applications. Since handle sizes vary and their contents are opaque, handles are described by two quantities, a pointer .RI ( hanp ") and a size (" hlen ). The size, .IR hlen , indicates the number of bytes in the handle which are pointed to by the pointer. .PP The .BR path_to_handle () function returns the handle for the object given by the .I path argument. If the final component of the path name is a symbolic link, the handle returned is that of the link itself. .PP The .BR path_to_fshandle () function returns the handle for the filesystem in which the object given by the .I path argument resides. .PP The .BR fd_to_handle () function returns the handle for the object referenced by the .I fd argument, which must be a valid file descriptor. .PP The .BR handle_to_fshandle () function returns the handle for the filesystem in which the object referenced by the handle given by the .I hanp and .I hlen arguments resides. .PP The .BR open_by_handle () function opens a file descriptor for the object referenced by a handle. It is analogous and identical to .BR open (2) with the exception of accepting handles instead of path names. .PP The .BR readlink_by_handle () function returns the contents of a symbolic link referenced by a handle. .PP The .BR attr_multi_by_handle () function manipulates multiple user attributes on a filesystem object. It is analogous and identical to .BR attr_multif (3) except that a handle is specified instead of a file descriptor. .PP The .BR attr_list_by_handle () function returns the names of the user attributes of a filesystem object. It is analogous and identical to .BR attr_listf (3) except that a handle is specified instead of a file descriptor. .PP The .BR fssetdm_by_handle () function sets the .B di_dmevmask and .B di_dmstate fields in an XFS on-disk inode. It is analogous to the .BR "XFS_IOC_FSSETDM xfsctl" (3) command, except that a handle is specified instead of a file. .PP The .BR free_handle () function frees the storage allocated for handles returned by the following functions: .BR path_to_handle (), .BR path_to_fshandle (), .BR fd_to_handle (), and .BR handle_to_fshandle (). .PP The .BR getparents_by_handle () function returns an array of .B parent_t structures for each hardlink to the inode represented by the given handle. The parent structure encodes the parent inode number, generation number and the basename of the link. .B This function is not operational on Linux. .PP The .BR getparentpaths_by_handle () function is identical to the .BR getparents_by_handle () function except that instead of returning the basename it returns the path of the link up to the mount point. .B This function is also not operational on Linux. .SH RETURN VALUE The function .BR free_handle () has no failure indication. The other functions return the value 0 to the calling process if they succeed; otherwise, they return the value \-1 and set .I errno to indicate the error. .SH ERRORS .TP .B EACCES Search permission was denied for a component of .IR path . .TP .B EBADF .I fd is not a valid and open file descriptor. .TP .B EFAULT An argument pointed to an invalid address. .TP .B EINVAL .I path is in a filesystem that does not support these functions. .TP .B ELOOP Too many symbolic links were encountered in translating the path name. .TP .B ENAMETOOLONG A component of .I path or the entire length of .I path exceeds filesystem limits. .TP .B ENOENT A component of .I path does not exist. .TP .B EPERM The caller does not have sufficient privileges. .SH SEE ALSO .BR open (2), .BR readlink (2), .BR attr_multi (3), .BR attr_list (3), .BR xfsctl (3), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/Makefile0000664000000000000000000000062111352300766014031 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs SUBDIRS = man3 man5 man8 default : $(SUBDIRS) install : $(addsuffix -install,$(SUBDIRS)) install-dev : $(addsuffix -install-dev,$(SUBDIRS)) %-install: $(Q)$(MAKE) $(MAKEOPTS) -C $* install %-install-dev: $(Q)$(MAKE) $(MAKEOPTS) -C $* install-dev include $(BUILDRULES) xfsprogs-3.1.9ubuntu2/man/man8/0000775000000000000000000000000012062211564013231 5ustar xfsprogs-3.1.9ubuntu2/man/man8/xfs_mdrestore.80000664000000000000000000000220611432653672016220 0ustar .TH xfs_mdrestore 8 .SH NAME xfs_mdrestore \- restores an XFS metadump image to a filesystem image .SH SYNOPSIS .B xfs_mdrestore [ .B \-g ] .I source .I target .SH DESCRIPTION .B xfs_mdrestore is a debugging tool that restores a metadata image generated by .BR xfs_metadump (8) to a filesystem. The .I source argument specifies the location of the metadump image and the .I target argument specifies the destination for the filsystem image. If the .I source is \-, then the metadata image is read from stdin. This allows the output of be another program such as a compression application to be redirected to .BR xfs_mdrestore . The .I target can be either a file or a device. .PP .B xfs_mdrestore should not be used to restore metadata onto an existing filesystem unless you are completely certain the .I target can be destroyed. .PP .SH OPTIONS .TP .B \-g Shows restore progress on stdout. .SH DIAGNOSTICS .B xfs_mdrestore returns an exit code of 0 if all the metadata is successfully restored or 1 if an error occurs. .SH SEE ALSO .BR xfs_metadump (8), .BR xfs_repair (8), .BR xfs_check (8), .BR xfs (5) .SH BUGS Email bug reports to .BR xfs@oss.sgi.com . xfsprogs-3.1.9ubuntu2/man/man8/Makefile0000664000000000000000000000060311140033220014653 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = ../.. include $(TOPDIR)/include/builddefs MAN_SECTION = 8 MAN_PAGES = $(shell echo *.$(MAN_SECTION)) MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION) LSRCFILES = $(MAN_PAGES) default : $(MAN_PAGES) include $(BUILDRULES) install : default $(INSTALL) -m 755 -d $(MAN_DEST) $(INSTALL_MAN) install-dev : xfsprogs-3.1.9ubuntu2/man/man8/xfs_logprint.80000664000000000000000000000543411140033220016031 0ustar .TH xfs_logprint 8 .SH NAME xfs_logprint \- print the log of an XFS filesystem .SH SYNOPSIS .B xfs_logprint [ .I options ] .I device .SH DESCRIPTION .B xfs_logprint prints the log of an XFS filesystem (see .BR xfs (5)). The .I device argument is the pathname of the partition or logical volume containing the filesystem. The .I device can be a regular file if the .B \-f option is used. The contents of the filesystem remain undisturbed. There are two major modes of operation in .BR xfs_logprint . .PP One mode is better for filesystem operation debugging. It is called the transactional view and is enabled through the .B \-t option. The transactional view prints only the portion of the log that pertains to recovery. In other words, it prints out complete transactions between the tail and the head. This view tries to display each transaction without regard to how they are split across log records. .PP The second mode starts printing out information from the beginning of the log. Some error blocks might print out in the beginning because the last log record usually overlaps the oldest log record. A message is printed when the physical end of the log is reached and when the logical end of the log is reached. A log record view is displayed one record at a time. Transactions that span log records may not be decoded fully. .SH OPTIONS .TP .B \-b Extract and print buffer information. Only used in transactional view. .TP .B \-c Attempt to continue when an error is detected. .TP .BI \-C " filename" Copy the log from the filesystem to the file .IR filename . The log itself is not printed. .TP .B \-d Dump the log from front to end, printing where each log record is located on disk. .TP .B \-D Do not decode anything; just print data. .TP .B \-e Exit when an error is found in the log. Normally, .B xfs_logprint tries to continue and unwind from bad logs. However, sometimes it just dies in bad ways. Using this option prevents core dumps. .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .BR mkfs.xfs "(8) " -d .I file option). This might happen if an image copy of a filesystem has been made into an ordinary file with .BR xfs_copy (8). .TP .BI \-l " logdev" External log device. Only for those filesystems which use an external log. .TP .B \-i Extract and print inode information. Only used in transactional view. .TP .B \-q Extract and print quota information. Only used in transactional view. .TP .B \-n Do not try and interpret log data; just interpret log header information. .TP .B \-o Also print buffer data in hex. Normally, buffer data is just decoded, so better information can be printed. .TP .BI \-s " start-block" Override any notion of where to start printing. .TP .B \-t Print out the transactional view. .SH SEE ALSO .BR mkfs.xfs (8), .BR mount (8). xfsprogs-3.1.9ubuntu2/man/man8/mkfs.xfs.80000664000000000000000000005302711466226660015102 0ustar .TH mkfs.xfs 8 .SH NAME mkfs.xfs \- construct an XFS filesystem .SH SYNOPSIS .B mkfs.xfs [ .B \-b .I block_size ] [ .B \-d .I data_section_options ] [ .B \-f ] [ .B \-i .I inode_options ] [ .B \-l .I log_section_options ] [ .B \-n .I naming_options ] [ .B \-p .I protofile ] [ .B \-q ] [ .B \-r .I realtime_section_options ] [ .B \-s .I sector_size ] [ .B \-L .I label ] [ .B \-N ] [ .B \-K ] .I device .SH DESCRIPTION .B mkfs.xfs constructs an XFS filesystem by writing on a special file using the values found in the arguments of the command line. It is invoked automatically by .BR mkfs (8) when it is given the .B \-t xfs option. .PP In its simplest (and most commonly used form), the size of the filesystem is determined from the disk driver. As an example, to make a filesystem with an internal log on the first partition on the first SCSI disk, use: .IP .B mkfs.xfs /dev/sda1 .PP The metadata log can be placed on another device to reduce the number of disk seeks. To create a filesystem on the first partition on the first SCSI disk with a 10000 block log located on the first partition on the second SCSI disk, use: .RS .HP .B mkfs.xfs\ \-l\ logdev=/dev/sdb1,size=10000b /dev/sda1 .RE .PP Each of the .I option elements in the argument list above can be given as multiple comma-separated suboptions if multiple suboptions apply to the same option. Equivalently, each main option can be given multiple times with different suboptions. For example, .B \-l internal,size=10000b and .B \-l internal \-l size=10000b are equivalent. .PP In the descriptions below, sizes are given in sectors, bytes, blocks, kilobytes, megabytes, gigabytes, etc. Sizes are treated as hexadecimal if prefixed by 0x or 0X, octal if prefixed by 0, or decimal otherwise. The following lists possible multiplication suffixes: .RS .PD 0 .HP .BR s "\ \-\ multiply by sector size (default = 512, see " \-s option below). .HP .BR b "\ \-\ multiply by filesystem block size (default = 4K, see " \-b option below). .HP .BR k "\ \-\ multiply by one kilobyte (1,024 bytes)." .HP .BR m "\ \-\ multiply by one megabyte (1,048,576 bytes)." .HP .BR g "\ \-\ multiply by one gigabyte (1,073,741,824 bytes)." .HP .BR t "\ \-\ multiply by one terabyte (1,099,511,627,776 bytes)." .HP .BR p "\ \-\ multiply by one petabyte (1,024 terabytes)." .HP .BR e "\ \-\ multiply by one exabyte (1,048,576 terabytes)." .PD .SH OPTIONS .TP .BI \-b " block_size_options" This option specifies the fundamental block size of the filesystem. The valid .I block_size_options are: .BI log= value or .BI size= value and only one can be supplied. The block size is specified either as a base two logarithm value with .BR log= , or in bytes with .BR size= . The default value is 4096 bytes (4 KiB), the minimum is 512, and the maximum is 65536 (64 KiB). XFS on Linux currently only supports pagesize or smaller blocks. .TP .BI \-d " data_section_options" These options specify the location, size, and other parameters of the data section of the filesystem. The valid .I data_section_options are: .RS 1.2i .TP .BI agcount= value This is used to specify the number of allocation groups. The data section of the filesystem is divided into allocation groups to improve the performance of XFS. More allocation groups imply that more parallelism can be achieved when allocating blocks and inodes. The minimum allocation group size is 16 MiB; the maximum size is just under 1 TiB. The data section of the filesystem is divided into .I value allocation groups (default value is scaled automatically based on the underlying device size). .TP .BI agsize= value This is an alternative to using the .B agcount suboption. The .I value is the desired size of the allocation group expressed in bytes (usually using the .BR m " or " g suffixes). This value must be a multiple of the filesystem block size, and must be at least 16MiB, and no more than 1TiB, and may be automatically adjusted to properly align with the stripe geometry. The .B agcount and .B agsize suboptions are mutually exclusive. .TP .BI name= value This can be used to specify the name of the special file containing the filesystem. In this case, the log section must be specified as .B internal (with a size, see the .B \-l option below) and there can be no real-time section. .TP .BI file[= value ] This is used to specify that the file given by the .B name suboption is a regular file. The .I value is either 0 or 1, with 1 signifying that the file is regular. This suboption is used only to make a filesystem image. If the .I value is omitted then 1 is assumed. .TP .BI size= value This is used to specify the size of the data section. This suboption is required if .B \-d file[=1] is given. Otherwise, it is only needed if the filesystem should occupy less space than the size of the special file. .TP .BI sunit= value This is used to specify the stripe unit for a RAID device or a logical volume. The .I value has to be specified in 512-byte block units. Use the .B su suboption to specify the stripe unit size in bytes. This suboption ensures that data allocations will be stripe unit aligned when the current end of file is being extended and the file size is larger than 512KiB. Also inode allocations and the internal log will be stripe unit aligned. .TP .BI su= value This is an alternative to using .B sunit. The .B su suboption is used to specify the stripe unit for a RAID device or a striped logical volume. The .I value has to be specified in bytes, (usually using the .BR m " or " g suffixes). This .I value must be a multiple of the filesystem block size. .TP .BI swidth= value This is used to specify the stripe width for a RAID device or a striped logical volume. The .I value has to be specified in 512-byte block units. Use the .B sw suboption to specify the stripe width size in bytes. This suboption is required if .B \-d sunit has been specified and it has to be a multiple of the .B \-d sunit suboption. .TP .BI sw= value suboption is an alternative to using .B swidth. The .B sw suboption is used to specify the stripe width for a RAID device or striped logical volume. The .I value is expressed as a multiplier of the stripe unit, usually the same as the number of stripe members in the logical volume configuration, or data disks in a RAID device. .IP When a filesystem is created on a logical volume device, .B mkfs.xfs will automatically query the logical volume for appropriate .B sunit and .B swidth values. .RE .TP .B \-f Force overwrite when an existing filesystem is detected on the device. By default, .B mkfs.xfs will not write to the device if it suspects that there is a filesystem or partition table on the device already. .TP .BI \-i " inode_options" This option specifies the inode size of the filesystem, and other inode allocation parameters. The XFS inode contains a fixed-size part and a variable-size part. The variable-size part, whose size is affected by this option, can contain: directory data, for small directories; attribute data, for small attribute sets; symbolic link data, for small symbolic links; the extent list for the file, for files with a small number of extents; and the root of a tree describing the location of extents for the file, for files with a large number of extents. .IP The valid .I inode_options are: .RS 1.2i .TP .BI size= value " | log=" value " | perblock=" value The inode size is specified either as a .I value in bytes with .BR size= , a base two logarithm .I value with .BR log= , or as the number fitting in a filesystem block with .BR perblock= . The mininum (and default) .I value is 256 bytes. The maximum .I value is 2048 (2 KiB) subject to the restriction that the inode size cannot exceed one half of the filesystem block size. .IP XFS uses 64-bit inode numbers internally; however, the number of significant bits in an inode number is affected by filesystem geometry. In practice, filesystem size and inode size are the predominant factors. The Linux kernel (on 32 bit hardware platforms) and most applications cannot currently handle inode numbers greater than 32 significant bits, so if no inode size is given on the command line, .B mkfs.xfs will attempt to choose a size such that inode numbers will be < 32 bits. If an inode size is specified, or if a filesystem is sufficently large, .B mkfs.xfs will warn if this will create inode numbers > 32 significant bits. .TP .BI maxpct= value This specifies the maximum percentage of space in the filesystem that can be allocated to inodes. The default .I value is 25% for filesystems under 1TB, 5% for filesystems under 50TB and 1% for filesystems over 50TB. .IP In the default inode allocation mode, inode blocks are chosen such that inode numbers will not exceed 32 bits, which restricts the inode blocks to the lower portion of the filesystem. The data block allocator will avoid these low blocks to accommodate the specified maxpct, so a high value may result in a filesystem with nothing but inodes in a significant portion of the lower blocks of the filesystem. (This restriction is not present when the filesystem is mounted with the .I "inode64" option on 64-bit platforms). .IP Setting the value to 0 means that essentially all of the filesystem can become inode blocks, subject to inode32 restrictions. .IP This value can be modified with .IR xfs_growfs(8) . .TP .BI align[= value ] This is used to specify that inode allocation is or is not aligned. The .I value is either 0 or 1, with 1 signifying that inodes are allocated aligned. If the .I value is omitted, 1 is assumed. The default is that inodes are aligned. Aligned inode access is normally more efficient than unaligned access; alignment must be established at the time the filesystem is created, since inodes are allocated at that time. This option can be used to turn off inode alignment when the filesystem needs to be mountable by a version of IRIX that does not have the inode alignment feature (any release of IRIX before 6.2, and IRIX 6.2 without XFS patches). .TP .BI attr= value This is used to specify the version of extended attribute inline allocation policy to be used. By default, this is 2, which uses an efficient algorithm for managing the available inline inode space between attribute and extent data. .IP The previous version 1, which has fixed regions for attribute and extent data, is kept for backwards compatibility with kernels older than version 2.6.16. .TP .BI projid32bit[= value ] This is used to enable 32bit quota project identifiers. The .I value is either 0 or 1, with 1 signifying that 32bit projid are to be enabled. If the value is omitted, 0 is assumed. .RE .TP .BI \-l " log_section_options" These options specify the location, size, and other parameters of the log section of the filesystem. The valid .I log_section_options are: .RS 1.2i .TP .BI internal[= value ] This is used to specify that the log section is a piece of the data section instead of being another device or logical volume. The .I value is either 0 or 1, with 1 signifying that the log is internal. If the .I value is omitted, 1 is assumed. .TP .BI logdev= device This is used to specify that the log section should reside on the .I device separate from the data section. The .B internal=1 and .B logdev options are mutually exclusive. .TP .BI size= value This is used to specify the size of the log section. .IP If the log is contained within the data section and .B size isn't specified, .B mkfs.xfs will try to select a suitable log size depending on the size of the filesystem. The actual logsize depends on the filesystem block size and the directory block size. .IP Otherwise, the .B size suboption is only needed if the log section of the filesystem should occupy less space than the size of the special file. The .I value is specified in bytes or blocks, with a .B b suffix meaning multiplication by the filesystem block size, as described above. The overriding minimum value for size is 512 blocks. With some combinations of filesystem block size, inode size, and directory block size, the minimum log size is larger than 512 blocks. .TP .BI version= value This specifies the version of the log. The current default is 2, which allows for larger log buffer sizes, as well as supporting stripe-aligned log writes (see the sunit and su options, below). .IP The previous version 1, which is limited to 32k log buffers and does not support stripe-aligned writes, is kept for backwards compatibility with very old 2.4 kernels. .TP .BI sunit= value This specifies the alignment to be used for log writes. The .I value has to be specified in 512-byte block units. Use the .B su suboption to specify the log stripe unit size in bytes. Log writes will be aligned on this boundary, and rounded up to this boundary. This gives major improvements in performance on some configurations such as software RAID5 when the .B sunit is specified as the filesystem block size. The equivalent byte value must be a multiple of the filesystem block size. Version 2 logs are automatically selected if the log .B sunit suboption is specified. .IP The .B su suboption is an alternative to using .B sunit. .TP .BI su= value This is used to specify the log stripe. The .I value has to be specified in bytes, (usually using the .BR s " or " b suffixes). This value must be a multiple of the filesystem block size. Version 2 logs are automatically selected if the log .B su suboption is specified. .TP .BI lazy-count= value This changes the method of logging various persistent counters in the superblock. Under metadata intensive workloads, these counters are updated and logged frequently enough that the superblock updates become a serialisation point in the filesystem. The .I value can be either 0 or 1. .IP With .BR lazy-count=1 , the superblock is not modified or logged on every change of the persistent counters. Instead, enough information is kept in other parts of the filesystem to be able to maintain the persistent counter values without needed to keep them in the superblock. This gives significant improvements in performance on some configurations. The default .I value is 1 (on) so you must specify .B lazy-count=0 if you want to disable this feature for older kernels which don't support it. .RE .TP .BI \-n " naming_options" These options specify the version and size parameters for the naming (directory) area of the filesystem. The valid .I naming_options are: .RS 1.2i .TP .BI size= value " | log=" value The block size is specified either as a .I value in bytes with .BR size= , or as a base two logarithm .I value .RB "with " log= . The block size must be a power of 2 and cannot be less than the filesystem block size. The default size .I value for version 2 directories is 4096 bytes (4 KiB), unless the filesystem block size is larger than 4096, in which case the default .I value is the filesystem block size. For version 1 directories the block size is the same as the filesystem block size. .TP .BI version= value The naming (directory) version .I value can be either 2 or 'ci', defaulting to 2 if unspecified. With version 2 directories, the directory block size can be any power of 2 size from the filesystem block size up to 65536. .IP The .B version=ci option enables ASCII only case-insensitive filename lookup and version 2 directories. Filenames are case-preserving, that is, the names are stored in directories using the case they were created with. .IP Note: Version 1 directories are not supported. .RE .TP .BI \-p " protofile" If the optional .BI \-p " protofile" argument is given, .B mkfs.xfs uses .I protofile as a prototype file and takes its directions from that file. The blocks and inodes specifiers in the .I protofile are provided for backwards compatibility, but are otherwise unused. The syntax of the protofile is defined by a number of tokens separated by spaces or newlines. Note that the line numbers are not part of the syntax but are meant to help you in the following discussion of the file contents. .nf .sp .8v .in +5 \f71 /stand/\f1\f2diskboot\f1\f7 2 4872 110 3 d\-\-777 3 1 4 usr d\-\-777 3 1 5 sh \-\-\-755 3 1 /bin/sh 6 ken d\-\-755 6 1 7 $ 8 b0 b\-\-644 3 1 0 0 9 c0 c\-\-644 3 1 0 0 10 fifo p\-\-644 3 1 11 slink l\-\-644 3 1 /a/symbolic/link 12 : This is a comment line 13 $ 14 $\f1 .in -5 .fi .IP Line 1 is a dummy string. (It was formerly the bootfilename.) It is present for backward compatibility; boot blocks are not used on SGI systems. .IP Note that some string of characters must be present as the first line of the proto file to cause it to be parsed correctly; the value of this string is immaterial since it is ignored. .IP Line 2 contains two numeric values (formerly the numbers of blocks and inodes). These are also merely for backward compatibility: two numeric values must appear at this point for the proto file to be correctly parsed, but their values are immaterial since they are ignored. .IP The lines 3 through 11 specify the files and directories you want to include in this filesystem. Line 3 defines the root directory. Other directories and files that you want in the filesystem are indicated by lines 4 through 6 and lines 8 through 10. Line 11 contains symbolic link syntax. .IP Notice the dollar sign .RB ( $ ) syntax on line 7. This syntax directs the .B mkfs.xfs command to terminate the branch of the filesystem it is currently on and then continue from the directory specified by the next line, in this case line 8. It must be the last character on a line. The colon on line 12 introduces a comment; all characters up until the following newline are ignored. Note that this means you cannot have a file in a prototype file whose name contains a colon. The .B $ on lines 13 and 14 end the process, since no additional specifications follow. .IP File specifications provide the following: .IP * file mode .br * user ID .br * group ID .br * the file's beginning contents .P .IP A 6-character string defines the mode for a file. The first character of this string defines the file type. The character range for this first character is .B \-bcdpl. A file may be a regular file, a block special file, a character special file, directory files, named pipes (first-in, first out files), and symbolic links. The second character of the mode string is used to specify setuserID mode, in which case it is .BR u . If setuserID mode is not specified, the second character is .BR \- . The third character of the mode string is used to specify the setgroupID mode, in which case it is .BR g . If setgroupID mode is not specified, the third character is .BR \- . The remaining characters of the mode string are a three digit octal number. This octal number defines the owner, group, and other read, write, and execute permissions for the file, respectively. For more information on file permissions, see the .BR chmod (1) command. .IP Following the mode character string are two decimal number tokens that specify the user and group IDs of the file's owner. .IP In a regular file, the next token specifies the pathname from which the contents and size of the file are copied. In a block or character special file, the next token are two decimal numbers that specify the major and minor device numbers. When a file is a symbolic link, the next token specifies the contents of the link. When the file is a directory, the .B mkfs.xfs command creates the entries .B dot (.) and .B dot-dot (..) and then reads the list of names and file specifications in a recursive manner for all of the entries in the directory. A scan of the protofile is always terminated with the dollar ( .B $ ) token. .TP .B \-q Quiet option. Normally .B mkfs.xfs prints the parameters of the filesystem to be constructed; the .B \-q flag suppresses this. .TP .BI \-r " realtime_section_options" These options specify the location, size, and other parameters of the real-time section of the filesystem. The valid .I realtime_section_options are: .RS 1.2i .TP .BI rtdev= device This is used to specify the .I device which should contain the real-time section of the filesystem. The suboption value is the name of a block device. .TP .BI extsize= value This is used to specify the size of the blocks in the real-time section of the filesystem. This .I value must be a multiple of the filesystem block size. The minimum allowed size is the filesystem block size or 4 KiB (whichever is larger); the default size is the stripe width for striped volumes or 64 KiB for non-striped volumes; the maximum allowed size is 1 GiB. The real-time extent size should be carefully chosen to match the parameters of the physical media used. .TP .BI size= value This is used to specify the size of the real-time section. This suboption is only needed if the real-time section of the filesystem should occupy less space than the size of the partition or logical volume containing the section. .RE .TP .BI \-s " sector_size" This option specifies the fundamental sector size of the filesystem. The .I sector_size is specified either as a value in bytes with .BI size= value or as a base two logarithm value with .BI log= value. The default .I sector_size is 512 bytes. The minimum value for sector size is 512; the maximum is 32768 (32 KiB). The .I sector_size must be a power of 2 size and cannot be made larger than the filesystem block size. .TP .BI \-L " label" Set the filesystem .IR label . XFS filesystem labels can be at most 12 characters long; if .I label is longer than 12 characters, .B mkfs.xfs will not proceed with creating the filesystem. Refer to the .BR mount "(8) and " xfs_admin (8) manual entries for additional information. .TP .B \-N Causes the file system parameters to be printed out without really creating the file system. .TP .B \-K Do not attempt to discard blocks at mkfs time. .SH SEE ALSO .BR xfs (5), .BR mkfs (8), .BR mount (8), .BR xfs_info (8), .BR xfs_admin (8). .SH BUGS With a prototype file, it is not possible to specify hard links. xfsprogs-3.1.9ubuntu2/man/man8/xfs_ncheck.80000664000000000000000000000324311140033220015422 0ustar .TH xfs_ncheck 8 .SH NAME xfs_ncheck \- generate pathnames from i-numbers for XFS .SH SYNOPSIS .B xfs_ncheck [ .B \-i .I ino ] ... [ .B \-f ] [ .B \-s ] [ .B \-l .I logdev ] .I device .SH DESCRIPTION .B xfs_ncheck with no .B \-i arguments generates an inode number and pathname list of all files on the given filesystem. Names of directory files are followed by .BR /. . The output is not sorted in any particular order. The filesystem to be examined is specified by the .I device argument, which should be the disk or volume device for the filesystem. Filesystems stored in files can also be checked, using the .B \-f flag. .SH OPTIONS .TP 0.9i .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .B mkfs.xfs \-d .I \f2file\f1 option). This might happen if an image copy of a filesystem has been made into an ordinary file. .TP .BI \-l " logdev" Specifies the device where the filesystem's external log resides. Only for those filesystems which use an external log. See the .B mkfs.xfs \-l option, and refer to .BR xfs (5) for a detailed description of the XFS log. .TP .B \-s Limits the report to special files and files with setuserid mode. This option may be used to detect violations of security policy. .TP .BI \-i " ino" Limits the report to only those files whose inode numbers follow. May be given multiple times to select multiple inode numbers. .PP If the filesystem is seriously corrupted, or very busy and looks like it is corrupt, a message of the form that would be generated by .BR xfs_check (8) may appear. .PP .B xfs_ncheck is only useful with XFS filesystems. .SH SEE ALSO .BR mkfs.xfs (8), .BR xfs_check (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_mkfile.80000664000000000000000000000115711140033220015440 0ustar .TH xfs_mkfile 8 .SH NAME xfs_mkfile \- create an XFS file .SH SYNOPSIS .B xfs_mkfile [ .B \-v ] [ .B \-n ] .I size\c .RB [ k | b | m | g ] .IR filename " ..." .SH DESCRIPTION .B xfs_mkfile creates one or more files. The file is padded with zeroes by default. The default size is in bytes, but it can be flagged as kilobytes, blocks, megabytes, or gigabytes with the .BR k , .BR b , .BR m , or .B g suffixes, respectively. .SH OPTIONS .TP .B \-v Verbose. Report the names and sizes of created files. .TP .B \-n No bytes. Create a holey file - that is, do not write out any data, just seek to end of file and write a block. xfsprogs-3.1.9ubuntu2/man/man8/xfs_fsr.80000664000000000000000000001141011140033220014754 0ustar .TH xfs_fsr 8 .SH NAME xfs_fsr \- filesystem reorganizer for XFS .SH SYNOPSIS .nf \f3xfs_fsr\f1 [\f3\-v\f1] \c [\f3\-t\f1 seconds] [\f3\-f\f1 leftoff] [\f3\-m\f1 mtab] \f3xfs_fsr\f1 [\f3\-v\f1] \c [xfsdev | file] ... .fi .SH DESCRIPTION .I xfs_fsr is applicable only to XFS filesystems. .PP .I xfs_fsr improves the organization of mounted filesystems. The reorganization algorithm operates on one file at a time, compacting or otherwise improving the layout of the file extents (contiguous blocks of file data). .PP The following options are accepted by .IR xfs_fsr . The .BR \-m , .BR \-t , and .B \-f options have no meaning if any filesystems or files are specified on the command line. .TP 13 .BI \-m " mtab" Use this file for the list of filesystems to reorganize. The default is to use .IR /etc/mtab . .TP .BI \-t " seconds" How long to reorganize. The default is 7200 (2 hours). .TP .BI \-f " leftoff" Use this file instead of .I /var/tmp/.fsrlast to read the state of where to start and as the file to store the state of where reorganization left off. .TP .B \-v Verbose. Print cryptic information about each file being reorganized. .PP When invoked with no arguments .I xfs_fsr reorganizes all regular files in all mounted filesystems. .I xfs_fsr makes many cycles over .I /etc/mtab each time making a single pass over each XFS filesystem. Each pass goes through and selects files that have the largest number of extents. It attempts to defragment the top 10% of these files on each pass. .PP It runs for up to two hours after which it records the filesystem where it left off, so it can start there the next time. This information is stored in the file .I /var/tmp/.fsrlast_xfs. If the information found here is somehow inconsistent or out of date it is ignored and reorganization starts at the beginning of the first filesystem found in .IR /etc/mtab . .PP .I xfs_fsr can be called with one or more arguments naming filesystems (block device name), and files to reorganize. In this mode .I xfs_fsr does not read or write .I /var/tmp/.fsrlast_xfs nor does it run for a fixed time interval. It makes one pass through each specified regular file and all regular files in each specified filesystem. A command line name referring to a symbolic link (except to a file system device), FIFO, or UNIX domain socket generates a warning message, but is otherwise ignored. While traversing the filesystem these types of files are silently skipped. .SH FILES .PD 0 .TP 21 /etc/mtab contains default list of filesystems to reorganize. .TP 21 /var/tmp/.fsrlast_xfs records the state where reorganization left off. .PD .SH "SEE ALSO" xfs_fsr(8), mkfs.xfs(8), xfs_ncheck(8), xfs(5). .SH "NOTES" .I xfs_fsr improves the layout of extents for each file by copying the entire file to a temporary location and then interchanging the data extents of the target and temporary files in an atomic manner. This method requires that enough free disk space be available to copy any given file and that the space be less fragmented than the original file. It also requires the owner of the file to have enough remaining filespace quota to do the copy on systems running quotas. .I xfs_fsr generates a warning message if space is not sufficient to improve the target file. .PP A temporary file used in improving a file given on the command line is created in the same parent directory of the target file and is prefixed by the string '\f3.fsr\f1'. The temporary files used in improving an entire XFS device are stored in a directory at the root of the target device and use the same naming scheme. The temporary files are unlinked upon creation so data will not be readable by any other process. .PP .I xfs_fsr does not operate on files that are currently mapped in memory. A 'file busy' error can be seen for these files if the verbose flag (\f3-v\f1) is set. .PP Files marked as no\-defrag will be skipped. The .IR xfs_io (8) chattr command with the f attribute can be used to set or clear this flag. Files and directories created in a directory with the no\-defrag flag will inherit the attribute. .PP An entry in .I /etc/mtab or the file specified using the .B \-m option must have the .B rw option specified for read and write access. If this option is not present, then .I xfs_fsr skips the filesystem described by that line. See the .IR fstab (5) reference page for more details. .PP In general we do not foresee the need to run .I xfs_fsr on system partitions such as .IR / , .I /boot and .I /usr as in general these will not suffer from fragmentation. There are also issues with defragmenting files .IR lilo (8) uses to boot your system. It is recommended that these files should be flagged as no\-defrag with the .IR xfs_io (8) chattr command. Should these files be moved by .I xfs_fsr then you must rerun .I lilo before you reboot or you may have an unbootable system. xfsprogs-3.1.9ubuntu2/man/man8/fsck.xfs.80000664000000000000000000000122211140033220015027 0ustar .TH fsck.xfs 8 .SH NAME fsck.xfs \- do nothing, successfully .SH SYNOPSIS .B fsck.xfs [ .I filesys \&... ] .SH DESCRIPTION .B fsck.xfs is called by the generic Linux .BR fsck (8) program at startup to check and repair an XFS filesystem. XFS is a journaling filesystem and performs recovery at .BR mount (8) time if necessary, so .B fsck.xfs simply exits with a zero exit status. .PP If you wish to check the consistency of an XFS filesystem, or repair a damaged or corrupt XFS filesystem, see .BR xfs_check (8) and .BR xfs_repair (8). . .SH FILES .IR /etc/fstab . .SH SEE ALSO .BR fsck (8), .BR fstab (5), .BR xfs (5), .BR xfs_check (8), .BR xfs_repair (8). xfsprogs-3.1.9ubuntu2/man/man8/xfs_check.80000664000000000000000000001375612062210562015270 0ustar .TH xfs_check 8 .SH NAME xfs_check \- check XFS filesystem consistency .SH SYNOPSIS .B xfs_check [ .B \-i .I ino ] ... [ .B \-b .I bno ] ... [ .B \-f ] [ .B \-s ] [ .B \-v ] [ .B \-l .I logdev ] .I device .SH DESCRIPTION .B xfs_check checks whether an XFS filesystem is consistent. It is normally run only when there is reason to believe that the filesystem has a consistency problem. The filesystem to be checked is specified by the .I device argument, which should be the disk or volume device for the filesystem. Filesystems stored in files can also be checked, using the .B \-f flag. The filesystem should normally be unmounted or read-only during the execution of .BR xfs_check . Otherwise, spurious problems are reported. .PP Note that using .B xfs_check is NOT recommended. Please use .BR xfs_repair " " \-n instead, for better scalability and speed. .SH OPTIONS .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .BR mkfs.xfs "(8) " \-d .I file option). This might happen if an image copy of a filesystem has been made into an ordinary file. .TP .BI \-l " logdev" Specifies the device where the filesystem's external log resides. Only for those filesystems which use an external log. See the .BR mkfs.xfs "(8) " \-l option, and refer to .BR xfs (5) for a detailed description of the XFS log. .TP .B \-s Specifies that only serious errors should be reported. Serious errors are those that make it impossible to find major data structures in the filesystem. This option can be used to cut down the amount of output when there is a serious problem, when the output might make it difficult to see what the real problem is. .TP .B \-v Specifies verbose output; it is impossibly long for a reasonably-sized filesystem. This option is intended for internal use only. .TP .BI \-i " ino" Specifies verbose behavior for the specified inode .IR ino . For instance, it can be used to locate all the blocks associated with a given inode. .TP .BI \-b " bno" Specifies verbose behavior for the specific filesystem block at .IR bno . For instance, it can be used to determine what a specific block is used for. The block number is a "file system block number". Conversion between disk addresses (i.e. addresses reported by .BR xfs_bmap (8)) and file system blocks may be accomplished using .BR xfs_db "(8)'s " convert command. .PP Any output that is produced when .B xfs_check is not run in verbose mode indicates that the filesystem has an inconsistency. The filesystem can be repaired using either .BR xfs_repair (8) to fix the filesystem in place, or by using .BR xfsdump (8) and .BR mkfs.xfs (8) to dump the filesystem, make a new filesystem, then use .BR xfsrestore (8) to restore the data onto the new filesystem. Note that xfsdump may fail on a corrupt filesystem. However, if the filesystem is mountable, xfsdump can be used to try and save important data before repairing the filesystem with xfs_repair. If the filesystem is not mountable though, xfs_repair is the only viable option. .SH DIAGNOSTICS If the filesystem is completely corrupt, a core dump might be produced instead of the message .RS .I device .B is not a valid filesystem .RE .PP If the filesystem is very large (has many files) then .B xfs_check might run out of memory. In this case the message .RS .B out of memory .RE is printed. .PP The following is a description of the most likely problems and the associated messages. Most of the diagnostics produced are only meaningful with an understanding of the structure of the filesystem. .TP .BI "agf_freeblks " n ", counted " m " in ag " a The freeblocks count in the allocation group header for allocation group .I a doesn't match the number of blocks counted free. .TP .BI "agf_longest " n ", counted " m " in ag " a The longest free extent in the allocation group header for allocation group .I a doesn't match the longest free extent found in the allocation group. .TP .BI "agi_count " n ", counted " m " in ag " a The allocated inode count in the allocation group header for allocation group .I a doesn't match the number of inodes counted in the allocation group. .TP .BI "agi_freecount " n ", counted " m " in ag " a The free inode count in the allocation group header for allocation group .I a doesn't match the number of inodes counted free in the allocation group. .TP .BI "block " a/b " expected inum 0 got " i The block number is specified as a pair (allocation group number, block in the allocation group). The block is used multiple times (shared), between multiple inodes. This message usually follows a message of the next type. .TP .BI "block " a/b " expected type unknown got " y The block is used multiple times (shared). .TP .BI "block " a/b " type unknown not expected The block is unaccounted for (not in the freelist and not in use). .TP .BI "link count mismatch for inode " nnn " (name " xxx "), nlink " m ", counted " n The inode has a bad link count (number of references in directories). .TP .BI "rtblock " b " expected inum 0 got " i The block is used multiple times (shared), between multiple inodes. This message usually follows a message of the next type. .TP .BI "rtblock " b " expected type unknown got " y The real-time block is used multiple times (shared). .TP .BI "rtblock " b " type unknown not expected The real-time block is unaccounted for (not in the freelist and not in use). .TP .BI "sb_fdblocks " n ", counted " m The number of free data blocks recorded in the superblock doesn't match the number counted free in the filesystem. .TP .BI "sb_frextents " n ", counted " m The number of free real-time extents recorded in the superblock doesn't match the number counted free in the filesystem. .TP .BI "sb_icount " n ", counted " m The number of allocated inodes recorded in the superblock doesn't match the number allocated in the filesystem. .TP .BI "sb_ifree " n ", counted " m The number of free inodes recorded in the superblock doesn't match the number free in the filesystem. .SH SEE ALSO .BR mkfs.xfs (8), .BR xfsdump (8), .BR xfsrestore (8), .BR xfs_ncheck (8), .BR xfs_repair (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_admin.80000664000000000000000000000515011466226660015305 0ustar .TH xfs_admin 8 .SH NAME xfs_admin \- change parameters of an XFS filesystem .SH SYNOPSIS .B xfs_admin [ .B \-eflpu ] [ .BR "\-c 0" | 1 ] [ .B \-L .I label ] [ .B \-U .I uuid ] .I device .SH DESCRIPTION .B xfs_admin uses the .BR xfs_db (8) command to modify various parameters of a filesystem. .PP Devices that are mounted cannot be modified. Administrators must unmount filesystems before .BR xfs_admin " or " xfs_db (8) can convert parameters. A number of parameters of a mounted filesystem can be examined and modified using the .BR xfs_growfs (8) command. .SH OPTIONS .TP .B \-e Enables unwritten extent support on a filesystem that does not already have this enabled (for legacy filesystems, it can't be disabled anymore at mkfs time). .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .B mkfs.xfs \-d .I file option). .TP .B \-j Enables version 2 log format (journal format supporting larger log buffers). .TP .B \-l Print the current filesystem label. .TP .B \-p Enable 32bit project identifier support (PROJID32BIT feature). .TP .B \-u Print the current filesystem UUID (Universally Unique IDentifier). .TP .BR "\-c 0" | 1 Enable (1) or disable (0) lazy-counters in the filesystem. This operation may take quite a bit of time on large filesystems as the entire filesystem needs to be scanned when this option is changed. .IP With lazy-counters enabled, the superblock is not modified or logged on every change of the free-space and inode counters. Instead, enough information is kept in other parts of the filesystem to be able to maintain the counter values without needing to keep them in the superblock. This gives significant improvements in performance on some configurations and metadata intensive workloads. .TP .BI \-L " label" Set the filesystem label to .IR label . XFS filesystem labels can be at most 12 characters long; if .I label is longer than 12 characters, .B xfs_admin will truncate it and print a warning message. The filesystem label can be cleared using the special "\c .B \-\-\c " value for .IR label . .TP .BI \-U " uuid" Set the UUID of the filesystem to .IR uuid . A sample UUID looks like this: "c1b9d5a2-f162-11cf-9ece-0020afc76f16". The .I uuid may also be .BR nil , which will set the filesystem UUID to the null UUID. The .I uuid may also be .BR generate , which will generate a new UUID for the filesystem. .PP The .BR mount (8) manual entry describes how to mount a filesystem using its label or UUID, rather than its block special device name. .SH SEE ALSO .BR mkfs.xfs (8), .BR mount (8), .BR xfs_db (8), .BR xfs_growfs (8), .BR xfs_repair (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_io.80000664000000000000000000003576412062210562014625 0ustar .TH xfs_io 8 .SH NAME xfs_io \- debug the I/O path of an XFS filesystem .SH SYNOPSIS .B xfs_io [ .B \-adfmrRstx ] [ .B \-c .I cmd ] ... [ .B \-p .I prog ] .I file .SH DESCRIPTION .B xfs_io is a debugging tool like .BR xfs_db (8), but is aimed at examining the regular file I/O paths rather than the raw XFS volume itself. These code paths include not only the obvious read/write/mmap interfaces for manipulating files, but also cover all of the XFS extensions (such as space preallocation, additional inode flags, etc). .SH OPTIONS .TP 1.0i .BI \-c " cmd" .B xfs_io commands may be run interactively (the default) or as arguments on the command line. Multiple .B \-c arguments may be given. The commands are run in the sequence given, then the program exits. .TP .BI \-p " prog" Set the program name for prompts and some error messages, the default value is .BR xfs_io . .TP .B \-f Create .I file if it does not already exist. .TP .B \-r Open .I file read-only, initially. This is required if .I file is immutable or append-only. .TP .B \-x Expert mode. Dangerous commands are only available in this mode. These commands also tend to require additional privileges. .PP The other .BR open (2) options described below are also available from the command line. .SH CONCEPTS .B xfs_io maintains a number of open files and memory mappings. Files can be initially opened on the command line (optionally), and additional files can also be opened later. .PP .B xfs_io commands can be broken up into three groups. Some commands are aimed at doing regular file I/O - read, write, sync, space preallocation, etc. .PP The second set of commands exist for manipulating memory mapped regions of a file - mapping, accessing, storing, unmapping, flushing, etc. .PP The remaining commands are for the navigation and display of data structures relating to the open files, mappings, and the filesystems where they reside. .PP Many commands have extensive online help. Use the .B help command for more details on any command. .SH FILE I/O COMMANDS .TP .BI "file [ " N " ]" Display a list of all open files and (optionally) switch to an alternate current open file. .TP .BI "open [[ \-acdfrstR ] " path " ]" Closes the current file, and opens the file specified by .I path instead. Without any arguments, displays statistics about the current file \- see the .B stat command. .RS 1.0i .PD 0 .TP 0.4i .B \-a opens append-only (O_APPEND). .TP .B \-d opens for direct I/O (O_DIRECT). .TP .B \-f creates the file if it doesn't already exist (O_CREAT). .TP .B \-r opens read-only (O_RDONLY). .TP .B \-s opens for synchronous I/O (O_SYNC). .TP .B \-t truncates on open (O_TRUNC). .TP .B \-R marks the file as a realtime XFS file after opening it, if it is not already marked as such. .PD .RE .TP .B o See the .B open command. .TP .B close Closes the current open file, marking the next open file as current (if one exists). .TP .B c See the .B close command. .TP .BI "pread [ \-b " bsize " ] [ \-v ] [ \-FBR [ \-Z " seed " ] ] [ \-V " vectors " ] " "offset length" Reads a range of bytes in a specified blocksize from the given .IR offset . .RS 1.0i .PD 0 .TP 0.4i .B \-b can be used to set the blocksize into which the .BR read (2) requests will be split. The default blocksize is 4096 bytes. .TP .B \-v dump the contents of the buffer after reading, by default only the count of bytes actually read is dumped. .TP .B \-F read the buffers in a forwards sequential direction. .TP .B \-B read the buffers in a reserve sequential direction. .TP .B \-R read the buffers in the give range in a random order. .TP .B \-Z seed specify the random number seed used for random reads. .TP .B \-V vectors Use the vectored IO read syscall .BR preadv (2) with a number of blocksize length iovecs. The number of iovecs is set by the .I vectors parameter. .PD .RE .TP .B r See the .B pread command. .TP .BI "pwrite [ \-i " file " ] [ \-d ] [ \-s " skip " ] [ \-b " size " ] [ \-S " seed " ] [ \-FBR [ \-Z " zeed " ] ] [ \-wW ] [ \-V " vectors " ] " "offset length" Writes a range of bytes in a specified blocksize from the given .IR offset . The bytes written can be either a set pattern or read in from another file before writing. .RS 1.0i .PD 0 .TP 0.4i .B \-i allows an input .I file to be specified as the source of the data to be written. .TP .B \-d causes direct I/O, rather than the usual buffered I/O, to be used when reading the input file. .TP .B \-s specifies the number of bytes to .I skip from the start of the input file before starting to read. .TP .B \-b used to set the blocksize into which the .BR write (2) requests will be split. The default blocksize is 4096 bytes. .TP .B \-S used to set the (repeated) fill pattern which is used when the data to write is not coming from a file. The default buffer fill pattern value is 0xcdcdcdcd. .TP .B \-F write the buffers in a forwards sequential direction. .TP .B \-B write the buffers in a reserve sequential direction. .TP .B \-R write the buffers in the give range in a random order. .TP .B \-Z seed specify the random number seed used for random write .TP .B \-w call .BR fdatasync (2) once all writes are complete (included in timing results) .TP .B \-W call .BR fsync (2) once all writes are complete (included in timing results) .TP .B \-V vectors Use the vectored IO write syscall .BR pwritev (2) with a number of blocksize length iovecs. The number of iovecs is set by the .I vectors parameter. .RE .PD .TP .B w See the .B pwrite command. .TP .BI "bmap [ \-adlpv ] [ \-n " nx " ]" Prints the block mapping for the current open file. Refer to the .BR xfs_bmap (8) manual page for complete documentation. .TP .BI "extsize [ \-R | \-D ] [ " value " ]" Display and/or modify the preferred extent size used when allocating space for the currently open file. If the .B \-R option is specified, a recursive descent is performed for all directory entries below the currently open file .RB ( \-D can be used to restrict the output to directories only). If the target file is a directory, then the inherited extent size is set for that directory (new files created in that directory inherit that extent size). The .I value should be specified in bytes, or using one of the usual units suffixes (k, m, g, b, etc). The extent size is always reported in units of bytes. .TP .BI "allocsp " size " 0" Sets the size of the file to .I size and zeroes any additional space allocated using the XFS_IOC_ALLOCSP/XFS_IOC_FREESP system call described in the .BR xfsctl (3) manual page. .B allocsp and .B freesp do exactly the same thing. .TP .BI "freesp " size " 0" See the .B allocsp command. .TP .BI "fadvise [ \-r | \-s | [[ \-d | \-n | \-w ] " "offset length " ]] On platforms which support it, allows hints be given to the system regarding the expected I/O patterns on the file. The range arguments are required by some advise commands ([*] below), and the others must have no range arguments. With no arguments, the POSIX_FADV_NORMAL advice is implied (default readahead). .RS 1.0i .PD 0 .TP 0.4i .B \-d the data will not be accessed again in the near future (POSIX_FADV_DONTNEED[*]). .TP .B \-n data will be accessed once and not be reused (POSIX_FADV_NOREUSE[*]). .TP .B \-r expect access to data in random order (POSIX_FADV_RANDOM), which sets readahead to zero. .TP .B \-s expect access to data in sequential order (POSIX_FADV_SEQUENTIAL), which doubles the default readahead on the file. .TP .B \-w advises the specified data will be needed again (POSIX_FADV_WILLNEED[*]) which forces the maximum readahead. .RE .PD .TP .B fdatasync Calls .BR fdatasync (2) to flush the file's in-core data to disk. .TP .B fsync Calls .BR fsync (2) to flush all in-core file state to disk. .TP .B s See the .B fsync command. .TP .BI "sync_range [ \-a | \-b | \-w ] offset length " On platforms which support it, allows control of syncing a range of the file to disk. With no options, SYNC_FILE_RANGE_WRITE is implied on the range supplied. .RS 1.0i .PD 0 .TP 0.4i .B \-a wait for IO in the given range to finish after writing (SYNC_FILE_RANGE_WAIT_AFTER). .TP .B \-b wait for IO in the given range to finish before writing (SYNC_FILE_RANGE_WAIT_BEFORE). .TP .B \-w start writeback of dirty data in the given range (SYNC_FILE_RANGE_WRITE). .RE .PD .TP .BI resvsp " offset length" Allocates reserved, unwritten space for part of a file using the XFS_IOC_RESVSP system call described in the .BR xfsctl (3) manual page. .TP .BI unresvsp " offset length" Frees reserved space for part of a file using the XFS_IOC_UNRESVSP system call described in the .BR xfsctl (3) manual page. .TP .BI "falloc [ \-k ]" " offset length" Allocates reserved, unwritten space for part of a file using the fallocate routine as described in the .BR fallocate (3) manual page. .RS 1.0i .PD 0 .TP 0.4i .B \-k will set the FALLOC_FL_KEEP_SIZE flag as described in .BR fallocate (3). .PD .RE .TP .BI truncate " offset" Truncates the current file at the given offset using .BR ftruncate (2). .TP .BI "sendfile \-i " srcfile " | \-f " N " [ " "offset length " ] On platforms which support it, allows a direct in-kernel copy between two file descriptors. The current open file is the target, the source must be specified as another open file .RB ( \-f ) or by path .RB ( \-i ). .SH MEMORY MAPPED I/O COMMANDS .TP .BI "mmap [ " N " | [[ \-rwx ] " "offset length " ]] With no arguments, .B mmap shows the current mappings. Specifying a single numeric argument .I N sets the current mapping. If two arguments are specified (a range specified by .I offset and .IR length ), a new mapping is created spanning the range, and the protection mode can be given as a combination of PROT_READ .RB ( \-r ), PROT_WRITE .RB ( \-w ), and PROT_EXEC .RB ( \-x ). .TP .B mm See the .B mmap command. .TP .B munmap Unmaps the current memory mapping. .TP .B mu See the .B munmap command. .TP .BI "mread [ \-f | \-v ] [ \-r ] [" " offset length " ] Accesses a segment of the current memory mapping, optionally dumping it to the standard output stream (with .B \-v or .B \-f option) for inspection. The accesses are performed sequentially from the start .I offset by default, but can also be done from the end backwards through the mapping if the .B \-r option in specified. The two verbose modes differ only in the relative offsets they display, the .B \-f option is relative to file start, whereas .B \-v shows offsets relative to the start of the mapping. .TP .B mr See the .B mread command. .TP .BI "mwrite [ \-r ] [ \-S " seed " ] [ " "offset length " ] Stores a byte into memory for a range within a mapping. The default stored value is 'X', repeated to fill the range specified, but this can be changed using the .B \-S option. The memory stores are performed sequentially from the start offset by default, but can also be done from the end backwards through the mapping if the .B \-r option in specified. .TP .B mw See the .B mwrite command. .TP .BI "msync [ \-i ] [ \-a | \-s ] [ " "offset length " ] Writes all modified copies of pages over the specified range (or entire mapping if no range specified) to their backing storage locations. Also, optionally invalidates .RB ( \-i ) so that subsequent references to the pages will be obtained from their backing storage locations (instead of cached copies). The flush can be done synchronously .RB ( \-s) or asynchronously .RB ( \-a ). .TP .B ms See the .B msync command. .TP .BI "madvise [ \-d | \-r | \-s | \-w ] [ " "offset length " ] Modifies page cache behavior when operating on the current mapping. The range arguments are required by some advise commands ([*] below). With no arguments, the POSIX_MADV_NORMAL advice is implied (default readahead). .RS 1.0i .PD 0 .TP 0.4i .B \-d the pages will not be needed (POSIX_MADV_DONTNEED[*]). .TP .B \-r expect random page references (POSIX_MADV_RANDOM), which sets readahead to zero. .TP .B \-s expect sequential page references (POSIX_MADV_SEQUENTIAL), which doubles the default readahead on the file. .TP .B \-w advises the specified pages will be needed again (POSIX_MADV_WILLNEED[*]) which forces the maximum readahead. .RE .PD .TP .B mincore Dumps a list of pages or ranges of pages that are currently in core, for the current memory mapping. .SH OTHER COMMANDS .TP .B print Display a list of all open files and memory mapped regions. The current file and current mapping are distinguishable from any others. .TP .B p See the .B print command. .TP .B quit Exit .BR xfs_io . .TP .B q See the .B quit command. .TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the .B \-R option is specified, a recursive descent is performed for all directory entries below the currently open file .RB ( \-D can be used to restrict the output to directories only). This is a depth first descent, it does not follow symlinks and it also does not cross mount points. .TP .BR chattr " [ " \-R " | " \-D " ] [ " + / \-riasAdtPneEfS " ]" Change extended inode flags on the currently open file. The .B \-R and .B \-D options have the same meaning as above. The mapping between each letter and the inode flags (refer to .BR xfsctl (3) for the full list) is available via the .B help command. .TP .B freeze Suspend all write I/O requests to the filesystem of the current file. Only available in expert mode and requires privileges. .TP .B thaw Undo the effects of a filesystem freeze operation. Only available in expert mode and requires privileges. .TP .BI "inject [ " tag " ]" Inject errors into a filesystem to observe filesystem behavior at specific points under adverse conditions. Without the .I tag argument, displays the list of error tags available. Only available in expert mode and requires privileges. .TP .BI "resblks [ " blocks " ]" Get and/or set count of reserved filesystem blocks using the XFS_IOC_GET_RESBLKS or XFS_IOC_SET_RESBLKS system calls. Note \-\- this can be useful for exercising out of space behavior. Only available in expert mode and requires privileges. .TP .BR shutdown " [ " \-f " ]" Force the filesystem to shutdown (with or without flushing the log). Only available in expert mode and requires privileges. .TP .BR stat " [ " \-v " ]" Selected statistics from .BR stat (2) and the XFS_IOC_GETXATTR system call on the current file. If the .B \-v option is specified, the atime (last access), mtime (last modify), and ctime (last change) timestamps are also displayed. .TP .B statfs Selected statistics from .BR statfs (2) and the XFS_IOC_FSGEOMETRY system call on the filesystem where the current file resides. .TP .BR parent " [ " \-cpv " ]" By default this command prints out the parent inode numbers, inode generation numbers and basenames of all the hardlinks which point to the inode of the current file. .RS 1.0i .PD 0 .TP 0.4i .B \-p the output is similar to the default output except pathnames up to the mount-point are printed out instead of the component name. .TP .B \-c the file's filesystem will check all the parent attributes for consistency. .TP .B \-v verbose output will be printed. .RE .IP .B [NOTE: Not currently operational on Linux.] .PD .SH SEE ALSO .BR mkfs.xfs (8), .BR xfsctl (3), .BR xfs_bmap (8), .BR xfs_db (8), .BR xfs (5), .BR fdatasync (2), .BR fstat (2), .BR fstatfs (2), .BR fsync (2), .BR ftruncate (2), .BR mmap (2), .BR msync (2), .BR open (2), .BR pread (2), .BR pwrite (2). xfsprogs-3.1.9ubuntu2/man/man8/xfs_metadump.80000664000000000000000000000702411432653652016031 0ustar .TH xfs_metadump 8 .SH NAME xfs_metadump \- copy XFS filesystem metadata to a file .SH SYNOPSIS .B xfs_metadump [ .B \-efgow ] [ .B \-l .I logdev ] .I source .I target .SH DESCRIPTION .B xfs_metadump is a debugging tool that copies the metadata from an XFS filesystem to a file. The .I source argument must be the pathname of the device or file containing the XFS filesystem and the .I target argument specifies the destination file name. If .I target is \-, then the output is sent to stdout. This allows the output to be redirected to another program such as a compression application. .PP .B xfs_metadump should only be used to copy unmounted filesystems, read-only mounted filesystems, or frozen filesystems (see .BR xfs_freeze (8)). Otherwise, the generated dump could be inconsistent or corrupt. .PP .B xfs_metadump does not alter the source filesystem in any way. The .I target image is a contiguous (non-sparse) file containing all the filesystem's metadata and indexes to where the blocks were copied from. .PP By default, .B xfs_metadump obfuscates most file (regular file, directory and symbolic link) names and extended attribute names to allow the dumps to be sent without revealing confidential information. Extended attribute values are zeroed and no data is copied. The only exceptions are file or attribute names that are 4 or less characters in length. Also file names that span extents (this can only occur with the .BR mkfs.xfs (8) options where .B \-n .I size > .B \-b .IR size ) are not obfuscated. Names between 5 and 8 characters in length inclusively are partially obfuscated. .PP .B xfs_metadump should not be used for any purposes other than for debugging and reporting filesystem problems. The most common usage scenario for this tool is when .BR xfs_repair (8) fails to repair a filesystem and a metadump image can be sent for analysis. .PP The file generated by .B xfs_metadump can be restored to filesystem image (minus the data) using the .BR xfs_mdrestore (8) tool. .PP .SH OPTIONS .TP .B \-e Stops the dump on a read error. Normally, it will ignore read errors and copy all the metadata that is accessible. .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file (see the .B mkfs.xfs -d file option). This can also happen if an image copy of a filesystem has been made into an ordinary file with .BR xfs_copy (8). .TP .B \-g Shows dump progress. This is sent to stdout if the .I target is a file or to stderr if the .I target is stdout. .TP .BI \-l " logdev" For filesystems which use an external log, this specifies the device where the external log resides. The external log is not copied, only internal logs are copied. .TP .B \-o Disables obfuscation of file names and extended attributes. .TP .B \-w Prints warnings of inconsistent metadata encountered to stderr. Bad metadata is still copied. .SH DIAGNOSTICS .B xfs_metadump returns an exit code of 0 if all readable metadata is successfully copied or 1 if a write error occurs or a read error occurs and the .B \-e option used. .SH NOTES As .B xfs_metadump copies metadata only, it does not matter if the .I source filesystem has a realtime section or not. If the filesystem has an external log, it is not copied. Internal logs are copied and any outstanding log transactions are not obfuscated if they contain names. .PP .B xfs_metadump is a shell wrapper around the .BR xfs_db (8) .B metadump command. .SH SEE ALSO .BR xfs_repair (8), .BR xfs_mdrestore (8), .BR xfs_freeze (8), .BR xfs_db (8), .BR xfs_copy (8), .BR xfs (5) .SH BUGS Email bug reports to .BR xfs@oss.sgi.com . xfsprogs-3.1.9ubuntu2/man/man8/xfs_rtcp.80000664000000000000000000000220311140033220015132 0ustar .TH xfs_rtcp 8 .SH NAME xfs_rtcp \- XFS realtime copy command .SH SYNOPSIS .B xfs_rtcp [ .B \-e .I extsize ] [ .B -p ] .IR source " ... " target .SH DESCRIPTION .B xfs_rtcp copies a file to the realtime partition on an XFS filesystem. If there is more than one .I source and .IR target , the final argument (the .IR target ) must be a directory which already exists. .SH OPTIONS .TP .BI \-e " extsize" Sets the extent size of the destination realtime file. .TP .B \-p Use if the size of the source file is not an even multiple of the block size of the destination filesystem. When .B \-p is specified .B xfs_rtcp will pad the destination file to a size which is an even multiple of the filesystem block size. This is necessary since the realtime file is created using direct I/O and the minimum I/O is the filesystem block size. .SH SEE ALSO .BR xfs (5), .BR mkfs.xfs (8), .BR mount (8). .SH CAVEATS Currently, realtime partitions are not supported under the Linux version of XFS, and use of a realtime partition .B WILL CAUSE CORRUPTION on the data partition. As such, this command is made available for curious .B DEVELOPERS ONLY at this point in time. xfsprogs-3.1.9ubuntu2/man/man8/xfs_db.80000664000000000000000000012521311466226660014605 0ustar .TH xfs_db 8 .SH NAME xfs_db \- debug an XFS filesystem .SH SYNOPSIS .B xfs_db [ .B \-c .I cmd ] ... [ .BR \-i | r | x | F ] [ .B \-f ] [ .B \-l .I logdev ] [ .B \-p .I progname ] .I device .br .B xfs_db \-V .SH DESCRIPTION .B xfs_db is used to examine an XFS filesystem. Under rare circumstances it can also be used to modify an XFS filesystem, but that task is normally left to .BR xfs_repair (8) or to scripts such as .BR xfs_admin (8) that run .BR xfs_db . .PP .SH OPTIONS .TP .BI \-c " cmd" .B xfs_db commands may be run interactively (the default) or as arguments on the command line. Multiple .B \-c arguments may be given. The commands are run in the sequence given, then the program exits. This is the mechanism used to implement .BR xfs_check (8). .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .BR mkfs.xfs "(8) " -d .I file option). This might happen if an image copy of a filesystem has been made into an ordinary file with .BR xfs_copy (8). .TP .B \-F Specifies that we want to continue even if the superblock magic is not correct. For use in .BR xfs_check and .BR xfs_metadump . .TP .B \-i Allows execution on a mounted filesystem, provided it is mounted read-only. Useful for shell scripts such as .BR xfs_check (8), which must only operate on filesystems in a guarenteed consistent state (either unmounted or mounted read-only). These semantics are slightly different to that of the .B -r option. .TP .BI \-l " logdev" Specifies the device where the filesystems external log resides. Only for those filesystems which use an external log. See the .BR mkfs.xfs "(8) " \-l option, and refer to .BR xfs (5) for a detailed description of the XFS log. .TP .BI \-p " progname" Set the program name to .I progname for prompts and some error messages, the default value is .BR xfs_db . .TP .B -r Open .I device or .I filename read-only. This option is required if the filesystem is mounted. It is only necessary to omit this flag if a command that changes data .RB ( write ", " blocktrash ) is to be used. .TP .B \-x Specifies expert mode. This enables the .B write and .B blocktrash commands. .TP .B \-V Prints out the current version number and exits. .SH CONCEPTS .B xfs_db commands can be broken up into two classes. Most commands are for the navigation and display of data structures in the filesystem. Other commands are for scanning the filesystem in some way. .PP Commands which are used to navigate the filesystem structure take arguments which reflect the names of filesystem structure fields. There can be multiple field names separated by dots when the underlying structures are nested, as in C. The field names can be indexed (as an array index) if the underlying field is an array. The array indices can be specified as a range, two numbers separated by a dash. .PP .B xfs_db maintains a current address in the filesystem. The granularity of the address is a filesystem structure. This can be a filesystem block, an inode or quota (smaller than a filesystem block), or a directory block (could be larger than a filesystem block). There are a variety of commands to set the current address. Associated with the current address is the current data type, which is the structural type of this data. Commands which follow the structure of the filesystem always set the type as well as the address. Commands which examine pieces of an individual file (inode) need the current inode to be set, this is done with the .B inode command. .PP The current address/type information is actually maintained in a stack that can be explicitly manipulated with the .BR push ", " pop ", and " stack commands. This allows for easy examination of a nested filesystem structure. Also, the last several locations visited are stored in a ring buffer which can be manipulated with the .BR forward ", " back ", and " ring commands. .PP XFS filesystems are divided into a small number of allocation groups. .B xfs_db maintains a notion of the current allocation group which is manipulated by some commands. The initial allocation group is 0. .SH COMMANDS .PP Many commands have extensive online help. Use the .B help command for more details on any command. .TP .B a See the .B addr command. .TP .BI ablock " filoff" Set current address to the offset .I filoff (a filesystem block number) in the attribute area of the current inode. .TP .BI "addr [" field-expression ] Set current address to the value of the .IR field-expression . This is used to "follow" a reference in one structure to the object being referred to. If no argument is given, the current address is printed. .TP .BI "agf [" agno ] Set current address to the AGF block for allocation group .IR agno . If no argument is given, use the current allocation group. .TP .BI "agfl [" agno ] Set current address to the AGFL block for allocation group .IR agno . If no argument is given, use the current allocation group. .TP .BI "agi [" agno ] Set current address to the AGI block for allocation group .IR agno . If no argument is given, use the current allocation group. .TP .B b See the .B back command. .TP .B back Move to the previous location in the position ring. .TP .B blockfree Free block usage information collected by the last execution of the .B blockget command. This must be done before another .B blockget command can be given, presumably with different arguments than the previous one. .TP .BI "blockget [\-npvs] [\-b " bno "] ... [\-i " ino "] ..." Get block usage and check filesystem consistency. The information is saved for use by a subsequent .BR blockuse ", " ncheck ", or " blocktrash command. See .BR xfs_check (8) for more information. .RS 1.0i .TP 0.4i .B \-b is used to specify filesystem block numbers about which verbose information should be printed. .TP .B \-i is used to specify inode numbers about which verbose information should be printed. .TP .B \-n is used to save pathnames for inodes visited, this is used to support the .BR xfs_ncheck (8) command. It also means that pathnames will be printed for inodes that have problems. This option uses a lot of memory so is not enabled by default. .TP .B \-p causes error messages to be prefixed with the filesystem name being processed. This is useful if several copies of .B xfs_db are run in parallel. .TP .B \-s restricts output to severe errors only. This is useful if the output is too long otherwise. .TP .B \-v enables verbose output. Messages will be printed for every block and inode processed. .RE .TP .BI "blocktrash [\-n " count "] [\-x " min "] [\-y " max "] [\-s " seed "] [\-0|1|2|3] [\-t " type "] ..." Trash randomly selected filesystem metadata blocks. Trashing occurs to randomly selected bits in the chosen blocks. This command is available only in debugging versions of .BR xfs_db . It is useful for testing .BR xfs_repair "(8) and " xfs_check (8). .RS 1.0i .TP 0.4i .BR \-0 " | " -1 " | " -2 " | " -3 These are used to set the operating mode for .BR blocktrash . Only one can be used: .B \-0 changed bits are cleared; .B \-1 changed bits are set; .B -2 changed bits are inverted; .B -3 changed bits are randomized. .TP .B \-n supplies the .I count of block-trashings to perform (default 1). .TP .B \-s supplies a .I seed to the random processing. .TP .B \-t gives a .I type of blocks to be selected for trashing. Multiple .B \-t options may be given. If no .B \-t options are given then all metadata types can be trashed. .TP .B \-x sets the .I minimum size of bit range to be trashed. The default value is 1. .TP .B \-y sets the .I maximum size of bit range to be trashed. The default value is 1024. .RE .TP .BI "blockuse [\-n] [\-c " count ] Print usage for current filesystem block(s). For each block, the type and (if any) inode are printed. .RS 1.0i .TP 0.4i .B \-c specifies a .I count of blocks to process. The default value is 1 (the current block only). .TP .B \-n specifies that file names should be printed. The prior .B blockget command must have also specified the .B \-n option. .RE .TP .BI "bmap [\-a\] [\-d] [" block " [" len ]] Show the block map for the current inode. The map display can be restricted to an area of the file with the .I block and .I len arguments. If .I block is given and .I len is omitted then 1 is assumed for len. .IP The .B \-a and .B \-d options are used to select the attribute or data area of the inode, if neither option is given then both areas are shown. .TP .B check See the .B blockget command. .TP .BI "convert " "type number" " [" "type number" "] ... " type Convert from one address form to another. The known .IR type s, with alternate names, are: .RS 1.0i .PD 0 .HP .B agblock or .B agbno (filesystem block within an allocation group) .HP .B agino or .B aginode (inode number within an allocation group) .HP .B agnumber or .B agno (allocation group number) .HP .B bboff or .B daddroff (byte offset in a .BR daddr ) .HP .B blkoff or .B fsboff or .B agboff (byte offset in a .B agblock or .BR fsblock ) .HP .B byte or .B fsbyte (byte address in filesystem) .HP .B daddr or .B bb (disk address, 512-byte blocks) .HP .B fsblock or .B fsb or .B fsbno (filesystem block, see the .B fsblock command) .HP .B ino or .B inode (inode number) .HP .B inoidx or .B offset (index of inode in filesystem block) .HP .B inooff or .B inodeoff (byte offset in inode) .PD .RE .IP Only conversions that "make sense" are allowed. The compound form (with more than three arguments) is useful for conversions such as .B convert agno .I ag .B agbno .I agb .BR fsblock . .TP .BI "daddr [" d ] Set current address to the daddr (512 byte block) given by .IR d . If no value for .I d is given, the current address is printed, expressed as a daddr. The type is set to .B data (uninterpreted). .TP .BI dblock " filoff" Set current address to the offset .I filoff (a filesystem block number) in the data area of the current inode. .TP .BI "debug [" flagbits ] Set debug option bits. These are used for debugging .BR xfs_db . If no value is given for .IR flagbits , print the current debug option bits. These are for the use of the implementor. .TP .BI "dquot [" projectid_or_userid ] Set current address to a project or user quota block. .TP .BI "echo [" arg "] ..." Echo the arguments to the output. .TP .B f See the .B forward command. .TP .B forward Move forward to the next entry in the position ring. .TP .B frag [\-adflqRrv] Get file fragmentation data. This prints information about fragmentation of file data in the filesystem (as opposed to fragmentation of freespace, for which see the .B freesp command). Every file in the filesystem is examined to see how far from ideal its extent mappings are. A summary is printed giving the totals. .RS 1.0i .TP 0.4i .B \-v sets verbosity, every inode has information printed for it. The remaining options select which inodes and extents are examined. If no options are given then all are assumed set, otherwise just those given are enabled. .TP .B \-a enables processing of attribute data. .TP .B \-d enables processing of directory data. .TP .B \-f enables processing of regular file data. .TP .B \-l enables processing of symbolic link data. .TP .B \-q enables processing of quota file data. .TP .B \-R enables processing of realtime control file data. .TP .B \-r enables processing of realtime file data. .RE .TP .BI "freesp [\-bcds] [\-a " ag "] ... [\-e " i "] [\-h " h1 "] ... [\-m " m ] Summarize free space for the filesystem. The free blocks are examined and totalled, and displayed in the form of a histogram, with a count of extents in each range of free extent sizes. .RS 1.0i .TP 0.4i .B \-a adds .I ag to the list of allocation groups to be processed. If no .B \-a options are given then all allocation groups are processed. .TP .B \-b specifies that the histogram buckets are binary-sized, with the starting sizes being the powers of 2. .TP .B \-c specifies that .B freesp will search the by-size (cnt) space Btree instead of the default by-block (bno) space Btree. .TP .B \-d specifies that every free extent will be displayed. .TP .B \-e specifies that the histogram buckets are equal-sized, with the size specified as .IR i . .TP .B \-h specifies a starting block number for a histogram bucket as .IR h1 . Multiple .BR \-h 's are given to specify the complete set of buckets. .TP .B \-m specifies that the histogram starting block numbers are powers of .IR m . This is the general case of .BR \-b . .TP .B \-s specifies that a final summary of total free extents, free blocks, and the average free extent size is printed. .RE .TP .B fsb See the .B fsblock command. .TP .BI "fsblock [" fsb ] Set current address to the fsblock value given by .IR fsb . If no value for .I fsb is given the current address is printed, expressed as an fsb. The type is set to .B data (uninterpreted). XFS filesystem block numbers are computed .RI (( agno " << " agshift ") | " agblock ) where .I agshift depends on the size of an allocation group. Use the .B convert command to convert to and from this form. Block numbers given for file blocks (for instance from the .B bmap command) are in this form. .TP .BI hash " string Prints the hash value of .I string using the hash function of the XFS directory and attribute implementation. .TP .BI "help [" command ] Print help for one or all commands. .TP .BI "inode [" inode# ] Set the current inode number. If no .I inode# is given, print the current inode number. .TP .BI "label [" label ] Set the filesystem label. The filesystem label can be used by .BR mount (8) instead of using a device special file. The maximum length of an XFS label is 12 characters \- use of a longer .I label will result in truncation and a warning will be issued. If no .I label is given, the current filesystem label is printed. .TP .BI "log [stop | start " filename ] Start logging output to .IR filename , stop logging, or print the current logging status. .TP .BI "metadump [\-egow] " filename Dumps metadata to a file. See .BR xfs_metadump (8) for more information. .TP .BI "ncheck [\-s] [\-i " ino "] ..." Print name-inode pairs. A .B blockget \-n command must be run first to gather the information. .RS 1.0i .TP 0.4i .B \-i specifies an inode number to be printed. If no .B \-i options are given then all inodes are printed. .TP .B \-s specifies that only setuid and setgid files are printed. .RE .TP .B p See the .B print command. .TP .B pop Pop location from the stack. .TP .BI "print [" field-expression "] ..." Print field values. If no argument is given, print all fields in the current structure. .TP .BI "push [" command ] Push location to the stack. If .I command is supplied, set the current location to the results of .I command after pushing the old location. .TP .B q See the .B quit command. .TP .B quit Exit .BR xfs_db . .TP .BI "ring [" index ] Show position ring (if no .I index argument is given), or move to a specific entry in the position ring given by .IR index . .TP .BI "sb [" agno ] Set current address to SB header in allocation group .IR agno . If no .I agno is given, use the current allocation group number. .TP .BI "source " source-file Process commands from .IR source-file . .B source commands can be nested. .TP .B stack View the location stack. .TP .BI "type [" type ] Set the current data type to .IR type . If no argument is given, show the current data type. The possible data types are: .BR agf ", " agfl ", " agi ", " attr ", " bmapbta ", " bmapbtd , .BR bnobt ", " cntbt ", " data ", " dir ", " dir2 ", " dqblk , .BR inobt ", " inode ", " log ", " rtbitmap ", " rtsummary , .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP .BI "uuid [" uuid " | " generate " | " rewrite ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8) instead of using a device special file. The .I uuid can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the superblock in the filesystem. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock. If no argument is given, the current filesystem UUID is printed. .TP .BI "version [" feature " | " "versionnum features2" ] Enable selected features for a filesystem (certain features can be enabled on an unmounted filesystem, after .BR mkfs.xfs (8) has created the filesystem). Support for unwritten extents can be enabled using the .B extflg option. Support for version 2 log format can be enabled using the .B log2 option. Support for extended attributes can be enabled using the .B attr1 or .B attr2 option. Once enabled, extended attributes cannot be disabled, but the user may toggle between .B attr1 and .B attr2 at will (older kernels may not support the newer version). .IP If no argument is given, the current version and feature bits are printed. With one argument, this command will write the updated version number into every copy of the superblock in the filesystem. If two arguments are given, they will be used as numeric values for the .I versionnum and .I features2 bits respectively, and their string equivalent reported (but no modifications are made). .TP .BI "write [" "field value" "] ..." Write a value to disk. Specific fields can be set in structures (struct mode), or a block can be set to data values (data mode), or a block can be set to string values (string mode, for symlink blocks). The operation happens immediately: there is no buffering. .IP Struct mode is in effect when the current type is structural, i.e. not data. For struct mode, the syntax is "\c .B write .I field value\c ". .IP Data mode is in effect when the current type is data. In this case the contents of the block can be shifted or rotated left or right, or filled with a sequence, a constant value, or a random value. In this mode .B write with no arguments gives more information on the allowed commands. .SH TYPES This section gives the fields in each structure type and their meanings. Note that some types of block cover multiple actual structures, for instance directory blocks. .TP 1.0i .B agf The AGF block is the header for block allocation information; it is in the second 512-byte block of each allocation group. The following fields are defined: .RS 1.4i .PD 0 .TP 1.2i .B magicnum AGF block magic number, 0x58414746 ('XAGF'). .TP .B versionnum version number, currently 1. .TP .B seqno sequence number starting from 0. .TP .B length size in filesystem blocks of the allocation group. All allocation groups except the last one of the filesystem have the superblock's .B agblocks value here. .TP .B bnoroot block number of the root of the Btree holding free space information sorted by block number. .TP .B cntroot block number of the root of the Btree holding free space information sorted by block count. .TP .B bnolevel number of levels in the by-block-number Btree. .TP .B cntlevel number of levels in the by-block-count Btree. .TP .B flfirst index into the AGFL block of the first active entry. .TP .B fllast index into the AGFL block of the last active entry. .TP .B flcount count of active entries in the AGFL block. .TP .B freeblks count of blocks represented in the freespace Btrees. .TP .B longest longest free space represented in the freespace Btrees. .TP .B btreeblks number of blocks held in the AGF Btrees. .PD .RE .TP .B agfl The AGFL block contains block numbers for use of the block allocator; it is in the fourth 512-byte block of each allocation group. Each entry in the active list is a block number within the allocation group that can be used for any purpose if space runs low. The AGF block fields .BR flfirst ", " fllast ", and " flcount designate which entries are currently active. Entry space is allocated in a circular manner within the AGFL block. Fields defined: .RS 1.4i .PD 0 .TP 1.2i .B bno array of all block numbers. Even those which are not active are printed. .PD .RE .TP .B agi The AGI block is the header for inode allocation information; it is in the third 512-byte block of each allocation group. Fields defined: .RS 1.4i .PD 0 .TP 1.2i .B magicnum AGI block magic number, 0x58414749 ('XAGI'). .TP .B versionnum version number, currently 1. .TP .B seqno sequence number starting from 0. .TP .B length size in filesystem blocks of the allocation group. .TP .B count count of inodes allocated. .TP .B root block number of the root of the Btree holding inode allocation information. .TP .B level number of levels in the inode allocation Btree. .TP .B freecount count of allocated inodes that are not in use. .TP .B newino last inode number allocated. .TP .B dirino unused. .TP .B unlinked an array of inode numbers within the allocation group. The entries in the AGI block are the heads of lists which run through the inode .B next_unlinked field. These inodes are to be unlinked the next time the filesystem is mounted. .PD .RE .TP .B attr An attribute fork is organized as a Btree with the actual data embedded in the leaf blocks. The root of the Btree is found in block 0 of the fork. The index (sort order) of the Btree is the hash value of the attribute name. All the blocks contain a .B blkinfo structure at the beginning, see type .B dir for a description. Nonleaf blocks are identical in format to those for version 1 and version 2 directories, see type .B dir for a description. Leaf blocks can refer to "local" or "remote" attribute values. Local values are stored directly in the leaf block. Remote values are stored in an independent block in the attribute fork (with no structure). Leaf blocks contain the following fields: .RS 1.4i .PD 0 .TP 1.2i .B hdr header containing a .B blkinfo structure .B info (magic number 0xfbee), a .B count of active entries, .B usedbytes total bytes of names and values, the .B firstused byte in the name area, .B holes set if the block needs compaction, and array .B freemap as for .B dir leaf blocks. .TP .B entries array of structures containing a .BR hashval , .B nameidx (index into the block of the name), and flags .BR incomplete , .BR root , and .BR local . .TP .B nvlist array of structures describing the attribute names and values. Fields always present: .B valuelen (length of value in bytes), .BR namelen , and .BR name . Fields present for local values: .B value (value string). Fields present for remote values: .B valueblk (fork block number of containing the value). .PD .RE .TP .B bmapbt Files with many extents in their data or attribute fork will have the extents described by the contents of a Btree for that fork, instead of being stored directly in the inode. Each bmap Btree starts with a root block contained within the inode. The other levels of the Btree are stored in filesystem blocks. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block contains the following fields: .RS 1.4i .PD 0 .TP 1.2i .B magic bmap Btree block magic number, 0x424d4150 ('BMAP'). .TP .B level level of this block above the leaf level. .TP .B numrecs number of records or keys in the block. .TP .B leftsib left (logically lower) sibling block, 0 if none. .TP .B rightsib right (logically higher) sibling block, 0 if none. .TP .B recs [leaf blocks only] array of extent records. Each record contains .BR startoff , .BR startblock , .BR blockcount , and .B extentflag (1 if the extent is unwritten). .TP .B keys [nonleaf blocks only] array of key records. These are the first key value of each block in the level below this one. Each record contains .BR startoff . .TP .B ptrs [nonleaf blocks only] array of child block pointers. Each pointer is a filesystem block number to the next level in the Btree. .PD .RE .TP .B bnobt There is one set of filesystem blocks forming the by-block-number allocation Btree for each allocation group. The root block of this Btree is designated by the .B bnoroot field in the coresponding AGF block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: .RS 1.4i .PD 0 .TP 1.2i .B magic BNOBT block magic number, 0x41425442 ('ABTB'). .TP .B level level number of this block, 0 is a leaf. .TP .B numrecs number of data entries in the block. .TP .B leftsib left (logically lower) sibling block, 0 if none. .TP .B rightsib right (logically higher) sibling block, 0 if none. .TP .B recs [leaf blocks only] array of freespace records. Each record contains .B startblock and .BR blockcount . .TP .B keys [nonleaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .B startblock and .BR blockcount . .TP .B ptrs [nonleaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE .TP .B cntbt There is one set of filesystem blocks forming the by-block-count allocation Btree for each allocation group. The root block of this Btree is designated by the .B cntroot field in the coresponding AGF block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: .RS 1.4i .PD 0 .TP 1.2i .B magic CNTBT block magic number, 0x41425443 ('ABTC'). .TP .B level level number of this block, 0 is a leaf. .TP .B numrecs number of data entries in the block. .TP .B leftsib left (logically lower) sibling block, 0 if none. .TP .B rightsib right (logically higher) sibling block, 0 if none. .TP .B recs [leaf blocks only] array of freespace records. Each record contains .B startblock and .BR blockcount . .TP .B keys [nonleaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .B blockcount and .BR startblock . .TP .B ptrs [nonleaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE .TP .B data User file blocks, and other blocks whose type is unknown, have this type for display purposes in .BR xfs_db . The block data is displayed in hexadecimal format. .TP .B dir A version 1 directory is organized as a Btree with the directory data embedded in the leaf blocks. The root of the Btree is found in block 0 of the file. The index (sort order) of the Btree is the hash value of the entry name. All the blocks contain a .B blkinfo structure at the beginning with the following fields: .RS 1.4i .PD 0 .TP 1.2i .B forw next sibling block. .TP .B back previous sibling block. .TP .B magic magic number for this block type. .RE .IP The non-leaf (node) blocks have the following fields: .RS 1.4i .TP 1.2i .B hdr header containing a .B blkinfo structure .B info (magic number 0xfebe), the .B count of active entries, and the .B level of this block above the leaves. .TP .B btree array of entries containing .B hashval and .B before fields. The .B before value is a block number within the directory file to the child block, the .B hashval is the last hash value in that block. .RE .IP The leaf blocks have the following fields: .RS 1.4i .TP 1.2i .B hdr header containing a .B blkinfo structure .B info (magic number 0xfeeb), the .B count of active entries, .B namebytes (total name string bytes), .B holes flag (block needs compaction), and .B freemap (array of .BR base ", " size entries for free regions). .TP .B entries array of structures containing .BR hashval , .B nameidx (byte index into the block of the name string), and .BR namelen . .TP .B namelist array of structures containing .B inumber and .BR name . .RE .PD .TP .B dir2 A version 2 directory has four kinds of blocks. Data blocks start at offset 0 in the file. There are two kinds of data blocks: single-block directories have the leaf information embedded at the end of the block, data blocks in multi-block directories do not. Node and leaf blocks start at offset 32GiB (with either a single leaf block or the root node block). Freespace blocks start at offset 64GiB. The node and leaf blocks form a Btree, with references to the data in the data blocks. The freespace blocks form an index of longest free spaces within the data blocks. .IP A single-block directory block contains the following fields: .RS 1.4i .PD 0 .TP 1.2i .B bhdr header containing .B magic number 0x58443242 ('XD2B') and an array .B bestfree of the longest 3 free spaces in the block .RB ( offset ", " length ). .TP .B bu array of union structures. Each element is either an entry or a freespace. For entries, there are the following fields: .BR inumber , .BR namelen , .BR name , and .BR tag . For freespace, there are the following fields: .B freetag (0xffff), .BR length , and .BR tag . The .B tag value is the byte offset in the block of the start of the entry it is contained in. .TP .B bleaf array of leaf entries containing .B hashval and .BR address . The .B address is a 64-bit word offset into the file. .TP .B btail tail structure containing the total .B count of leaf entries and .B stale count of unused leaf entries. .RE .IP A data block contains the following fields: .RS 1.4i .TP 1.2i .B dhdr header containing .B magic number 0x58443244 ('XD2D') and an array .B bestfree of the longest 3 free spaces in the block .RB ( offset ", " length ). .TP .B du array of union structures as for .BR bu . .RE .IP Leaf blocks have two possible forms. If the Btree consists of a single leaf then the freespace information is in the leaf block, otherwise it is in separate blocks and the root of the Btree is a node block. A leaf block contains the following fields: .RS 1.4i .TP 1.2i .B lhdr header containing a .B blkinfo structure .B info (magic number 0xd2f1 for the single leaf case, 0xd2ff for the true Btree case), the total .B count of leaf entries, and .B stale count of unused leaf entries. .TP .B lents leaf entries, as for .BR bleaf . .TP .B lbests [single leaf only] array of values which represent the longest freespace in each data block in the directory. .TP .B ltail [single leaf only] tail structure containing .B bestcount count of .BR lbests . .RE .IP A node block is identical to that for types .B attr and .BR dir . A freespace block contains the following fields: .RS 1.4i .TP 1.2i .B fhdr header containing .B magic number 0x58443246 ('XD2F'), .B firstdb first data block number covered by this freespace block, .B nvalid number of valid entries, and .B nused number of entries representing real data blocks. .TP .B fbests array of values as for .BR lbests . .PD .RE .TP .B dqblk The quota information is stored in files referred to by the superblock .B uquotino and .B pquotino fields. Each filesystem block in a quota file contains a constant number of quota entries. The quota entry size is currently 136 bytes, so with a 4KiB filesystem block size there are 30 quota entries per block. The .B dquot command is used to locate these entries in the filesystem. The file entries are indexed by the user or project identifier to determine the block and offset. Each quota entry has the following fields: .RS 1.4i .PD 0 .TP 1.5i .B magic magic number, 0x4451 ('DQ'). .TP .B version version number, currently 1. .TP .B flags flags, values include 0x01 for user quota, 0x02 for project quota. .TP .B id user or project identifier. .TP .B blk_hardlimit absolute limit on blocks in use. .TP .B blk_softlimit preferred limit on blocks in use. .TP .B ino_hardlimit absolute limit on inodes in use. .TP .B ino_softlimit preferred limit on inodes in use. .TP .B bcount blocks actually in use. .TP .B icount inodes actually in use. .TP .B itimer time when service will be refused if soft limit is violated for inodes. .TP .B btimer time when service will be refused if soft limit is violated for blocks. .TP .B iwarns number of warnings issued about inode limit violations. .TP .B bwarns number of warnings issued about block limit violations. .TP .B rtb_hardlimit absolute limit on realtime blocks in use. .TP .B rtb_softlimit preferred limit on realtime blocks in use. .TP .B rtbcount realtime blocks actually in use. .TP .B rtbtimer time when service will be refused if soft limit is violated for realtime blocks. .TP .B rtbwarns number of warnings issued about realtime block limit violations. .PD .RE .TP .B inobt There is one set of filesystem blocks forming the inode allocation Btree for each allocation group. The root block of this Btree is designated by the .B root field in the coresponding AGI block. The blocks are linked to sibling left and right blocks at each level, as well as by pointers from parent to child blocks. Each block has the following fields: .RS 1.4i .PD 0 .TP 1.2i .B magic INOBT block magic number, 0x49414254 ('IABT'). .TP .B level level number of this block, 0 is a leaf. .TP .B numrecs number of data entries in the block. .TP .B leftsib left (logically lower) sibling block, 0 if none. .TP .B rightsib right (logically higher) sibling block, 0 if none. .TP .B recs [leaf blocks only] array of inode records. Each record contains .B startino allocation-group relative inode number, .B freecount count of free inodes in this chunk, and .B free bitmap, LSB corresponds to inode 0. .TP .B keys [nonleaf blocks only] array of key records. These are the first value of each block in the level below this one. Each record contains .BR startino . .TP .B ptrs [nonleaf blocks only] array of child block pointers. Each pointer is a block number within the allocation group to the next level in the Btree. .PD .RE .TP .B inode Inodes are allocated in "chunks" of 64 inodes each. Usually a chunk is multiple filesystem blocks, although there are cases with large filesystem blocks where a chunk is less than one block. The inode Btree (see .B inobt above) refers to the inode numbers per allocation group. The inode numbers directly reflect the location of the inode block on disk. Use the .B inode command to point .B xfs_db to a specific inode. Each inode contains four regions: .BR core , .BR next_unlinked , .BR u ", and " .BR a . .B core contains the fixed information. .B next_unlinked is separated from the core due to journaling considerations, see type .B agi field .BR unlinked . .B u is a union structure that is different in size and format depending on the type and representation of the file data ("data fork"). .B a is an optional union structure to describe attribute data, that is different in size, format, and location depending on the presence and representation of attribute data, and the size of the .B u data ("attribute fork"). .B xfs_db automatically selects the proper union members based on information in the inode. .IP The following are fields in the inode core: .RS 1.4i .PD 0 .TP 1.2i .B magic inode magic number, 0x494e ('IN'). .TP .B mode mode and type of file, as described in .BR chmod (2), .BR mknod (2), and .BR stat (2). .TP .B version inode version, 1 or 2. .TP .B format format of .B u union data (0: xfs_dev_t, 1: local file \- in-inode directory or symlink, 2: extent list, 3: Btree root, 4: unique id [unused]). .TP .B nlinkv1 number of links to the file in a version 1 inode. .TP .B nlinkv2 number of links to the file in a version 2 inode. .TP .B projid_lo owner's project id (low word; version 2 inode only). .B projid_hi owner's project id (high word; version 2 inode only). .TP .B uid owner's user id. .TP .B gid owner's group id. .TP .B atime time last accessed (seconds and nanoseconds). .TP .B mtime time last modified. .TP .B ctime time created or inode last modified. .TP .B size number of bytes in the file. .TP .B nblocks total number of blocks in the file including indirect and attribute. .TP .B extsize basic/minimum extent size for the file. .TP .B nextents number of extents in the data fork. .TP .B naextents number of extents in the attribute fork. .TP .B forkoff attribute fork offset in the inode, in 64-bit words from the start of .BR u . .TP .B aformat format of .B a data (1: local attribute data, 2: extent list, 3: Btree root). .TP .B dmevmask DMAPI event mask. .TP .B dmstate DMAPI state information. .TP .B newrtbm file is the realtime bitmap and is "new" format. .TP .B prealloc file has preallocated data space after EOF. .TP .B realtime file data is in the realtime subvolume. .TP .B gen inode generation number. .RE .IP The following fields are in the .B u data fork union: .RS 1.4i .TP 1.2i .B bmbt bmap Btree root. This looks like a .B bmapbtd block with redundant information removed. .TP .B bmx array of extent descriptors. .TP .B dev dev_t for the block or character device. .TP .B sfdir shortform (in-inode) version 1 directory. This consists of a .B hdr containing the .B parent inode number and a .B count of active entries in the directory, followed by an array .B list of .B hdr.count entries. Each such entry contains .BR inumber , .BR namelen , and .B name string. .TP .B sfdir2 shortform (in-inode) version 2 directory. This consists of a .B hdr containing a .B count of active entries in the directory, an .B i8count of entries with inumbers that don't fit in a 32-bit value, and the .B parent inode number, followed by an array .B list of .B hdr.count entries. Each such entry contains .BR namelen , a saved .B offset used when the directory is converted to a larger form, a .B name string, and the .BR inumber . .TP .B symlink symbolic link string value. .RE .IP The following fields are in the .B a attribute fork union if it exists: .RS 1.4i .TP 1.2i .B bmbt bmap Btree root, as above. .TP .B bmx array of extent descriptors. .TP .B sfattr shortform (in-inode) attribute values. This consists of a .B hdr containing a .B totsize (total size in bytes) and a .B count of active entries, followed by an array .B list of .B hdr.count entries. Each such entry contains .BR namelen , .BR valuelen , .BR root flag, .BR name , and .BR value . .PD .RE .TP .B log Log blocks contain the journal entries for XFS. It's not useful to examine these with .BR xfs_db , use .BR xfs_logprint (8) instead. .TP .B rtbitmap If the filesystem has a realtime subvolume, then the .B rbmino field in the superblock refers to a file that contains the realtime bitmap. Each bit in the bitmap file controls the allocation of a single realtime extent (set == free). The bitmap is processed in 32-bit words, the LSB of a word is used for the first extent controlled by that bitmap word. The .B atime field of the realtime bitmap inode contains a counter that is used to control where the next new realtime file will start. .TP .B rtsummary If the filesystem has a realtime subvolume, then the .B rsumino field in the superblock refers to a file that contains the realtime summary data. The summary file contains a two-dimensional array of 16-bit values. Each value counts the number of free extent runs (consecutive free realtime extents) of a given range of sizes that starts in a given bitmap block. The size ranges are binary buckets (low size in the bucket is a power of 2). There are as many size ranges as are necessary given the size of the realtime subvolume. The first dimension is the size range, the second dimension is the starting bitmap block number (adjacent entries are for the same size, adjacent bitmap blocks). .TP .B sb There is one sb (superblock) structure per allocation group. It is the first disk block in the allocation group. Only the first one (block 0 of the filesystem) is actually used; the other blocks are redundant information for .BR xfs_repair (8) to use if the first superblock is damaged. Fields defined: .RS 1.4i .PD 0 .TP 1.2i .B magicnum superblock magic number, 0x58465342 ('XFSB'). .TP .B blocksize filesystem block size in bytes. .TP .B dblocks number of filesystem blocks present in the data subvolume. .TP .B rblocks number of filesystem blocks present in the realtime subvolume. .TP .B rextents number of realtime extents that .B rblocks contain. .TP .B uuid unique identifier of the filesystem. .TP .B logstart starting filesystem block number of the log (journal). If this value is 0 the log is "external". .TP .B rootino root inode number. .TP .B rbmino realtime bitmap inode number. .TP .B rsumino realtime summary data inode number. .TP .B rextsize realtime extent size in filesystem blocks. .TP .B agblocks size of an allocation group in filesystem blocks. .TP .B agcount number of allocation groups. .TP .B rbmblocks number of realtime bitmap blocks. .TP .B logblocks number of log blocks (filesystem blocks). .TP .B versionnum filesystem version information. This value is currently 1, 2, 3, or 4 in the low 4 bits. If the low bits are 4 then the other bits have additional meanings. 1 is the original value. 2 means that attributes were used. 3 means that version 2 inodes (large link counts) were used. 4 is the bitmask version of the version number. In this case, the other bits are used as flags (0x0010: attributes were used, 0x0020: version 2 inodes were used, 0x0040: quotas were used, 0x0080: inode cluster alignment is in force, 0x0100: data stripe alignment is in force, 0x0200: the .B shared_vn field is used, 0x1000: unwritten extent tracking is on, 0x2000: version 2 directories are in use). .TP .B sectsize sector size in bytes, currently always 512. This is the size of the superblock and the other header blocks. .TP .B inodesize inode size in bytes. .TP .B inopblock number of inodes per filesystem block. .TP .B fname obsolete, filesystem name. .TP .B fpack obsolete, filesystem pack name. .TP .B blocklog log2 of .BR blocksize . .TP .B sectlog log2 of .BR sectsize . .TP .B inodelog log2 of .BR inodesize . .TP .B inopblog log2 of .BR inopblock . .TP .B agblklog log2 of .B agblocks (rounded up). .TP .B rextslog log2 of .BR rextents . .TP .B inprogress .BR mkfs.xfs (8) or .BR xfs_copy (8) aborted before completing this filesystem. .TP .B imax_pct maximum percentage of filesystem space used for inode blocks. .TP .B icount number of allocated inodes. .TP .B ifree number of allocated inodes that are not in use. .TP .B fdblocks number of free data blocks. .TP .B frextents number of free realtime extents. .TP .B uquotino user quota inode number. .TP .B pquotino project quota inode number; this is currently unused. .TP .B qflags quota status flags (0x01: user quota accounting is on, 0x02: user quota limits are enforced, 0x04: quotacheck has been run on user quotas, 0x08: project quota accounting is on, 0x10: project quota limits are enforced, 0x20: quotacheck has been run on project quotas). .TP .B flags random flags. 0x01: only read-only mounts are allowed. .TP .B shared_vn shared version number (shared readonly filesystems). .TP .B inoalignmt inode chunk alignment in filesystem blocks. .TP .B unit stripe or RAID unit. .TP .B width stripe or RAID width. .TP .B dirblklog log2 of directory block size (filesystem blocks). .PD .RE .TP .B symlink Symbolic link blocks are used only when the symbolic link value does not fit inside the inode. The block content is just the string value. Bytes past the logical end of the symbolic link value have arbitrary values. .TP .B text User file blocks, and other blocks whose type is unknown, have this type for display purposes in .BR xfs_db . The block data is displayed in two columns: Hexadecimal format and printable ASCII chars. .SH DIAGNOSTICS Many messages can come from the .B check .RB ( blockget ) command; these are documented in .BR xfs_check (8). .SH SEE ALSO .BR mkfs.xfs (8), .BR xfs_admin (8), .BR xfs_check (8), .BR xfs_copy (8), .BR xfs_logprint (8), .BR xfs_metadump (8), .BR xfs_ncheck (8), .BR xfs_repair (8), .BR mount (8), .BR chmod (2), .BR mknod (2), .BR stat (2), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_bmap.80000664000000000000000000000436611140033220015115 0ustar .TH xfs_bmap 8 .SH NAME xfs_bmap \- print block mapping for an XFS file .SH SYNOPSIS .B xfs_bmap [ .B \-adlpv ] [ .B \-n .I num_extents ] .I file .SH DESCRIPTION .B xfs_bmap prints the map of disk blocks used by files in an XFS filesystem. The map lists each .I extent used by the file, as well as regions in the file that do not have any corresponding blocks (holes). Each line of the listings takes the following form: .PP .RS .IR extent ": [" startoffset .. endoffset "]: " startblock .. endblock .RE .PP Holes are marked by replacing the .IR startblock .. endblock " with " hole . All the file offsets and disk blocks are in units of 512-byte blocks, no matter what the filesystem's block size is. .PP .SH OPTIONS .TP .B \-a If this option is specified, information about the file's attribute fork is printed instead of the default data fork. .TP .B \-d If portions of the file have been migrated offline by a DMAPI application, a DMAPI read event will be generated to bring those portions back online before the disk block map is printed. However if the .B \-d option is used, no DMAPI read event will be generated for a DMAPI file and offline portions will be reported as holes. .TP .B \-l If this option is used, then .IP .RS 1.2i .RI < nblocks "> blocks" .RE .IP will be appended to each line. .I nblocks is the length of the extent described on the line in units of 512-byte blocks. .IP This flag has no effect if the .B \-v option is used. .TP .BI \-n " num_extents" If this option is given, .B xfs_bmap obtains the extent list of the file in groups of .I num_extents extents. In the absence of .BR \-n ", " xfs_bmap queries the system for the number of extents in the file and uses that value to compute the group size. .TP .B \-p If this option is used, .B xfs_bmap obtains all unwritten (preallocated) extents that do not contain written data. With the .B \-v option, the .I flags column will show which extents are preallocated/unwritten. .TP .B \-v Shows verbose information. When this flag is specified, additional AG specific information is appended to each line in the following form: .IP .RS 1.2i .IR agno " (" startagoffset .. endagoffset ") " nblocks " " flags .RE .IP A second .B \-v option will print out the .I flags legend. .SH SEE ALSO .BR xfs_fsr (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_quota.80000664000000000000000000004525311200167233015340 0ustar .TH xfs_quota 8 .SH NAME xfs_quota \- manage use of quota on XFS filesystems .SH SYNOPSIS .B xfs_quota [ .B \-x ] [ .B \-p .I prog ] [ .B \-c .I cmd ] ... [ .B \-d .I project ] ... [ .IR path " ... ]" .SH DESCRIPTION .B xfs_quota is a utility for reporting and editing various aspects of filesystem quota. .PP The options to .B xfs_quota are: .TP 1.0i .BI \-c " cmd" .B xfs_quota commands may be run interactively (the default) or as arguments on the command line. Multiple .B \-c arguments may be given. The commands are run in the sequence given, then the program exits. .TP .BI \-p " prog" Set the program name for prompts and some error messages, the default value is .BR xfs_quota . .TP .B \-x Enable expert mode. All of the administrative commands (see the ADMINISTRATOR COMMANDS section below) which allow modifications to the quota system are available only in expert mode. .TP .BI \-d " project" Project names or numeric identifiers may be specified with this option, which restricts the output of the individual .B xfs_quota commands to the set of projects specified. Multiple .B \-d arguments may be given. .PP The optional .I path argument(s) can be used to specify mount points or device files which identify XFS filesystems. The output of the individual .B xfs_quota commands will then be restricted to the set of filesystems specified. .PP This manual page is divided into two sections \- firstly, information for users of filesystems with quota enabled, and the .B xfs_quota commands of interest to such users; and then information which is useful only to administrators of XFS filesystems using quota and the quota commands which allow modifications to the quota system. .PP Note that common to almost all of the individual commands described below are the options for specifying which quota types are of interest \- user quota .RB ( \-u ), group quota .RB ( \-g ), and/or project quota .RB ( \-p ). Also, several commands provide options to operate on "blocks used" .RB ( \-b ), "inodes used" .RB ( \-i ), and/or "realtime blocks used" .RB ( \-r ). .PP Many commands also have extensive online help. Use the .B help command for more details on any command. .SH QUOTA OVERVIEW .PP In most computing environments, disk space is not infinite. The quota subsystem provides a mechanism to control usage of disk space. Quotas can be set for each individual user on any/all of the local filesystems. The quota subsystem warns users when they exceed their allotted limit, but allows some extra space for current work (hard limit/soft limit). In addition, XFS filesystems with limit enforcement turned off can be used as an effective disk usage accounting system. .SS Users' View of Disk Quotas To most users, disk quotas are either of no concern or a fact of life that cannot be avoided. There are two possible quotas that can be imposed \- a limit can be set on the amount of space a user can occupy, and there may be a limit on the number of files (inodes) he can own. .PP The .B quota command provides information on the quotas that have been set by the system administrators and current usage. .PP There are four numbers for each limit: current usage, soft limit (quota), hard limit, and time limit. The soft limit is the number of 1K-blocks (or files) that the user is expected to remain below. The hard limit cannot be exceeded. If a user's usage reaches the hard limit, further requests for space (or attempts to create a file) fail with the "Quota exceeded" (EDQUOT) error. .PP When a user exceeds the soft limit, the timer is enabled. Any time the quota drops below the soft limits, the timer is disabled. If the timer pops, the particular limit that has been exceeded is treated as if the hard limit has been reached, and no more resources are allocated to the user. The only way to reset this condition, short of turning off limit enforcement or increasing the limit, is to reduce usage below quota. Only the superuser (i.e. a sufficiently capable process) can set the time limits and this is done on a per filesystem basis. .SS Surviving When the Quota Limit Is Reached In most cases, the only way for a user to recover from over-quota conditions is to abort whatever activity is in progress on the filesystem that has reached its limit, remove sufficient files to bring the limit back below quota, and retry the failed program. .br However, if a user is in the editor and a write fails because of an over quota situation, that is not a suitable course of action. It is most likely that initially attempting to write the file has truncated its previous contents, so if the editor is aborted without correctly writing the file, not only are the recent changes lost, but possibly much, or even all, of the contents that previously existed. .br There are several possible safe exits for a user caught in this situation. He can use the editor shell escape command to examine his file space and remove surplus files. Alternatively, using .BR sh (1), he can suspend the editor, remove some files, then resume it. A third possibility is to write the file to some other filesystem (perhaps to a file on .IR /tmp ) where the user's quota has not been exceeded. Then after rectifying the quota situation, the file can be moved back to the filesystem it belongs on. .SH USER COMMANDS .TP .B print Lists all paths with devices/project identifiers. The path list can come from several places \- the command line, the mount table, and the .I /etc/projects file. .TP .B df See the .B free command. .HP .B quota [ .B \-gpu ] [ .B \-bir ] [ .B \-hnNv ] [ .B \-f .I file ] [ .I ID | .I name ] ... .br Show individual usage and limits, for a single user .I name or numeric user .IR ID . The .B \-h option reports in a "human-readable" format similar to the .BR df (1) command. The .B \-n option reports the numeric IDs rather than the name. The .B \-N option omits the header. The .B \-v option outputs verbose information. The .B \-f option sends the output to .I file instead of stdout. .HP .B free [ .B \-bir ] [ .B \-hN ] [ .B \-f .I file ] .br Reports filesystem usage, much like the .BR df (1) utility. It can show usage for .BR b locks, .BR i node, and/or .BR r ealtime block space, and shows used, free, and total available. If project quota are in use (see the DIRECTORY TREE QUOTA section below), it will also report utilisation for those projects (directory trees). The .B \-h option reports in a "human-readable" format. The .B \-N option omits the header. The .B \-f option outputs the report to .I file instead of stdout. .HP .B help [ .I command ] .br Online help for all commands, or one specific .IR command . .TP .B quit Exit .BR xfs_quota . .TP .B q See the .B quit command. .SH QUOTA ADMINISTRATION The XFS quota system differs to that of other filesystems in a number of ways. Most importantly, XFS considers quota information as filesystem metadata and uses journaling to provide a higher level guarantee of consistency. As such, it is administered differently, in particular: .IP 1. The .B quotacheck command has no effect on XFS filesystems. The first time quota accounting is turned on (at mount time), XFS does an automatic quotacheck internally; afterwards, the quota system will always be completely consistent until quotas are manually turned off. .IP 2. There is no need for quota file(s) in the root of the XFS filesystem. .IP 3. XFS distinguishes between quota accounting and limit enforcement. Quota accounting must be turned on at the time of mounting the XFS filesystem. However, it is possible to turn on/off limit enforcement any time quota accounting is turned on. The "quota" option to the .B mount command turns on both (user) quota accounting and enforcement. The "uqnoenforce" option must be used to turn on user accounting with limit enforcement disabled. .IP 4. Turning on quotas on the root filesystem is slightly different from the above. For IRIX XFS, refer to .BR quotaon (1M). For Linux XFS, the quota mount flags must be passed in with the "rootflags=" boot parameter. .IP 5. It is useful to use the .B state to monitor the XFS quota subsystem at various stages \- it can be used to see if quotas are turned on, and also to monitor the space occupied by the quota system itself.. .IP 6. There is a mechanism built into .B xfsdump that allows quota limit information to be backed up for later restoration, should the need arise. .IP 7. Quota limits cannot be set before turning on quotas on. .IP 8. XFS filesystems keep quota accounting on the superuser (user ID zero), and the tool will display the superuser's usage information. However, limits are never enforced on the superuser (nor are they enforced for group and project ID zero). .IP 9. XFS filesystems perform quota accounting whether the user has quota limits or not. .IP 10. XFS supports the notion of project quota, which can be used to implement a form of directory tree quota (i.e. to restrict a directory tree to only being able to use up a component of the filesystems available space; or simply to keep track of the amount of space used, or number of inodes, within the tree). .SH ADMINISTRATOR COMMANDS .HP .B path [ .I N ] .br Lists all paths with devices/project identifiers or set the current path to the .IR N th list entry (the current path is used by many of the commands described here, it identifies the filesystem toward which a command is directed). The patch list can come from several places \- the command line, the mount table, and the .I /etc/projects file. .HP .B report [ .B \-gpu ] [ .B \-bir ] [ .B \-ahntLNU ] [ .B \-f .I file ] .br Report filesystem quota information. This reports all quota usage for a filesystem, for the specified quota type .RB ( u / g / p and/or .BR b locks/ i nodes/ r ealtime). It reports blocks in 1KB units by default. The .B \-h option reports in a "human-readable" format similar to the .BR df (1) command. The .B \-f option outputs the report to .I file instead of stdout. The .B \-a option reports on all filesystems. The .B \-n option outputs the numeric ID instead of the name. The .B \-L and .B \-U options specify lower and upper ID bounds to report on. The .B \-N option reports information without the header line. The .B \-t option performs a terse report. .HP .B state [ .B \-gpu ] [ .B \-av ] [ .B \-f .I file ] .br Report overall quota state information. This reports on the state of quota accounting, quota enforcement, and the number of extents being used by quota metadata within the filesystem. The .B \-f option outputs state information to .I file instead of stdout. The .B \-a option reports state on all filesystems and not just the current path. .HP .B limit [ .B \-gpu ] .BI bsoft= N | .BI bhard= N | .BI isoft= N | .BI ihard= N | .BI rtbsoft= N | .BI rtbhard= N .B \-d | .I id | .I name .br Set quota block limits (bhard/bsoft), inode count limits (ihard/isoft) and/or realtime block limits (rtbhard/rtbsoft). The .B \-d option (defaults) can be used to set the default value that will be used, otherwise a specific .BR u ser/ g roup/ p roject .I name or numeric .IR id entifier must be specified. .HP .B timer [ .B \-gpu ] [ .B \-bir ] .I value .br Allows the quota enforcement timeout (i.e. the amount of time allowed to pass before the soft limits are enforced as the hard limits) to be modified. The current timeout setting can be displayed using the .B state command. The value argument is a number of seconds, but units of \&'minutes', 'hours', 'days', and 'weeks' are also understood (as are their abbreviations 'm', 'h', 'd', and 'w'). .HP .B warn [ .B \-gpu ] [ .B \-bir ] .I value .B -d | .I id | .I name .br Allows the quota warnings limit (i.e. the number of times a warning will be send to someone over quota) to be viewed and modified. The .B \-d option (defaults) can be used to set the default time that will be used, otherwise a specific .BR u ser/ g roup/ p roject .I name or numeric .IR id entifier must be specified. .B NOTE: this feature is not currently implemented. .TP .BR enable " [ " \-gpu " ] [ " \-v " ]" Switches on quota enforcement for the filesystem identified by the current path. This requires the filesystem to have been mounted with quota enabled, and for accounting to be currently active. The .B \-v option (verbose) displays the state after the operation has completed. .TP .BR disable " [ " \-gpu " ] [ " \-v " ]" Disables quota enforcement, while leaving quota accounting active. The .B \-v option (verbose) displays the state after the operation has completed. .TP .BR off " [ " \-gpu " ] [ " \-v " ]" Permanently switches quota off for the filesystem identified by the current path. Quota can only be switched back on subsequently by unmounting and then mounting again. .TP .BR remove " [ " \-gpu " ] [ " \-v " ]" Remove any space allocated to quota metadata from the filesystem identified by the current path. Quota must not be enabled on the filesystem, else this operation will report an error. .HP .B dump [ .B \-gpu ] [ .B \-f .I file ] .br Dump out quota limit information for backup utilities, either to standard output (default) or to a .IR file . This is only the limits, not the usage information, of course. .HP .B restore [ .B \-gpu ] [ .B \-f .I file ] .br Restore quota limits from a backup .IR file . The file must be in the format produced by the .B dump command. .HP .B quot [ .B \-gpu ] [ .B \-bir ] [ .B \-acnv ] [ .B \-f .I file ] .br Summarize filesystem ownership, by user, group or project. This command uses a special XFS "bulkstat" interface to quickly scan an entire filesystem and report usage information. This command can be used even when filesystem quota are not enabled, as it is a full-filesystem scan (it may also take a long time...). The .B \-a option displays information on all filesystems. The .B \-c option displays a histogram instead of a report. The .B \-n option displays numeric IDs rather than names. The .B \-v option displays verbose information. The .B \-f option send the output to .I file instead of stdout. .HP .B project [ .B \-cCs [ .B \-d .I depth ] [ .B \-p .I path ] .I id | .I name ] .br Without arguments, this command lists known project names and identifiers (based on entries in the .I /etc/projects and .I /etc/projid files). The .BR \-c , .BR \-C , and .B \-s options allow the directory tree quota mechanism to be maintained. .BR \-d allows to limit recursion level when processing project directories and .BR \-p allows to specify project paths at command line ( instead of .I /etc/projects ). All options are discussed in detail below. .SH DIRECTORY TREE QUOTA The project quota mechanism in XFS can be used to implement a form of directory tree quota, where a specified directory and all of the files and subdirectories below it (i.e. a tree) can be restricted to using a subset of the available space in the filesystem. .PP A managed tree must be setup initially using the .B \-s option to the .B project command. The specified project name or identifier is matched to one or more trees defined in .IR /etc/projects , and these trees are then recursively descended to mark the affected inodes as being part of that tree. This process sets an inode flag and the project identifier on every file in the affected tree. Once this has been done, new files created in the tree will automatically be accounted to the tree based on their project identifier. An attempt to create a hard link to a file in the tree will only succeed if the project identifier matches the project identifier for the tree. The .B xfs_io utility can be used to set the project ID for an arbitrary file, but this can only be done by a privileged user. .PP A previously setup tree can be cleared from project quota control through use of the .B project \-C option, which will recursively descend the tree, clearing the affected inodes from project quota control. .PP Finally, the .B project \-c option can be used to check whether a tree is setup, it reports nothing if the tree is correct, otherwise it reports the paths of inodes which do not have the project ID of the rest of the tree, or if the inode flag is not set. .PP Option .B \-d can be used to limit recursion level (\-1 is infinite, 0 is top level only, 1 is first level ... ). Option .B \-p adds posibility to specify project paths in command line without a need for .I /etc/projects to exist. Note that if projects file exists then it is also used. .SH EXAMPLES Enabling quota enforcement on an XFS filesystem (restrict a user to a set amount of space). .nf .sp .in +5 # mount \-o uquota /dev/xvm/home /home # xfs_quota \-x \-c 'limit bsoft=500m bhard=550m tanya' /home # xfs_quota \-x \-c report /home .in -5 .fi .PP Enabling project quota on an XFS filesystem (restrict files in log file directories to only using 1 gigabyte of space). .nf .sp .in +5 # mount \-o prjquota /dev/xvm/var /var # echo 42:/var/log >> /etc/projects # echo logfiles:42 >> /etc/projid # xfs_quota \-x \-c 'project \-s logfiles' /var # xfs_quota \-x \-c 'limit \-p bhard=1g logfiles' /var .in -5 .fi .PP Same as above without a need for configuration files. .nf .sp .in +5 # rm \-f /etc/projects /etc/projid # mount \-o prjquota /dev/xvm/var /var # xfs_quota \-x \-c 'project \-s \-p /var/log 42' /var # xfs_quota \-x \-c 'limit \-p bhard=1g 42' /var .in -5 .fi .SH CAVEATS XFS implements delayed allocation (aka. allocate-on-flush) and this has implications for the quota subsystem. Since quota accounting can only be done when blocks are actually allocated, it is possible to issue (buffered) writes into a file and not see the usage immediately updated. Only when the data is actually written out, either via one of the kernels flushing mechanisms, or via a manual .BR sync (2), will the usage reported reflect what has actually been written. .PP In addition, the XFS allocation mechanism will always reserve the maximum amount of space required before proceeding with an allocation. If insufficient space for this reservation is available, due to the block quota limit being reached for example, this may result in the allocation failing even though there is sufficient space. Quota enforcement can thus sometimes happen in situations where the user is under quota and the end result of some operation would still have left the user under quota had the operation been allowed to run its course. This additional overhead is typically in the range of tens of blocks. .PP Both of these properties are unavoidable side effects of the way XFS operates, so should be kept in mind when assigning block limits. .SH BUGS Quota support for filesystems with realtime subvolumes is not yet implemented, nor is the quota warning mechanism (the Linux .BR warnquota (8) tool can be used to provide similar functionality on that platform). .SH FILES .PD 0 .TP 20 .I /etc/projects Mapping of numeric project identifiers to directories trees. .TP .I /etc/projid Mapping of numeric project identifiers to project names. .PD .SH IRIX SEE ALSO .BR quotaon (1M), .BR xfs (4). .SH LINUX SEE ALSO .BR warnquota (8), .BR xfs (5). .SH SEE ALSO .BR df (1), .BR mount (1), .BR sync (2), .BR projid (5), .BR projects (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_freeze.80000664000000000000000000000377011146407622015475 0ustar .TH xfs_freeze 8 .SH NAME xfs_freeze \- suspend access to an XFS filesystem .SH SYNOPSIS .B xfs_freeze \-f | .B \-u .I mount-point .fi .SH DESCRIPTION .B xfs_freeze suspends and resumes access to an XFS filesystem (see .BR xfs (5)). .PP .B xfs_freeze halts new access to the filesystem and creates a stable image on disk. .B xfs_freeze is intended to be used with volume managers and hardware RAID devices that support the creation of snapshots. .PP The .I mount-point argument is the pathname of the directory where the filesystem is mounted. The filesystem must be mounted to be frozen (see .BR mount (8)). .PP The .B \-f flag requests the specified XFS filesystem to be frozen from new modifications. When this is selected, all ongoing transactions in the filesystem are allowed to complete, new write system calls are halted, other calls which modify the filesystem are halted, and all dirty data, metadata, and log information are written to disk. Any process attempting to write to the frozen filesystem will block waiting for the filesystem to be unfrozen. .PP Note that even after freezing, the on-disk filesystem can contain information on files that are still in the process of unlinking. These files will not be unlinked until the filesystem is unfrozen or a clean mount of the snapshot is complete. .PP The .B \-u flag is used to un-freeze the filesystem and allow operations to continue. Any filesystem modifications that were blocked by the freeze are unblocked and allowed to complete. .PP One of .B \-f or .B \-u must be supplied to .BR xfs_freeze . .SH NOTES A copy of a frozen XFS filesystem will usually have the same universally unique identifier (UUID) as the original, and thus may be prevented from being mounted. The XFS .B nouuid mount option can be used to circumvent this issue. .PP In Linux kernel version 2.6.29, the interface which XFS uses to freeze and unfreeze was elevated to the VFS, so that this tool can now be used on many other Linux filesystems. .SH SEE ALSO .BR xfs (5), .BR lvm (8), .BR mount (8). xfsprogs-3.1.9ubuntu2/man/man8/xfs_estimate.80000664000000000000000000000423511200167240016013 0ustar .TH xfs_estimate 8 .SH NAME xfs_estimate \- estimate the space that an XFS filesystem will take .SH SYNOPSIS .nf \f3xfs_estimate\f1 [ \f3\-h?\f1 ] [ \f3\-b\f1 blocksize ] [ \f3\-i\f1 logsize ] [ \f3\-e\f1 logsize ] [ \f3\-v\f1 ] directory ... .fi .SH DESCRIPTION For each \f2directory\f1 argument, .I xfs_estimate estimates the space that directory would take if it were copied to an XFS filesystem. .I xfs_estimate does not cross mount points. The following definitions are used: .PD 0 .IP KB = *1024 .IP MB = *1024*1024 .IP GB = *1024*1024*1024 .PD .PP The .I xfs_estimate options are: .TP \f3\-b\f1 \f2blocksize\f1 Use .I blocksize instead of the default blocksize of 4096 bytes. The modifier .B k can be used after the number to indicate multiplication by 1024. For example, .sp .8v .RS \f4xfs_estimate \-b 64k /\f1 .RE .IP requests an estimate of the space required by the directory / on an XFS filesystem using a blocksize of 64K (65536) bytes. .TP .B \-v Display more information, formatted. .TP .B \-h Display usage message. .TP .B \-? Display usage message. .TP \f3\-i, \-e\f1 \f2logsize\f1 Use .I logsize instead of the default log size of 1000 blocks. .B \-i refers to an internal log, while .B \-e refers to an external log. The modifiers .B k or .B m can be used after the number to indicate multiplication by 1024 or 1048576, respectively. .IP For example, .sp .8v .RS \f4xfs_estimate \-i 1m /\f1 .RE .IP requests an estimate of the space required by the directory / on an XFS filesystem using an internal log of 1 megabyte. .SH EXAMPLES .nf .sp 8v % \f4xfs_estimate \-e 10m /var/tmp\f1\f7 /var/tmp will take about 4.2 megabytes with the external log using 2560 blocks or about 10.0 megabytes .fi .nf .sp .8v % \f4xfs_estimate \-v \-e 10m /var/tmp\f1\f7 directory bsize blocks megabytes logsize /var/tmp 4096 792 4.0MB 10485760 .fi .nf .sp .8v % \f4xfs_estimate \-v /var/tmp\f1\f7 directory bsize blocks megabytes logsize /var/tmp 4096 3352 14.0MB 10485760 .fi .nf .sp .8v % \f4xfs_estimate /var/tmp\f1\f7 /var/tmp will take about 14.0 megabytes .fi xfsprogs-3.1.9ubuntu2/man/man8/xfs_repair.80000664000000000000000000003701111140033220015451 0ustar .TH xfs_repair 8 .SH NAME xfs_repair \- repair an XFS filesystem .SH SYNOPSIS .B xfs_repair [ .B \-dfLnPv ] [ .B \-m .I maxmem ] [ .BI \-c " subopt" = value ] [ .B \-o .I subopt\c [\c .B =\c .IR value ] ] [ .B \-t .I interval ] [ .B \-l .I logdev ] [ .B \-r .I rtdev ] .I device .br .B xfs_repair \-V .SH DESCRIPTION .B xfs_repair repairs corrupt or damaged XFS filesystems (see .BR xfs (5)). The filesystem is specified using the .I device argument which should be the device name of the disk partition or volume containing the filesystem. If given the name of a block device, .B xfs_repair will attempt to find the raw device associated with the specified block device and will use the raw device instead. .PP Regardless, the filesystem to be repaired must be unmounted, otherwise, the resulting filesystem may be inconsistent or corrupt. .SH OPTIONS .TP .B \-f Specifies that the filesystem image to be processed is stored in a regular file at .I device (see the .B mkfs.xfs \-d .I file option). This might happen if an image copy of a filesystem has been copied or written into an ordinary file. This option implies that any external log or realtime section is also in an ordinary file. .TP .B \-L Force Log Zeroing. Forces .B xfs_repair to zero the log even if it is dirty (contains metadata changes). When using this option the filesystem will likely appear to be corrupt, and can cause the loss of user files and/or data. .TP .BI \-l " logdev" Specifies the device special file where the filesystem's external log resides. Only for those filesystems which use an external log. See the .B mkfs.xfs \-l option, and refer to .BR xfs (5) for a detailed description of the XFS log. .TP .BI \-r " rtdev" Specifies the device special file where the filesystem's realtime section resides. Only for those filesystems which use a realtime section. See the .B mkfs.xfs \-r option, and refer to .BR xfs (5) for a detailed description of the XFS realtime section. .TP .B \-n No modify mode. Specifies that .B xfs_repair should not modify the filesystem but should only scan the filesystem and indicate what repairs would have been made. .TP .B \-P Disable prefetching of inode and directory blocks. Use this option if you find .B xfs_repair gets stuck and stops proceeding. Interrupting a stuck .B xfs_repair is safe. .TP .BI \-m " maxmem" Specifies the approximate maximum amount of memory, in megabytes, to use for .BR xfs_repair . .B xfs_repair has its own internal block cache which will scale out up to the lesser of the process's virtual address limit or about 75% of the system's physical RAM. This option overrides these limits. .IP .B NOTE: These memory limits are only approximate and may use more than the specified limit. .TP .BI \-c " subopt" = value Change filesystem parameters. Refer to .BR xfs_admin (8) for information on changing filesystem parameters. .HP .B \-o .I subopt\c [\c .B =\c .IR value ] .br Override what the program might conclude about the filesystem if left to its own devices. .IP The .IR subopt ions supported are: .RS 1.0i .TP .BI ihash= ihashsize overrides the default inode cache hash size. The total number of inode cache entries are limited to 8 times this amount. The default .I ihashsize is 1024 (for a total of 8192 entries). .TP .BI bhash= bhashsize overrides the default buffer cache hash size. The total number of buffer cache entries are limited to 8 times this amount. The default size is set to use up the remainder of 75% of the system's physical RAM size. .TP .BI ag_stride= ags_per_concat_unit This creates additional processing threads to parallel process AGs that span multiple concat units. This can significantly reduce repair times on concat based filesystems. .TP .BI force_geometry Check the filesystem even if geometry information could not be validated. Geometry information can not be validated if only a single allocation group and exist and thus we do not have a backup superblock available, or if there are two allocation groups and the two superblocks do not agree on the filesystem geometry. Only use this option if you validated the geometry yourself and know what you are doing. If In doubt run in no modify mode first. .RE .TP .B \-t " interval" Modify reporting interval. During long runs .B xfs_repair outputs its progress every 15 minutes. Reporting is only activated when ag_stride is enabled. .TP .B \-v Verbose output. .TP .B \-d Repair dangerously. Allow .B xfs_repair to repair an XFS filesystem mounted read only. This is typically done on a root fileystem from single user mode, immediately followed by a reboot. .TP .B \-V Prints out the current version number and exits. .SS Checks Performed Inconsistencies corrected include the following: .IP 1. Inode and inode blockmap (addressing) checks: bad magic number in inode, bad magic numbers in inode blockmap blocks, extents out of order, incorrect number of records in inode blockmap blocks, blocks claimed that are not in a legal data area of the filesystem, blocks that are claimed by more than one inode. .IP 2. Inode allocation map checks: bad magic number in inode map blocks, inode state as indicated by map (free or in-use) inconsistent with state indicated by the inode, inodes referenced by the filesystem that do not appear in the inode allocation map, inode allocation map referencing blocks that do not appear to contain inodes. .IP 3. Size checks: number of blocks claimed by inode inconsistent with inode size, directory size not block aligned, inode size not consistent with inode format. .IP 4. Directory checks: bad magic numbers in directory blocks, incorrect number of entries in a directory block, bad freespace information in a directory leaf block, entry pointing to an unallocated (free) or out of range inode, overlapping entries, missing or incorrect dot and dotdot entries, entries out of hashvalue order, incorrect internal directory pointers, directory type not consistent with inode format and size. .IP 5. Pathname checks: files or directories not referenced by a pathname starting from the filesystem root, illegal pathname components. .IP 6. Link count checks: link counts that do not agree with the number of directory references to the inode. .IP 7. Freemap checks: blocks claimed free by the freemap but also claimed by an inode, blocks unclaimed by any inode but not appearing in the freemap. .IP 8. Super Block checks: total free block and/or free i-node count incorrect, filesystem geometry inconsistent, secondary and primary superblocks contradictory. .PP Orphaned files and directories (allocated, in-use but unreferenced) are reconnected by placing them in the .I lost+found directory. The name assigned is the inode number. .SS Disk Errors .B xfs_repair aborts on most disk I/O errors. Therefore, if you are trying to repair a filesystem that was damaged due to a disk drive failure, steps should be taken to ensure that all blocks in the filesystem are readable and writeable before attempting to use .B xfs_repair to repair the filesystem. A possible method is using .BR dd (8) to copy the data onto a good disk. .SS lost+found The directory .I lost+found does not have to already exist in the filesystem being repaired. If the directory does not exist, it is automatically created if required. If it already exists, it will be checked for consistency and if valid will be used for additional orphaned files. Invalid .I lost+found directories are removed and recreated. Existing files in a valid .I lost+found are not removed or renamed. .SS Corrupted Superblocks XFS has both primary and secondary superblocks. .B xfs_repair uses information in the primary superblock to automatically find and validate the primary superblock against the secondary superblocks before proceeding. Should the primary be too corrupted to be useful in locating the secondary superblocks, the program scans the filesystem until it finds and validates some secondary superblocks. At that point, it generates a primary superblock. .SS Quotas If quotas are in use, it is possible that .B xfs_repair will clear some or all of the filesystem quota information. If so, the program issues a warning just before it terminates. If all quota information is lost, quotas are disabled and the program issues a warning to that effect. .PP Note that .B xfs_repair does not check the validity of quota limits. It is recommended that you check the quota limit information manually after .BR xfs_repair . Also, space usage information is automatically regenerated the next time the filesystem is mounted with quotas turned on, so the next quota mount of the filesystem may take some time. .SH DIAGNOSTICS .B xfs_repair issues informative messages as it proceeds indicating what it has found that is abnormal or any corrective action that it has taken. Most of the messages are completely understandable only to those who are knowledgeable about the structure of the filesystem. Some of the more common messages are explained here. Note that the language of the messages is slightly different if .B xfs_repair is run in no-modify mode because the program is not changing anything on disk. No-modify mode indicates what it would do to repair the filesystem if run without the no-modify flag. .PP .B disconnected inode .IB ino , .B moving to lost+found .IP An inode numbered .I ino was not connected to the filesystem directory tree and was reconnected to the .I lost+found directory. The inode is assigned the name of its inode number .RI ( ino ). If a .I lost+found directory does not exist, it is automatically created. .PP .B disconnected dir inode .IB ino , .B moving to lost+found .IP As above only the inode is a directory inode. If a directory inode is attached to .IR lost+found , all of its children (if any) stay attached to the directory and therefore get automatically reconnected when the directory is reconnected. .PP .B imap claims in-use inode .I ino .B is free, correcting imap .IP The inode allocation map thinks that inode .I ino is free whereas examination of the inode indicates that the inode may be in use (although it may be disconnected). The program updates the inode allocation map. .PP .B imap claims free inode .I ino .B is in use, correcting imap .IP The inode allocation map thinks that inode .I ino is in use whereas examination of the inode indicates that the inode is not in use and therefore is free. The program updates the inode allocation map. .PP .B resetting inode .I ino .B nlinks from .I x .B to .I y .IP The program detected a mismatch between the number of valid directory entries referencing inode .I ino and the number of references recorded in the inode and corrected the the number in the inode. .PP .I fork-type .B fork in ino .I ino .B claims used block .I bno .IP Inode .I ino claims a block .I bno that is used (claimed) by either another inode or the filesystem itself for metadata storage. The .I fork-type is either .B data or .B attr indicating whether the problem lies in the portion of the inode that tracks regular data or the portion of the inode that stores XFS attributes. If the inode is a real-time (rt) inode, the message says so. Any inode that claims blocks used by the filesystem is deleted. If two or more inodes claim the same block, they are both deleted. .PP .I fork-type .B fork in ino .I ino .B claims dup extent ... .IP Inode .I ino claims a block in an extent known to be claimed more than once. The offset in the inode, start and length of the extent is given. The message is slightly different if the inode is a real-time (rt) inode and the extent is therefore a real-time (rt) extent. .PP .B inode .I ino .B \- bad extent ... .IP An extent record in the blockmap of inode .I ino claims blocks that are out of the legal range of the filesystem. The message supplies the start, end, and file offset of the extent. The message is slightly different if the extent is a real-time (rt) extent. .PP .B bad .I fork-type .B fork in inode .I ino .IP There was something structurally wrong or inconsistent with the data structures that map offsets to filesystem blocks. .PP .B cleared inode .I ino .IP There was something wrong with the inode that was uncorrectable so the program freed the inode. This usually happens because the inode claims blocks that are used by something else or the inode itself is badly corrupted. Typically, this message is preceded by one or more messages indicating why the inode needed to be cleared. .PP .B bad attribute fork in inode .IR ino , .B clearing attr fork .IP There was something wrong with the portion of the inode that stores XFS attributes (the attribute fork) so the program reset the attribute fork. As a result of this, all attributes on that inode are lost. .PP .B correcting nextents for inode .IR ino , .B was .I x .B \- counted .I y .IP The program found that the number of extents used to store the data in the inode is wrong and corrected the number. The message refers to nextents if the count is wrong on the number of extents used to store attribute information. .PP .B entry .I name .B in dir .I dir_ino .B not consistent with .. value .BI ( xxxx ) .B in dir ino .IB ino , .B junking entry .I name .B in directory inode .I dir_ino .IP The entry .I name in directory inode .I dir_ino references a directory inode .IR ino . However, the ..\& entry in directory .I ino does not point back to directory .IR dir_ino , so the program deletes the entry .I name in directory inode .IR dir_ino . If the directory inode .I ino winds up becoming a disconnected inode as a result of this, it is moved to .I lost+found later. .PP .B entry .I name .B in dir .I dir_ino .B references already connected dir ino .IB ino , .B junking entry .I name .B in directory inode .I dir_ino .IP The entry .I name in directory inode .I dir_ino points to a directory inode .I ino that is known to be a child of another directory. Therefore, the entry is invalid and is deleted. This message refers to an entry in a small directory. If this were a large directory, the last phrase would read "will clear entry". .PP .B entry references free inode .I ino .B in directory .IB dir_ino , .B will clear entry .IP An entry in directory inode .I dir_ino references an inode .I ino that is known to be free. The entry is therefore invalid and is deleted. This message refers to a large directory. If the directory were small, the message would read "junking entry ...". .SH EXIT STATUS .B xfs_repair \-n (no modify node) will return a status of 1 if filesystem corruption was detected and 0 if no filesystem corruption was detected. .B xfs_repair run without the \-n option will always return a status code of 0. .SH BUGS The filesystem to be checked and repaired must have been unmounted cleanly using normal system administration procedures (the .BR umount (8) command or system shutdown), not as a result of a crash or system reset. If the filesystem has not been unmounted cleanly, mount it and unmount it cleanly before running .BR xfs_repair . .PP .B xfs_repair does not do a thorough job on XFS extended attributes. The structure of the attribute fork will be consistent, but only the contents of attribute forks that will fit into an inode are checked. This limitation will be fixed in the future. .PP The no-modify mode .RB ( \-n option) is not completely accurate. It does not catch inconsistencies in the freespace and inode maps, particularly lost blocks or subtly corrupted maps (trees). .PP The no-modify mode can generate repeated warnings about the same problems because it cannot fix the problems as they are encountered. .PP If a filesystem fails to be repaired, a metadump image can be generated with .BR xfs_metadump (8) and be sent to an XFS maintainer to be analysed and .B xfs_repair fixed and/or improved. .SH SEE ALSO .BR dd (1), .BR mkfs.xfs (8), .BR umount (8), .BR xfs_admin (8), .BR xfs_check (8), .BR xfs_metadump (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_copy.80000664000000000000000000001041111140033220015134 0ustar .TH xfs_copy 8 .SH NAME xfs_copy \- copy the contents of an XFS filesystem .SH SYNOPSIS .B xfs_copy [ .B \-bd ] [ .B \-L .I log ] .I source target1 [ .I target2 \&... ] .SH DESCRIPTION .B xfs_copy copies an XFS filesystem to one or more targets in parallel (see .BR xfs (5)). The first .RI ( source ) argument must be the pathname of the device or file containing the XFS filesystem. The remaining arguments specify one or more .I target devices or file names. If the pathnames specify devices, a copy of the source XFS filesystem is created on each device. The .I target can also be the name of a regular file, in which case an image of the source XFS filesystem is created in that file. If the file does not exist, .B xfs_copy creates the file. The length of the resulting file is equal to the size of the source filesystem. However, if the file is created on an XFS filesystem, the file consumes roughly the amount of space actually used in the source filesystem by the filesystem and the XFS log. The space saving is because .B xfs_copy seeks over free blocks instead of copying them and the XFS filesystem supports sparse files efficiently. .PP .B xfs_copy should only be used to copy unmounted filesystems, read-only mounted filesystems, or frozen filesystems (see .BR xfs_freeze (8)). Otherwise, the generated filesystem(s) would be inconsistent or corrupt. .PP .B xfs_copy does not alter the source filesystem in any way. Each new (target) filesystem is identical to the original filesystem except that new filesystems each have a new unique filesystem identifier (UUID). Therefore, if both the old and new filesystems will be used as separate distinct filesystems, .B xfs_copy or .BR xfsdump (8)/ xfsrestore (8) should be used to generate the new filesystem(s) instead of .BR dd (1) or other programs that do block-by-block disk copying. .PP .B xfs_copy uses synchronous writes to ensure that write errors are detected. .PP .B xfs_copy uses .BR pthreads (7) to perform simultaneous parallel writes. .B xfs_copy creates one additional thread for each target to be written. All threads die if .B xfs_copy terminates or aborts. .SH OPTIONS .TP .B \-d Create a duplicate (true clone) filesystem. This should be done only if the new filesystem will be used as a replacement for the original filesystem (such as in the case of disk replacement). .TP .B \-b The buffered option can be used to ensure direct IO is not attempted to any of the target files. This is useful when the filesystem holding the target file does not support direct IO. .TP .BI \-L " log" Specifies the location of the .I log if the default location of .I /var/tmp/xfs_copy.log.XXXXXX is not desired. .SH DIAGNOSTICS .B xfs_copy reports errors to both .B stderr and in more detailed form to a generated log file whose name is of the form .I /var/tmp/xfs_copy.log.XXXXXX or a log file specified by the .B \-L option. If .B xfs_copy detects a write error on a target, the copy of that one target is aborted and an error message is issued to both stderr and the log file, but the rest of the copies continue. When .B xfs_copy terminates, all aborted targets are reported to both .B stderr and the log file. .PP If all targets abort or if there is an error reading the source filesystem, .B xfs_copy immediately aborts. .PP .B xfs_copy returns an exit code of 0 if all targets are successfully copied and an exit code of 1 if any target fails. .SH NOTES When moving filesystems from one disk to another, if the original filesystem is significantly smaller than the new filesystem, and will be made larger, we recommend that .BR mkfs.xfs "(8) and " xfsdump (8)/ xfsrestore (8) be used instead of using .B xfs_copy and .BR xfs_growfs (8). The filesystem layout resulting from using .BR xfs_copy / xfs_growfs is almost always worse than the result of using .BR mkfs.xfs / xfsdump / xfsrestore but in the case of small filesystems, the differences can have a significant performance impact. This is due to the way .BR xfs_growfs (8) works, and not due to any shortcoming in .B xfs_copy itself. .SH CAVEATS .B xfs_copy does not copy XFS filesystems that have a real-time section or XFS filesystems with external logs. In both cases, .B xfs_copy aborts with an error message. .SH SEE ALSO .BR mkfs.xfs (8), .BR xfsdump (8), .BR xfsrestore (8), .BR xfs_freeze (8), .BR xfs_growfs (8), .BR xfs (5). xfsprogs-3.1.9ubuntu2/man/man8/xfs_growfs.80000664000000000000000000001140211650373061015512 0ustar .\" Verbatim blocks taken from openssl req manpage content .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .TH xfs_growfs 8 .SH NAME xfs_growfs, xfs_info \- expand an XFS filesystem .SH SYNOPSIS .B xfs_growfs [ .B \-dilnrxV ] [ .B \-D .I size ] [ .B \-e .I rtextsize ] [ .B \-L .I size ] [ .B \-m .I maxpct ] [ .B \-t .I mtab ] [ .B \-R .I size ] .I mount-point .br .B xfs_info [ .B \-t .I mtab ] .I mount-point .SH DESCRIPTION .B xfs_growfs expands an existing XFS filesystem (see .BR xfs (5)). The .I mount-point argument is the pathname of the directory where the filesystem is mounted. The filesystem must be mounted to be grown (see .BR mount (8)). The existing contents of the filesystem are undisturbed, and the added space becomes available for additional file storage. .PP .B xfs_info is equivalent to invoking .B xfs_growfs with the .B \-n option (see discussion below). .SH OPTIONS .TP .BI "\-d | \-D " size Specifies that the data section of the filesystem should be grown. If the .B \-D .I size option is given, the data section is grown to that .IR size , otherwise the data section is grown to the largest size possible with the .B \-d option. The size is expressed in filesystem blocks. .TP .B \-e Allows the real-time extent size to be specified. In .BR mkfs.xfs (8) this is specified with .B \-r extsize=\c .IR nnnn . .TP .B \-i The new log is an internal log (inside the data section). .B [NOTE: This option is not implemented] .TP .BI "\-l | \-L " size Specifies that the log section of the filesystem should be grown, shrunk, or moved. If the .B \-L .I size option is given, the log section is changed to be that .IR size , if possible. The size is expressed in filesystem blocks. The size of an internal log must be smaller than the size of an allocation group (this value is printed at .BR mkfs (8) time). If neither .B \-i nor .B \-x is given with .BR \-l , the log continues to be internal or external as it was before. .B [NOTE: These options are not implemented] .TP .B \-m Specify a new value for the maximum percentage of space in the filesystem that can be allocated as inodes. In .BR mkfs.xfs (8) this is specified with .B -i maxpct=\c .IR nn . .TP .B \-n Specifies that no change to the filesystem is to be made. The filesystem geometry is printed, and argument checking is performed, but no growth occurs. .B See output examples below. .TP .BI "\-r | \-R " size Specifies that the real-time section of the filesystem should be grown. If the .B \-R .I size option is given, the real-time section is grown to that size, otherwise the real-time section is grown to the largest size possible with the .B \-r option. The size is expressed in filesystem blocks. The filesystem does not need to have contained a real-time section before the .B xfs_growfs operation. .TP .B \-t Specifies an alternate mount table file (default is .I /proc/mounts if it exists, else .IR /etc/mtab ). This is used when working with filesystems mounted without writing to .I /etc/mtab file - refer to .BR mount (8) for further details. .TP .B \-V Prints the version number and exits. The .I mount-point argument is not required with .BR \-V . .PP .B xfs_growfs is most often used in conjunction with logical volumes (see .BR md (4) and .BR lvm (8) on Linux). However, it can also be used on a regular disk partition, for example if a partition has been enlarged while retaining the same starting block. .SH PRACTICAL USE Filesystems normally occupy all of the space on the device where they reside. In order to grow a filesystem, it is necessary to provide added space for it to occupy. Therefore there must be at least one spare new disk partition available. Adding the space is often done through the use of a logical volume manager. .SH "EXAMPLES" Understanding xfs_info output. .PP Suppose one has the following "xfs_info /dev/sda" output: .PP .RS 2 .Vb \&meta-data=/dev/sda isize=256 agcount=32, agsize=16777184 blks \& = sectsz=512 attr=2 \&data = bsize=4096 blocks=536869888, imaxpct=5 \& = sunit=32 swidth=128 blks \&naming =version 2 bsize=4096 \&log =internal bsize=4096 blocks=32768, version=2 \& = sectsz=512 sunit=32 blks, lazy-count=1 \&realtime =none extsz=524288 blocks=0, rtextents=0 .Ve .RE .PP Here, the data section of the output indicates "bsize=4096", meaning the data block size for this filesystem is 4096 bytes. This section also shows "sunit=32 swidth=128 blks", which means the stripe unit is 32*4096 bytes = 128 kibibytes and the stripe width is 128*4096 bytes = 512 kibibytes. A single stripe of this filesystem therefore consists of four stripe units (128 blocks / 32 blocks per unit). .SH SEE ALSO .BR mkfs.xfs (8), .BR md (4), .BR lvm (8), .BR mount (8). xfsprogs-3.1.9ubuntu2/man/man5/0000775000000000000000000000000012062211564013226 5ustar xfsprogs-3.1.9ubuntu2/man/man5/Makefile0000664000000000000000000000060311140033220014650 0ustar # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = ../.. include $(TOPDIR)/include/builddefs MAN_SECTION = 5 MAN_PAGES = $(shell echo *.$(MAN_SECTION)) MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION) LSRCFILES = $(MAN_PAGES) default : $(MAN_PAGES) include $(BUILDRULES) install : default $(INSTALL) -m 755 -d $(MAN_DEST) $(INSTALL_MAN) install-dev : xfsprogs-3.1.9ubuntu2/man/man5/xfs.50000664000000000000000000000730311140033220014102 0ustar .TH xfs 5 .SH NAME xfs \- layout of the XFS filesystem .SH DESCRIPTION An XFS filesystem can reside on a regular disk partition or on a logical volume. An XFS filesystem has up to three parts: a data section, a log section, and a realtime section. Using the default .BR mkfs.xfs (8) options, the realtime section is absent, and the log area is contained within the data section. The log section can be either separate from the data section or contained within it. The filesystem sections are divided into a certain number of .IR blocks , whose size is specified at .BR mkfs.xfs (8) time with the .B \-b option. .PP The data section contains all the filesystem metadata (inodes, directories, indirect blocks) as well as the user file data for ordinary (non-realtime) files and the log area if the log is .I internal to the data section. The data section is divided into a number of .IR "allocation groups" . The number and size of the allocation groups are chosen by .BR mkfs.xfs (8) so that there is normally a small number of equal-sized groups. The number of allocation groups controls the amount of parallelism available in file and block allocation. It should be increased from the default if there is sufficient memory and a lot of allocation activity. The number of allocation groups should not be set very high, since this can cause large amounts of CPU time to be used by the filesystem, especially when the filesystem is nearly full. More allocation groups are added (of the original size) when .BR xfs_growfs (8) is run. .PP The log section (or area, if it is internal to the data section) is used to store changes to filesystem metadata while the filesystem is running until those changes are made to the data section. It is written sequentially during normal operation and read only during mount. When mounting a filesystem after a crash, the log is read to complete operations that were in progress at the time of the crash. .PP The realtime section is used to store the data of realtime files. These files had an attribute bit set through .BR xfsctl (3) after file creation, before any data was written to the file. The realtime section is divided into a number of .I extents of fixed size (specified at .BR mkfs.xfs (8) time). Each file in the realtime section has an extent size that is a multiple of the realtime section extent size. .PP Each allocation group contains several data structures. The first sector contains the superblock. For allocation groups after the first, the superblock is just a copy and is not updated after .BR mkfs.xfs (8). The next three sectors contain information for block and inode allocation within the allocation group. Also contained within each allocation group are data structures to locate free blocks and inodes; these are located through the header structures. .PP Each XFS filesystem is labeled with a Universal Unique Identifier (UUID). The UUID is stored in every allocation group header and is used to help distinguish one XFS filesystem from another, therefore you should avoid using .BR dd (1) or other block-by-block copying programs to copy XFS filesystems. If two XFS filesystems on the same machine have the same UUID, .BR xfsdump (8) may become confused when doing incremental and resumed dumps. .BR xfsdump (8) and .BR xfsrestore (8) are recommended for making copies of XFS filesystems. .SH OPERATIONS Some functionality specific to the XFS filesystem is accessible to applications through the .BR xfsctl (3) and by-handle (see .BR open_by_handle (3)) interfaces. .SH MOUNT OPTIONS Refer to the .BR mount (8) manual entry for descriptions of the individual XFS mount options. .SH SEE ALSO .BR xfsctl (3), .BR mount (8), .BR mkfs.xfs (8), .BR xfs_info (8), .BR xfs_admin (8), .BR xfsdump (8), .BR xfsrestore (8). xfsprogs-3.1.9ubuntu2/man/man5/projects.50000664000000000000000000000106711175243422015153 0ustar .TH projects 5 .SH NAME projects \- persistent project root defintion .SH DESCRIPTION The .I /etc/projects file provides a mapping between numeric project identifiers and those directories which are the roots of the quota tree. Its format is simply: .nf .sp .in +5 # comments are hash-prefixed # ... 10:/export/cage 42:/var/log .in -5 .fi .PP The .I /etc/projects file is optional, instead .BR xfs_quota (8) can be used with the .B \-p argument to specify a project root directly for each operation. .SH SEE ALSO .BR xfs_quota (8), .BR xfsctl (3), .BR projid (5). xfsprogs-3.1.9ubuntu2/man/man5/projid.50000664000000000000000000000106711175243422014611 0ustar .TH projid 5 .SH NAME projid \- the project name mapping file .SH DESCRIPTION The .I /etc/projid file provides a mapping between numeric project identifiers and a simple human readable name (similar relationship to the one that exists between usernames and uids). Its format is simply: .nf .sp .in +5 # comments are hash-prefixed # ... cage:10 logfiles:42 .in -5 .fi .PP This file is optional, if a project identifier cannot be mapped to a name, it will be parsed and displayed as a numeric value. .SH SEE ALSO .BR xfs_quota (8), .BR xfsctl (3), .BR projects (5). xfsprogs-3.1.9ubuntu2/include/0000775000000000000000000000000012062211563013235 5ustar xfsprogs-3.1.9ubuntu2/include/xfs_alloc_btree.h0000664000000000000000000000705511140033220016534 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_ALLOC_BTREE_H__ #define __XFS_ALLOC_BTREE_H__ /* * Freespace on-disk structures */ struct xfs_buf; struct xfs_btree_cur; struct xfs_mount; /* * There are two on-disk btrees, one sorted by blockno and one sorted * by blockcount and blockno. All blocks look the same to make the code * simpler; if we have time later, we'll make the optimizations. */ #define XFS_ABTB_MAGIC 0x41425442 /* 'ABTB' for bno tree */ #define XFS_ABTC_MAGIC 0x41425443 /* 'ABTC' for cnt tree */ /* * Data record/key structure */ typedef struct xfs_alloc_rec { __be32 ar_startblock; /* starting block number */ __be32 ar_blockcount; /* count of free blocks */ } xfs_alloc_rec_t, xfs_alloc_key_t; typedef struct xfs_alloc_rec_incore { xfs_agblock_t ar_startblock; /* starting block number */ xfs_extlen_t ar_blockcount; /* count of free blocks */ } xfs_alloc_rec_incore_t; /* btree pointer type */ typedef __be32 xfs_alloc_ptr_t; /* * Minimum and maximum blocksize and sectorsize. * The blocksize upper limit is pretty much arbitrary. * The sectorsize upper limit is due to sizeof(sb_sectsize). */ #define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ #define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ #define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) #define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) #define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ #define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ #define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) #define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) /* * Block numbers in the AG: * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3. */ #define XFS_BNO_BLOCK(mp) ((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1)) #define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1)) /* * Btree block header size depends on a superblock flag. * * (not quite yet, but soon) */ #define XFS_ALLOC_BLOCK_LEN(mp) XFS_BTREE_SBLOCK_LEN /* * Record, key, and pointer address macros for btree blocks. * * (note that some of these may appear unused, but they are used in userspace) */ #define XFS_ALLOC_REC_ADDR(mp, block, index) \ ((xfs_alloc_rec_t *) \ ((char *)(block) + \ XFS_ALLOC_BLOCK_LEN(mp) + \ (((index) - 1) * sizeof(xfs_alloc_rec_t)))) #define XFS_ALLOC_KEY_ADDR(mp, block, index) \ ((xfs_alloc_key_t *) \ ((char *)(block) + \ XFS_ALLOC_BLOCK_LEN(mp) + \ ((index) - 1) * sizeof(xfs_alloc_key_t))) #define XFS_ALLOC_PTR_ADDR(mp, block, index, maxrecs) \ ((xfs_alloc_ptr_t *) \ ((char *)(block) + \ XFS_ALLOC_BLOCK_LEN(mp) + \ (maxrecs) * sizeof(xfs_alloc_key_t) + \ ((index) - 1) * sizeof(xfs_alloc_ptr_t))) extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t, xfs_btnum_t); extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int); #endif /* __XFS_ALLOC_BTREE_H__ */ xfsprogs-3.1.9ubuntu2/include/kmem.h0000664000000000000000000000303411140033220014323 0ustar /* * Copyright (c) 2008 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __KMEM_H__ #define __KMEM_H__ #define KM_SLEEP 0x0001u #define KM_NOSLEEP 0x0002u #define KM_NOFS 0x0004u #define KM_MAYFAIL 0x0008u #define KM_LARGE 0x0010u typedef struct kmem_zone { int zone_unitsize; /* Size in bytes of zone unit */ char *zone_name; /* tag name */ int allocated; /* debug: How many currently allocated */ } kmem_zone_t; extern kmem_zone_t *kmem_zone_init(int, char *); extern void *kmem_zone_alloc(kmem_zone_t *, int); extern void *kmem_zone_zalloc(kmem_zone_t *, int); static inline void kmem_zone_free(kmem_zone_t *zone, void *ptr) { zone->allocated--; free(ptr); } extern void *kmem_alloc(size_t, int); extern void *kmem_zalloc(size_t, int); static inline void kmem_free(void *ptr) { free(ptr); } extern void *kmem_realloc(void *, size_t, size_t, int); #endif xfsprogs-3.1.9ubuntu2/include/xfs_trans.h0000664000000000000000000004532211650373061015427 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_TRANS_H__ #define __XFS_TRANS_H__ struct xfs_log_item; /* * This is the structure written in the log at the head of * every transaction. It identifies the type and id of the * transaction, and contains the number of items logged by * the transaction so we know how many to expect during recovery. * * Do not change the below structure without redoing the code in * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). */ typedef struct xfs_trans_header { uint th_magic; /* magic number */ uint th_type; /* transaction type */ __int32_t th_tid; /* transaction id (unused) */ uint th_num_items; /* num items logged by trans */ } xfs_trans_header_t; #define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ /* * Log item types. */ #define XFS_LI_EFI 0x1236 #define XFS_LI_EFD 0x1237 #define XFS_LI_IUNLINK 0x1238 #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ #define XFS_LI_DQUOT 0x123d #define XFS_LI_QUOTAOFF 0x123e #define XFS_LI_TYPE_DESC \ { XFS_LI_EFI, "XFS_LI_EFI" }, \ { XFS_LI_EFD, "XFS_LI_EFD" }, \ { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ { XFS_LI_INODE, "XFS_LI_INODE" }, \ { XFS_LI_BUF, "XFS_LI_BUF" }, \ { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" } /* * Transaction types. Used to distinguish types of buffers. */ #define XFS_TRANS_SETATTR_NOT_SIZE 1 #define XFS_TRANS_SETATTR_SIZE 2 #define XFS_TRANS_INACTIVE 3 #define XFS_TRANS_CREATE 4 #define XFS_TRANS_CREATE_TRUNC 5 #define XFS_TRANS_TRUNCATE_FILE 6 #define XFS_TRANS_REMOVE 7 #define XFS_TRANS_LINK 8 #define XFS_TRANS_RENAME 9 #define XFS_TRANS_MKDIR 10 #define XFS_TRANS_RMDIR 11 #define XFS_TRANS_SYMLINK 12 #define XFS_TRANS_SET_DMATTRS 13 #define XFS_TRANS_GROWFS 14 #define XFS_TRANS_STRAT_WRITE 15 #define XFS_TRANS_DIOSTRAT 16 /* 17 was XFS_TRANS_WRITE_SYNC */ #define XFS_TRANS_WRITEID 18 #define XFS_TRANS_ADDAFORK 19 #define XFS_TRANS_ATTRINVAL 20 #define XFS_TRANS_ATRUNCATE 21 #define XFS_TRANS_ATTR_SET 22 #define XFS_TRANS_ATTR_RM 23 #define XFS_TRANS_ATTR_FLAG 24 #define XFS_TRANS_CLEAR_AGI_BUCKET 25 #define XFS_TRANS_QM_SBCHANGE 26 /* * Dummy entries since we use the transaction type to index into the * trans_type[] in xlog_recover_print_trans_head() */ #define XFS_TRANS_DUMMY1 27 #define XFS_TRANS_DUMMY2 28 #define XFS_TRANS_QM_QUOTAOFF 29 #define XFS_TRANS_QM_DQALLOC 30 #define XFS_TRANS_QM_SETQLIM 31 #define XFS_TRANS_QM_DQCLUSTER 32 #define XFS_TRANS_QM_QINOCREATE 33 #define XFS_TRANS_QM_QUOTAOFF_END 34 #define XFS_TRANS_SB_UNIT 35 #define XFS_TRANS_FSYNC_TS 36 #define XFS_TRANS_GROWFSRT_ALLOC 37 #define XFS_TRANS_GROWFSRT_ZERO 38 #define XFS_TRANS_GROWFSRT_FREE 39 #define XFS_TRANS_SWAPEXT 40 #define XFS_TRANS_SB_COUNT 41 #define XFS_TRANS_CHECKPOINT 42 #define XFS_TRANS_TYPE_MAX 42 /* new transaction types need to be reflected in xfs_logprint(8) */ #define XFS_TRANS_TYPES \ { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ { XFS_TRANS_INACTIVE, "INACTIVE" }, \ { XFS_TRANS_CREATE, "CREATE" }, \ { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ { XFS_TRANS_REMOVE, "REMOVE" }, \ { XFS_TRANS_LINK, "LINK" }, \ { XFS_TRANS_RENAME, "RENAME" }, \ { XFS_TRANS_MKDIR, "MKDIR" }, \ { XFS_TRANS_RMDIR, "RMDIR" }, \ { XFS_TRANS_SYMLINK, "SYMLINK" }, \ { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ { XFS_TRANS_GROWFS, "GROWFS" }, \ { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ { XFS_TRANS_WRITEID, "WRITEID" }, \ { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ { XFS_TRANS_DUMMY1, "DUMMY1" }, \ { XFS_TRANS_DUMMY2, "DUMMY2" }, \ { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } /* * This structure is used to track log items associated with * a transaction. It points to the log item and keeps some * flags to track the state of the log item. It also tracks * the amount of space needed to log the item it describes * once we get to commit processing (see xfs_trans_commit()). */ struct xfs_log_item_desc { struct xfs_log_item *lid_item; ushort lid_size; unsigned char lid_flags; struct list_head lid_trans; }; #define XFS_LID_DIRTY 0x1 #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ /* * Values for t_flags. */ #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ /* * Values for call flags parameter. */ #define XFS_TRANS_RELEASE_LOG_RES 0x4 #define XFS_TRANS_ABORT 0x8 /* * Field values for xfs_trans_mod_sb. */ #define XFS_TRANS_SB_ICOUNT 0x00000001 #define XFS_TRANS_SB_IFREE 0x00000002 #define XFS_TRANS_SB_FDBLOCKS 0x00000004 #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 #define XFS_TRANS_SB_FREXTENTS 0x00000010 #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 #define XFS_TRANS_SB_DBLOCKS 0x00000040 #define XFS_TRANS_SB_AGCOUNT 0x00000080 #define XFS_TRANS_SB_IMAXPCT 0x00000100 #define XFS_TRANS_SB_REXTSIZE 0x00000200 #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 #define XFS_TRANS_SB_RBLOCKS 0x00000800 #define XFS_TRANS_SB_REXTENTS 0x00001000 #define XFS_TRANS_SB_REXTSLOG 0x00002000 /* * Per-extent log reservation for the allocation btree changes * involved in freeing or allocating an extent. * 2 trees * (2 blocks/level * max depth - 1) * block size */ #define XFS_ALLOCFREE_LOG_RES(mp,nx) \ ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) /* * Per-directory log reservation for any directory change. * dir blocks: (1 btree block per level + data block + free block) * dblock size * bmap btree: (levels + 2) * max depth * block size * v2 directory blocks can be fragmented below the dirblksize down to the fsb * size, so account for that in the DAENTER macros. */ #define XFS_DIROP_LOG_RES(mp) \ (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) #define XFS_DIROP_LOG_COUNT(mp) \ (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) /* * Logging the inode timestamps on an fsync -- same as SWRITE * as long as SWRITE logs the entire inode core */ #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) #define XFS_ATTRSET_LOG_RES(mp, ext) \ ((mp)->m_reservations.tr_attrset + \ (ext * (mp)->m_sb.sb_sectsize) + \ (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) /* * Various log count values. */ #define XFS_DEFAULT_LOG_COUNT 1 #define XFS_DEFAULT_PERM_LOG_COUNT 2 #define XFS_ITRUNCATE_LOG_COUNT 2 #define XFS_INACTIVE_LOG_COUNT 2 #define XFS_CREATE_LOG_COUNT 2 #define XFS_MKDIR_LOG_COUNT 3 #define XFS_SYMLINK_LOG_COUNT 3 #define XFS_REMOVE_LOG_COUNT 2 #define XFS_LINK_LOG_COUNT 2 #define XFS_RENAME_LOG_COUNT 2 #define XFS_WRITE_LOG_COUNT 2 #define XFS_ADDAFORK_LOG_COUNT 2 #define XFS_ATTRINVAL_LOG_COUNT 1 #define XFS_ATTRSET_LOG_COUNT 3 #define XFS_ATTRRM_LOG_COUNT 3 /* * Here we centralize the specification of XFS meta-data buffer * reference count values. This determine how hard the buffer * cache tries to hold onto the buffer. */ #define XFS_AGF_REF 4 #define XFS_AGI_REF 4 #define XFS_AGFL_REF 3 #define XFS_INO_BTREE_REF 3 #define XFS_ALLOC_BTREE_REF 2 #define XFS_BMAP_BTREE_REF 2 #define XFS_DIR_BTREE_REF 2 #define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 #define XFS_DQUOT_REF 1 #ifdef __KERNEL__ struct xfs_buf; struct xfs_buftarg; struct xfs_efd_log_item; struct xfs_efi_log_item; struct xfs_inode; struct xfs_item_ops; struct xfs_log_iovec; struct xfs_log_item_desc; struct xfs_mount; struct xfs_trans; struct xfs_dquot_acct; struct xfs_busy_extent; typedef struct xfs_log_item { struct list_head li_ail; /* AIL pointers */ xfs_lsn_t li_lsn; /* last on-disk lsn */ struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ struct xfs_mount *li_mountp; /* ptr to fs mount */ struct xfs_ail *li_ailp; /* ptr to AIL */ uint li_type; /* item type */ uint li_flags; /* misc flags */ struct xfs_log_item *li_bio_list; /* buffer item list */ void (*li_cb)(struct xfs_buf *, struct xfs_log_item *); /* buffer item iodone */ /* callback func */ struct xfs_item_ops *li_ops; /* function list */ /* delayed logging */ struct list_head li_cil; /* CIL pointers */ struct xfs_log_vec *li_lv; /* active log vector */ xfs_lsn_t li_seq; /* CIL commit seq */ } xfs_log_item_t; #define XFS_LI_IN_AIL 0x1 #define XFS_LI_ABORTED 0x2 #define XFS_LI_FLAGS \ { XFS_LI_IN_AIL, "IN_AIL" }, \ { XFS_LI_ABORTED, "ABORTED" } typedef struct xfs_item_ops { uint (*iop_size)(xfs_log_item_t *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); void (*iop_pin)(xfs_log_item_t *); void (*iop_unpin)(xfs_log_item_t *, int remove); uint (*iop_trylock)(xfs_log_item_t *); void (*iop_unlock)(xfs_log_item_t *); xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); void (*iop_push)(xfs_log_item_t *); void (*iop_pushbuf)(xfs_log_item_t *); void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); } xfs_item_ops_t; #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) #define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove) #define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) /* * Return values for the IOP_TRYLOCK() routines. */ #define XFS_ITEM_SUCCESS 0 #define XFS_ITEM_PINNED 1 #define XFS_ITEM_LOCKED 2 #define XFS_ITEM_PUSHBUF 3 /* * This is the type of function which can be given to xfs_trans_callback() * to be called upon the transaction's commit to disk. */ typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); /* * This is the structure maintained for every active transaction. */ typedef struct xfs_trans { unsigned int t_magic; /* magic number */ xfs_log_callback_t t_logcb; /* log callback struct */ unsigned int t_type; /* transaction type */ unsigned int t_log_res; /* amt of log space resvd */ unsigned int t_log_count; /* count for perm log res */ unsigned int t_blk_res; /* # of blocks resvd */ unsigned int t_blk_res_used; /* # of resvd blocks used */ unsigned int t_rtx_res; /* # of rt extents resvd */ unsigned int t_rtx_res_used; /* # of resvd rt extents used */ struct xlog_ticket *t_ticket; /* log mgr ticket */ xfs_lsn_t t_lsn; /* log seq num of start of * transaction. */ xfs_lsn_t t_commit_lsn; /* log seq num of end of * transaction. */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ unsigned int t_flags; /* misc flags */ int64_t t_icount_delta; /* superblock icount change */ int64_t t_ifree_delta; /* superblock ifree change */ int64_t t_fdblocks_delta; /* superblock fdblocks chg */ int64_t t_res_fdblocks_delta; /* on-disk only chg */ int64_t t_frextents_delta;/* superblock freextents chg*/ int64_t t_res_frextents_delta; /* on-disk only chg */ #ifdef DEBUG int64_t t_ag_freeblks_delta; /* debugging counter */ int64_t t_ag_flist_delta; /* debugging counter */ int64_t t_ag_btree_delta; /* debugging counter */ #endif int64_t t_dblocks_delta;/* superblock dblocks change */ int64_t t_agcount_delta;/* superblock agcount change */ int64_t t_imaxpct_delta;/* superblock imaxpct change */ int64_t t_rextsize_delta;/* superblock rextsize chg */ int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ int64_t t_rblocks_delta;/* superblock rblocks change */ int64_t t_rextents_delta;/* superblocks rextents chg */ int64_t t_rextslog_delta;/* superblocks rextslog chg */ struct list_head t_items; /* log item descriptors */ xfs_trans_header_t t_header; /* header for in-log trans */ struct list_head t_busy; /* list of busy extents */ unsigned long t_pflags; /* saved process flags state */ } xfs_trans_t; /* * XFS transaction mechanism exported interfaces that are * actually macros. */ #define xfs_trans_get_log_res(tp) ((tp)->t_log_res) #define xfs_trans_get_log_count(tp) ((tp)->t_log_count) #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) #ifdef DEBUG #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) #else #define xfs_trans_agblocks_delta(tp, d) #define xfs_trans_agflist_delta(tp, d) #define xfs_trans_agbtree_delta(tp, d) #endif /* * XFS transaction mechanism exported interfaces. */ xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint); xfs_trans_t *xfs_trans_dup(xfs_trans_t *); int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, uint, uint); void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, int, uint); int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, int, uint, struct xfs_buf **); struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *, xfs_ino_t , uint, uint, struct xfs_inode **); void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint); void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *); void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); void xfs_efi_release(struct xfs_efi_log_item *, uint); void xfs_trans_log_efi_extent(xfs_trans_t *, struct xfs_efi_log_item *, xfs_fsblock_t, xfs_extlen_t); struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, struct xfs_efi_log_item *, uint); void xfs_trans_log_efd_extent(xfs_trans_t *, struct xfs_efd_log_item *, xfs_fsblock_t, xfs_extlen_t); int _xfs_trans_commit(xfs_trans_t *, uint flags, int *); #define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) void xfs_trans_cancel(xfs_trans_t *, int); int xfs_trans_ail_init(struct xfs_mount *); void xfs_trans_ail_destroy(struct xfs_mount *); extern kmem_zone_t *xfs_trans_zone; extern kmem_zone_t *xfs_log_item_desc_zone; #endif /* __KERNEL__ */ void xfs_trans_init(struct xfs_mount *); int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); #endif /* __XFS_TRANS_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2_block.h0000664000000000000000000000545411140033220016274 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_BLOCK_H__ #define __XFS_DIR2_BLOCK_H__ /* * xfs_dir2_block.h * Directory version 2, single block format structures */ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_dir2_data_hdr; struct xfs_dir2_leaf_entry; struct xfs_inode; struct xfs_mount; struct xfs_trans; /* * The single block format is as follows: * xfs_dir2_data_hdr_t structure * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures * xfs_dir2_leaf_entry_t structures * xfs_dir2_block_tail_t structure */ #define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ typedef struct xfs_dir2_block_tail { __be32 count; /* count of leaf entries */ __be32 stale; /* count of stale lf entries */ } xfs_dir2_block_tail_t; /* * Generic single-block structure, for xfs_db. */ typedef struct xfs_dir2_block { xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_BLOCK_MAGIC */ xfs_dir2_data_union_t u[1]; xfs_dir2_leaf_entry_t leaf[1]; xfs_dir2_block_tail_t tail; } xfs_dir2_block_t; /* * Pointer to the leaf header embedded in a data block (1-block format) */ static inline xfs_dir2_block_tail_t * xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) { return (((xfs_dir2_block_tail_t *) ((char *)(block) + (mp)->m_dirblksize)) - 1); } /* * Pointer to the leaf entries embedded in a data block (1-block format) */ static inline struct xfs_dir2_leaf_entry * xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) { return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count); } /* * Function declarations. */ extern int xfs_dir2_block_addname(struct xfs_da_args *args); extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent, xfs_off_t *offset, filldir_t filldir); extern int xfs_dir2_block_lookup(struct xfs_da_args *args); extern int xfs_dir2_block_removename(struct xfs_da_args *args); extern int xfs_dir2_block_replace(struct xfs_da_args *args); extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, struct xfs_dabuf *lbp, struct xfs_dabuf *dbp); extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); #endif /* __XFS_DIR2_BLOCK_H__ */ xfsprogs-3.1.9ubuntu2/include/list.h0000664000000000000000000000752211650373060014372 0ustar /* * Copyright (c) 2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LIST_H__ #define __LIST_H__ /* * Simple, generic doubly-linked list implementation. */ struct list_head { struct list_head *next; struct list_head *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) #define INIT_LIST_HEAD(list) list_head_init(list) static inline void list_head_init(struct list_head *list) { list->next = list->prev = list; } static inline void list_head_destroy(struct list_head *list) { list->next = list->prev = NULL; } static inline void __list_add(struct list_head *add, struct list_head *prev, struct list_head *next) { next->prev = add; add->next = next; add->prev = prev; prev->next = add; } static inline void list_add(struct list_head *add, struct list_head *head) { __list_add(add, head, head->next); } static inline void list_add_tail(struct list_head *add, struct list_head *head) { __list_add(add, head->prev, head); } static inline void __list_del(struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; } static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); list_head_init(entry); } static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); } static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); } static inline int list_empty(const struct list_head *head) { return head->next == head; } static inline void __list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; struct list_head *last = list->prev; struct list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } static inline void list_splice(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head); } static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head); list_head_init(list); } } #define list_entry(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) #endif /* __LIST_H__ */ xfsprogs-3.1.9ubuntu2/include/Makefile0000664000000000000000000000412511650373060014702 0ustar # # Copyright (c) 2000-2006 Silicon Graphics, Inc. # All Rights Reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # TOPDIR = .. include $(TOPDIR)/include/builddefs QAHFILES = libxfs.h libxlog.h \ atomic.h bitops.h cache.h kmem.h list.h hlist.h parent.h radix-tree.h \ swab.h \ xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h xfs_attr_leaf.h \ xfs_attr_sf.h xfs_bit.h xfs_bmap.h xfs_bmap_btree.h xfs_btree.h \ xfs_btree_trace.h xfs_buf_item.h xfs_da_btree.h xfs_dinode.h \ xfs_dir2.h xfs_dir2_block.h xfs_dir2_data.h xfs_dir2_leaf.h \ xfs_dir2_node.h xfs_dir2_sf.h xfs_dir_leaf.h xfs_dir_sf.h \ xfs_extfree_item.h xfs_ialloc.h xfs_ialloc_btree.h \ xfs_inode.h xfs_inode_item.h xfs_inum.h \ xfs_log.h xfs_log_priv.h xfs_log_recover.h xfs_metadump.h \ xfs_mount.h xfs_quota.h xfs_rtalloc.h xfs_sb.h xfs_trace.h \ xfs_trans.h xfs_trans_space.h xfs_types.h xfs_dfrag.h HFILES = handle.h jdm.h xqm.h xfs.h xfs_fs.h HFILES += $(PKG_PLATFORM).h PHFILES = darwin.h freebsd.h irix.h linux.h gnukfreebsd.h DKHFILES = volume.h fstyp.h dvh.h LSRCFILES = $(shell echo $(PHFILES) | sed -e "s/$(PKG_PLATFORM).h//g") LSRCFILES += platform_defs.h.in builddefs.in buildmacros buildrules install-sh LSRCFILES += $(DKHFILES) command.h input.h path.h project.h LDIRT = xfs disk default install: xfs disk xfs disk: @echo " [LN] $@" $(Q)$(LN_S) . $@ include $(BUILDRULES) install-dev: default $(INSTALL) -m 755 -d $(PKG_INC_DIR) $(INSTALL) -m 644 $(HFILES) $(PKG_INC_DIR) $(INSTALL) -m 644 platform_defs.h $(PKG_INC_DIR) install-qa: install-dev $(INSTALL) -m 644 $(QAHFILES) $(PKG_INC_DIR) xfsprogs-3.1.9ubuntu2/include/xfs_alloc.h0000664000000000000000000001637011650373060015372 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_ALLOC_H__ #define __XFS_ALLOC_H__ struct xfs_buf; struct xfs_mount; struct xfs_perag; struct xfs_trans; struct xfs_busy_extent; /* * Freespace allocation types. Argument to xfs_alloc_[v]extent. */ #define XFS_ALLOCTYPE_ANY_AG 0x01 /* allocate anywhere, use rotor */ #define XFS_ALLOCTYPE_FIRST_AG 0x02 /* ... start at ag 0 */ #define XFS_ALLOCTYPE_START_AG 0x04 /* anywhere, start in this a.g. */ #define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */ #define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */ #define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */ #define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */ /* this should become an enum again when the tracing code is fixed */ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_TYPES \ { XFS_ALLOCTYPE_ANY_AG, "ANY_AG" }, \ { XFS_ALLOCTYPE_FIRST_AG, "FIRST_AG" }, \ { XFS_ALLOCTYPE_START_AG, "START_AG" }, \ { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } /* * Flags for xfs_alloc_fix_freelist. */ #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ /* * In order to avoid ENOSPC-related deadlock caused by * out-of-order locking of AGF buffer (PV 947395), we place * constraints on the relationship among actual allocations for * data blocks, freelist blocks, and potential file data bmap * btree blocks. However, these restrictions may result in no * actual space allocated for a delayed extent, for example, a data * block in a certain AG is allocated but there is no additional * block for the additional bmap btree block due to a split of the * bmap btree of the file. The result of this may lead to an * infinite loop in xfssyncd when the file gets flushed to disk and * all delayed extents need to be actually allocated. To get around * this, we explicitly set aside a few blocks which will not be * reserved in delayed allocation. Considering the minimum number of * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap * btree requires 1 fsb, so we set the number of set-aside blocks * to 4 + 4*agcount. */ #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) /* * Argument structure for xfs_alloc routines. * This is turned into a structure to avoid having 20 arguments passed * down several levels of the stack. */ typedef struct xfs_alloc_arg { struct xfs_trans *tp; /* transaction pointer */ struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ xfs_extlen_t minlen; /* minimum size of extent */ xfs_extlen_t maxlen; /* maximum size of extent */ xfs_extlen_t mod; /* mod value for extent size */ xfs_extlen_t prod; /* prod value for extent size */ xfs_extlen_t minleft; /* min blocks must be left after us */ xfs_extlen_t total; /* total blocks needed in xaction */ xfs_extlen_t alignment; /* align answer to multiple of this */ xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */ xfs_extlen_t len; /* output: actual size of extent */ xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ xfs_alloctype_t otype; /* original allocation type */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; /* * Defines for userdata */ #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ /* * Find the length of the longest extent in an AG. */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag); #ifdef __KERNEL__ void xfs_alloc_busy_insert(xfs_trans_t *tp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len); void xfs_alloc_busy_clear(struct xfs_mount *mp, struct xfs_busy_extent *busyp); #endif /* __KERNEL__ */ /* * Compute and fill in value of m_ag_maxlevels. */ void xfs_alloc_compute_maxlevels( struct xfs_mount *mp); /* file system mount structure */ /* * Get a block from the freelist. * Returns with the buffer for the block gotten. */ int /* error */ xfs_alloc_get_freelist( struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *agbp, /* buffer containing the agf structure */ xfs_agblock_t *bnop, /* block address retrieved from freelist */ int btreeblk); /* destination is a AGF btree */ /* * Log the given fields from the agf structure. */ void xfs_alloc_log_agf( struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *bp, /* buffer for a.g. freelist header */ int fields);/* mask of fields to be logged (XFS_AGF_...) */ /* * Interface for inode allocation to force the pag data to be initialized. */ int /* error */ xfs_alloc_pagf_init( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags); /* XFS_ALLOC_FLAGS_... */ /* * Put the block on the freelist for the allocation group. */ int /* error */ xfs_alloc_put_freelist( struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *agbp, /* buffer for a.g. freelist header */ struct xfs_buf *agflbp,/* buffer for a.g. free block array */ xfs_agblock_t bno, /* block being freed */ int btreeblk); /* owner was a AGF btree */ /* * Read in the allocation group header (free/alloc section). */ int /* error */ xfs_alloc_read_agf( struct xfs_mount *mp, /* mount point structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ int flags, /* XFS_ALLOC_FLAG_... */ struct xfs_buf **bpp); /* buffer for the ag freelist header */ /* * Allocate an extent (variable-size). */ int /* error */ xfs_alloc_vextent( xfs_alloc_arg_t *args); /* allocation argument structure */ /* * Free an extent. */ int /* error */ xfs_free_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len); /* length of extent */ #endif /* __XFS_ALLOC_H__ */ xfsprogs-3.1.9ubuntu2/include/swab.h0000664000000000000000000001054111140033220014327 0ustar #ifndef SWAB_H #define SWAB_H /* casts are necessary for constants, because we never know how for sure * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. */ #define ___swab16(x) \ ({ \ __u16 __x = (x); \ ((__u16)( \ (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ }) #define ___swab32(x) \ ({ \ __u32 __x = (x); \ ((__u32)( \ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ }) #define ___swab64(x) \ ({ \ __u64 __x = (x); \ ((__u64)( \ (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ }) #define ___constant_swab16(x) \ ((__u16)( \ (((__u16)(x) & (__u16)0x00ffU) << 8) | \ (((__u16)(x) & (__u16)0xff00U) >> 8) )) #define ___constant_swab32(x) \ ((__u32)( \ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) #define ___constant_swab64(x) \ ((__u64)( \ (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) )) /* * provide defaults when no architecture-specific optimization is detected */ #ifndef __arch__swab16 # define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); }) #endif #ifndef __arch__swab32 # define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); }) #endif #ifndef __arch__swab64 # define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); }) #endif #ifndef __arch__swab16p # define __arch__swab16p(x) __arch__swab16(*(x)) #endif #ifndef __arch__swab32p # define __arch__swab32p(x) __arch__swab32(*(x)) #endif #ifndef __arch__swab64p # define __arch__swab64p(x) __arch__swab64(*(x)) #endif #ifndef __arch__swab16s # define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0) #endif #ifndef __arch__swab32s # define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0) #endif #ifndef __arch__swab64s # define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0) #endif /* * Allow constant folding */ # define __swab16(x) \ (__builtin_constant_p((__u16)(x)) ? \ ___swab16((x)) : \ __fswab16((x))) # define __swab32(x) \ (__builtin_constant_p((__u32)(x)) ? \ ___swab32((x)) : \ __fswab32((x))) # define __swab64(x) \ (__builtin_constant_p((__u64)(x)) ? \ ___swab64((x)) : \ __fswab64((x))) static __inline__ __u16 __fswab16(__u16 x) { return (__extension__ __arch__swab16(x)); } static __inline__ __u16 __swab16p(__u16 *x) { return (__extension__ __arch__swab16p(x)); } static __inline__ void __swab16s(__u16 *addr) { (__extension__ ({__arch__swab16s(addr);})); } static __inline__ __u32 __fswab32(__u32 x) { return (__extension__ __arch__swab32(x)); } static __inline__ __u32 __swab32p(__u32 *x) { return (__extension__ __arch__swab32p(x)); } static __inline__ void __swab32s(__u32 *addr) { (__extension__ ({__arch__swab32s(addr);})); } static __inline__ __u64 __fswab64(__u64 x) { # ifdef __SWAB_64_THRU_32__ __u32 h = x >> 32; __u32 l = x & ((1ULL<<32)-1); return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h))); # else return (__extension__ __arch__swab64(x)); # endif } static __inline__ __u64 __swab64p(__u64 *x) { return (__extension__ __arch__swab64p(x)); } static __inline__ void __swab64s(__u64 *addr) { (__extension__ ({__arch__swab64s(addr);})); } #endif /* SWAB_H */ xfsprogs-3.1.9ubuntu2/include/xfs_buf_item.h0000664000000000000000000001007411650373060016065 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BUF_ITEM_H__ #define __XFS_BUF_ITEM_H__ extern kmem_zone_t *xfs_buf_item_zone; /* * This is the structure used to lay out a buf log item in the * log. The data map describes which 128 byte chunks of the buffer * have been logged. * For 6.2 and beyond, this is XFS_LI_BUF. We use this to log everything. */ typedef struct xfs_buf_log_format { unsigned short blf_type; /* buf log item type indicator */ unsigned short blf_size; /* size of this item */ ushort blf_flags; /* misc state */ ushort blf_len; /* number of blocks in this buf */ __int64_t blf_blkno; /* starting blkno of this buf */ unsigned int blf_map_size; /* size of data bitmap in words */ unsigned int blf_data_map[1];/* variable size bitmap of */ /* regions of buffer in this item */ } xfs_buf_log_format_t; /* * This flag indicates that the buffer contains on disk inodes * and requires special recovery handling. */ #define XFS_BLF_INODE_BUF 0x1 /* * This flag indicates that the buffer should not be replayed * during recovery because its blocks are being freed. */ #define XFS_BLF_CANCEL 0x2 /* * This flag indicates that the buffer contains on disk * user or group dquots and may require special recovery handling. */ #define XFS_BLF_UDQUOT_BUF 0x4 #define XFS_BLF_PDQUOT_BUF 0x8 #define XFS_BLF_GDQUOT_BUF 0x10 #define XFS_BLF_CHUNK 128 #define XFS_BLF_SHIFT 7 #define BIT_TO_WORD_SHIFT 5 #define NBWORD (NBBY * sizeof(unsigned int)) /* * buf log item flags */ #define XFS_BLI_HOLD 0x01 #define XFS_BLI_DIRTY 0x02 #define XFS_BLI_STALE 0x04 #define XFS_BLI_LOGGED 0x08 #define XFS_BLI_INODE_ALLOC_BUF 0x10 #define XFS_BLI_STALE_INODE 0x20 #define XFS_BLI_INODE_BUF 0x40 #define XFS_BLI_FLAGS \ { XFS_BLI_HOLD, "HOLD" }, \ { XFS_BLI_DIRTY, "DIRTY" }, \ { XFS_BLI_STALE, "STALE" }, \ { XFS_BLI_LOGGED, "LOGGED" }, \ { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \ { XFS_BLI_STALE_INODE, "STALE_INODE" }, \ { XFS_BLI_INODE_BUF, "INODE_BUF" } #ifdef __KERNEL__ struct xfs_buf; struct xfs_mount; struct xfs_buf_log_item; /* * This is the in core log item structure used to track information * needed to log buffers. It tracks how many times the lock has been * locked, and which 128 byte chunks of the buffer are dirty. */ typedef struct xfs_buf_log_item { xfs_log_item_t bli_item; /* common item structure */ struct xfs_buf *bli_buf; /* real buffer pointer */ unsigned int bli_flags; /* misc flags */ unsigned int bli_recur; /* lock recursion count */ atomic_t bli_refcount; /* cnt of tp refs */ #ifdef XFS_TRANS_DEBUG char *bli_orig; /* original buffer copy */ char *bli_logged; /* bytes logged (bitmap) */ #endif xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); void xfs_buf_item_relse(struct xfs_buf *); void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); uint xfs_buf_item_dirty(xfs_buf_log_item_t *); void xfs_buf_attach_iodone(struct xfs_buf *, void(*)(struct xfs_buf *, xfs_log_item_t *), xfs_log_item_t *); void xfs_buf_iodone_callbacks(struct xfs_buf *); void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); #ifdef XFS_TRANS_DEBUG void xfs_buf_item_flush_log_debug( struct xfs_buf *bp, uint first, uint last); #else #define xfs_buf_item_flush_log_debug(bp, first, last) #endif #endif /* __KERNEL__ */ #endif /* __XFS_BUF_ITEM_H__ */ xfsprogs-3.1.9ubuntu2/include/project.h0000664000000000000000000000317611140033220015047 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __PROJECT_H__ #define __PROJECT_H__ #include #if !defined(__sgi__) typedef __uint32_t prid_t; #endif extern int setprojid(const char *__name, int __fd, prid_t __id); extern int getprojid(const char *__name, int __fd, prid_t *__id); typedef struct fs_project { prid_t pr_prid; /* project identifier */ char *pr_name; /* project name */ } fs_project_t; extern void setprent(void); extern void endprent(void); extern fs_project_t *getprent(void); extern fs_project_t *getprnam(char *__name); extern fs_project_t *getprprid(prid_t __id); typedef struct fs_project_path { prid_t pp_prid; /* project identifier */ char *pp_pathname; /* pathname to root of project tree */ } fs_project_path_t; extern void setprpathent(void); extern void endprpathent(void); extern fs_project_path_t *getprpathent(void); extern void setprfiles(void); extern char *projid_file; extern char *projects_file; #endif /* __PROJECT_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_bit.h0000664000000000000000000000421411650373060015050 0ustar /* * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BIT_H__ #define __XFS_BIT_H__ /* * XFS bit manipulation routines. */ /* * masks with n high/low bits set, 64-bit values */ static inline __uint64_t xfs_mask64hi(int n) { return (__uint64_t)-1 << (64 - (n)); } static inline __uint32_t xfs_mask32lo(int n) { return ((__uint32_t)1 << (n)) - 1; } static inline __uint64_t xfs_mask64lo(int n) { return ((__uint64_t)1 << (n)) - 1; } /* Get high bit set out of 32-bit argument, -1 if none set */ static inline int xfs_highbit32(__uint32_t v) { return fls(v) - 1; } /* Get high bit set out of 64-bit argument, -1 if none set */ static inline int xfs_highbit64(__uint64_t v) { return fls64(v) - 1; } /* Get low bit set out of 32-bit argument, -1 if none set */ static inline int xfs_lowbit32(__uint32_t v) { return ffs(v) - 1; } /* Get low bit set out of 64-bit argument, -1 if none set */ static inline int xfs_lowbit64(__uint64_t v) { __uint32_t w = (__uint32_t)v; int n = 0; if (w) { /* lower bits */ n = ffs(w); } else { /* upper bits */ w = (__uint32_t)(v >> 32); if (w && (n = ffs(w))) n += 32; } return n - 1; } /* Return whether bitmap is empty (1 == empty) */ extern int xfs_bitmap_empty(uint *map, uint size); /* Count continuous one bits in map starting with start_bit */ extern int xfs_contig_bits(uint *map, uint size, uint start_bit); /* Find next set bit in map */ extern int xfs_next_bit(uint *map, uint size, uint start_bit); #endif /* __XFS_BIT_H__ */ xfsprogs-3.1.9ubuntu2/include/dvh.h0000664000000000000000000001711111140033220014154 0ustar /* * Copyright (c) 2000-2001, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DVH_H__ #define __DVH_H__ /* * Format for volume header information * * The volume header is a block located at the beginning of all disk * media (sector 0). It contains information pertaining to physical * device parameters and logical partition information. * * The volume header is manipulated by disk formatters/verifiers, * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers. * * Previous versions of IRIX wrote a copy of the volume header is * located at sector 0 of each track of cylinder 0. These copies were * never used, and reduced the capacity of the volume header to hold large * files, so this practice was discontinued. * The volume header is constrained to be less than or equal to 512 * bytes long. A particular copy is assumed valid if no drive errors * are detected, the magic number is correct, and the 32 bit 2's complement * of the volume header is correct. The checksum is calculated by initially * zeroing vh_csum, summing the entire structure and then storing the * 2's complement of the sum. Thus a checksum to verify the volume header * should be 0. * * The error summary table, bad sector replacement table, and boot blocks are * located by searching the volume directory within the volume header. * * Tables are sized simply by the integral number of table records that * will fit in the space indicated by the directory entry. * * The amount of space allocated to the volume header, replacement blocks, * and other tables is user defined when the device is formatted. */ /* * device parameters are in the volume header to determine mapping * from logical block numbers to physical device addresses * * Linux doesn't care ... */ struct device_parameters { unsigned char dp_skew; /* spiral addressing skew */ unsigned char dp_gap1; /* words of 0 before header */ unsigned char dp_gap2; /* words of 0 between hdr and data */ unsigned char dp_spares_cyl; /* This is for drives (such as SCSI that support zone oriented sparing, where the zone is larger than one track. It gets subracteded from the cylinder size ( dp_trks0 * dp_sec) when doing partition size calculations */ unsigned short dp_cyls; /* number of usable cylinders (i.e., doesn't include cylinders reserved by the drive for badblocks, etc.). For drives with variable geometry, this number may be decreased so that: dp_cyls * ((dp_heads * dp_trks0) - dp_spares_cyl) <= actualcapacity This happens on SCSI drives such as the Wren IV and Toshiba 156 Also see dp_cylshi below */ unsigned short dp_shd0; /* starting head vol 0 */ unsigned short dp_trks0; /* number of tracks / cylinder vol 0*/ unsigned char dp_ctq_depth; /* Depth of CTQ queue */ unsigned char dp_cylshi; /* high byte of 24 bits of cylinder count */ unsigned short dp_unused; /* not used */ unsigned short dp_secs; /* number of sectors/track */ unsigned short dp_secbytes; /* length of sector in bytes */ unsigned short dp_interleave; /* sector interleave */ int dp_flags; /* controller characteristics */ int dp_datarate; /* bytes/sec for kernel stats */ int dp_nretries; /* max num retries on data error */ int dp_mspw; /* ms per word to xfer, for iostat */ unsigned short dp_xgap1; /* Gap 1 for xylogics controllers */ unsigned short dp_xsync; /* sync delay for xylogics controllers */ unsigned short dp_xrdly; /* read delay for xylogics controllers */ unsigned short dp_xgap2; /* gap 2 for xylogics controllers */ unsigned short dp_xrgate; /* read gate for xylogics controllers */ unsigned short dp_xwcont; /* write continuation for xylogics */ }; /* * Device characterization flags * (dp_flags) */ #define DP_SECTSLIP 0x00000001 /* sector slip to spare sector */ #define DP_SECTFWD 0x00000002 /* forward to replacement sector */ #define DP_TRKFWD 0x00000004 /* forward to replacement track */ #define DP_MULTIVOL 0x00000008 /* multiple volumes per spindle */ #define DP_IGNOREERRORS 0x00000010 /* transfer data regardless of errors */ #define DP_RESEEK 0x00000020 /* recalibrate as last resort */ #define DP_CTQ_EN 0x00000040 /* enable command tag queueing */ /* * Boot blocks, bad sector tables, and the error summary table, are located * via the volume_directory. */ #define VDNAMESIZE 8 struct volume_directory { char vd_name[VDNAMESIZE]; /* name */ int vd_lbn; /* logical block number */ int vd_nbytes; /* file length in bytes */ }; /* * partition table describes logical device partitions * (device drivers examine this to determine mapping from logical units * to cylinder groups, device formatters/verifiers examine this to determine * location of replacement tracks/sectors, etc) * * NOTE: pt_firstlbn SHOULD BE CYLINDER ALIGNED */ struct partition_table { /* one per logical partition */ int pt_nblks; /* # of logical blks in partition */ int pt_firstlbn; /* first lbn of partition */ int pt_type; /* use of partition */ }; #define PTYPE_VOLHDR 0 /* partition is volume header */ #define PTYPE_TRKREPL 1 /* partition is used for repl trks */ #define PTYPE_SECREPL 2 /* partition is used for repl secs */ #define PTYPE_RAW 3 /* partition is used for data */ #define PTYPE_BSD42 4 /* partition is 4.2BSD file system */ #define PTYPE_BSD 4 /* partition is 4.2BSD file system */ #define PTYPE_SYSV 5 /* partition is SysV file system */ #define PTYPE_VOLUME 6 /* partition is entire volume */ #define PTYPE_EFS 7 /* partition is sgi EFS */ #define PTYPE_LVOL 8 /* partition is part of a logical vol */ #define PTYPE_RLVOL 9 /* part of a "raw" logical vol */ #define PTYPE_XFS 10 /* partition is sgi XFS */ #define PTYPE_XFSLOG 11 /* partition is sgi XFS log */ #define PTYPE_XLV 12 /* partition is part of an XLV vol */ #define PTYPE_XVM 13 /* partition is sgi XVM */ #define NPTYPES 16 #define VHMAGIC 0xbe5a941 /* randomly chosen value */ #define NPARTAB 16 /* 16 unix partitions */ #define NVDIR 15 /* max of 15 directory entries */ #define BFNAMESIZE 16 /* max 16 chars in boot file name */ /* Partition types for ARCS */ #define NOT_USED 0 /* Not used */ #define FAT_SHORT 1 /* FAT filesystem, 12-bit FAT entries */ #define FAT_LONG 4 /* FAT filesystem, 16-bit FAT entries */ #define EXTENDED 5 /* extended partition */ #define HUGE 6 /* huge partition- MS/DOS 4.0 and later */ /* Active flags for ARCS */ #define BOOTABLE 0x00; #define NOT_BOOTABLE 0x80; struct volume_header { int vh_magic; /* identifies volume header */ short vh_rootpt; /* root partition number */ short vh_swappt; /* swap partition number */ char vh_bootfile[BFNAMESIZE]; /* name of file to boot */ struct device_parameters vh_dp; /* device parameters */ struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */ struct partition_table vh_pt[NPARTAB]; /* device partition layout */ int vh_csum; /* volume header checksum */ int vh_fill; /* fill out to 512 bytes */ }; #endif /* __DVH_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_log_priv.h0000664000000000000000000006151611650373061016124 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_LOG_PRIV_H__ #define __XFS_LOG_PRIV_H__ struct xfs_buf; struct log; struct xlog_ticket; struct xfs_mount; /* * Macros, structures, prototypes for internal log manager use. */ #define XLOG_MIN_ICLOGS 2 #define XLOG_MAX_ICLOGS 8 #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ #define XLOG_VERSION_1 1 #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ #define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) #define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */ #define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ #define XLOG_MAX_RECORD_BSIZE (256*1024) #define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ #define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ #define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ #define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ #define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ (log)->l_mp->m_sb.sb_logsunit) #define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit) #define XLOG_HEADER_SIZE 512 #define XLOG_REC_SHIFT(log) \ BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) #define XLOG_TOTAL_REC_SHIFT(log) \ BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) { return ((xfs_lsn_t)cycle << 32) | block; } static inline uint xlog_get_cycle(char *ptr) { if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) return be32_to_cpu(*((__be32 *)ptr + 1)); else return be32_to_cpu(*(__be32 *)ptr); } #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) #ifdef __KERNEL__ /* * get client id from packed copy. * * this hack is here because the xlog_pack code copies four bytes * of xlog_op_header containing the fields oh_clientid, oh_flags * and oh_res2 into the packed copy. * * later on this four byte chunk is treated as an int and the * client id is pulled out. * * this has endian issues, of course. */ static inline uint xlog_get_client_id(__be32 i) { return be32_to_cpu(i) >> 24; } #define xlog_panic(args...) cmn_err(CE_PANIC, ## args) #define xlog_exit(args...) cmn_err(CE_PANIC, ## args) #define xlog_warn(args...) cmn_err(CE_WARN, ## args) /* * In core log state */ #define XLOG_STATE_ACTIVE 0x0001 /* Current IC log being written to */ #define XLOG_STATE_WANT_SYNC 0x0002 /* Want to sync this iclog; no more writes */ #define XLOG_STATE_SYNCING 0x0004 /* This IC log is syncing */ #define XLOG_STATE_DONE_SYNC 0x0008 /* Done syncing to disk */ #define XLOG_STATE_DO_CALLBACK \ 0x0010 /* Process callback functions */ #define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */ #define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/ #define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */ #define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */ #define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */ #endif /* __KERNEL__ */ /* * Flags to log operation header * * The first write of a new transaction will be preceded with a start * record, XLOG_START_TRANS. Once a transaction is committed, a commit * record is written, XLOG_COMMIT_TRANS. If a single region can not fit into * the remainder of the current active in-core log, it is split up into * multiple regions. Each partial region will be marked with a * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS. * */ #define XLOG_START_TRANS 0x01 /* Start a new transaction */ #define XLOG_COMMIT_TRANS 0x02 /* Commit this transaction */ #define XLOG_CONTINUE_TRANS 0x04 /* Cont this trans into new region */ #define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ #define XLOG_END_TRANS 0x10 /* End a continued transaction */ #define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ #ifdef __KERNEL__ /* * Flags to log ticket */ #define XLOG_TIC_INITED 0x1 /* has been initialized */ #define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */ #define XLOG_TIC_FLAGS \ { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \ { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" } #endif /* __KERNEL__ */ #define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */ /* * Flags for log structure */ #define XLOG_CHKSUM_MISMATCH 0x1 /* used only during recovery */ #define XLOG_ACTIVE_RECOVERY 0x2 /* in the middle of recovery */ #define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */ #define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being shutdown */ #ifdef __KERNEL__ /* * Below are states for covering allocation transactions. * By covering, we mean changing the h_tail_lsn in the last on-disk * log write such that no allocation transactions will be re-done during * recovery after a system crash. Recovery starts at the last on-disk * log write. * * These states are used to insert dummy log entries to cover * space allocation transactions which can undo non-transactional changes * after a crash. Writes to a file with space * already allocated do not result in any transactions. Allocations * might include space beyond the EOF. So if we just push the EOF a * little, the last transaction for the file could contain the wrong * size. If there is no file system activity, after an allocation * transaction, and the system crashes, the allocation transaction * will get replayed and the file will be truncated. This could * be hours/days/... after the allocation occurred. * * The fix for this is to do two dummy transactions when the * system is idle. We need two dummy transaction because the h_tail_lsn * in the log record header needs to point beyond the last possible * non-dummy transaction. The first dummy changes the h_tail_lsn to * the first transaction before the dummy. The second dummy causes * h_tail_lsn to point to the first dummy. Recovery starts at h_tail_lsn. * * These dummy transactions get committed when everything * is idle (after there has been some activity). * * There are 5 states used to control this. * * IDLE -- no logging has been done on the file system or * we are done covering previous transactions. * NEED -- logging has occurred and we need a dummy transaction * when the log becomes idle. * DONE -- we were in the NEED state and have committed a dummy * transaction. * NEED2 -- we detected that a dummy transaction has gone to the * on disk log with no other transactions. * DONE2 -- we committed a dummy transaction when in the NEED2 state. * * There are two places where we switch states: * * 1.) In xfs_sync, when we detect an idle log and are in NEED or NEED2. * We commit the dummy transaction and switch to DONE or DONE2, * respectively. In all other states, we don't do anything. * * 2.) When we finish writing the on-disk log (xlog_state_clean_log). * * No matter what state we are in, if this isn't the dummy * transaction going out, the next state is NEED. * So, if we aren't in the DONE or DONE2 states, the next state * is NEED. We can't be finishing a write of the dummy record * unless it was committed and the state switched to DONE or DONE2. * * If we are in the DONE state and this was a write of the * dummy transaction, we move to NEED2. * * If we are in the DONE2 state and this was a write of the * dummy transaction, we move to IDLE. * * * Writing only one dummy transaction can get appended to * one file space allocation. When this happens, the log recovery * code replays the space allocation and a file could be truncated. * This is why we have the NEED2 and DONE2 states before going idle. */ #define XLOG_STATE_COVER_IDLE 0 #define XLOG_STATE_COVER_NEED 1 #define XLOG_STATE_COVER_DONE 2 #define XLOG_STATE_COVER_NEED2 3 #define XLOG_STATE_COVER_DONE2 4 #define XLOG_COVER_OPS 5 /* Ticket reservation region accounting */ #define XLOG_TIC_LEN_MAX 15 /* * Reservation region * As would be stored in xfs_log_iovec but without the i_addr which * we don't care about. */ typedef struct xlog_res { uint r_len; /* region length :4 */ uint r_type; /* region's transaction type :4 */ } xlog_res_t; typedef struct xlog_ticket { wait_queue_head_t t_wait; /* ticket wait queue */ struct list_head t_queue; /* reserve/write queue */ xlog_tid_t t_tid; /* transaction identifier : 4 */ atomic_t t_ref; /* ticket reference count : 4 */ int t_curr_res; /* current reservation in bytes : 4 */ int t_unit_res; /* unit reservation in bytes : 4 */ char t_ocnt; /* original count : 1 */ char t_cnt; /* current count : 1 */ char t_clientid; /* who does this belong to; : 1 */ char t_flags; /* properties of reservation : 1 */ uint t_trans_type; /* transaction type : 4 */ /* reservation array fields */ uint t_res_num; /* num in array : 4 */ uint t_res_num_ophdrs; /* num op hdrs : 4 */ uint t_res_arr_sum; /* array sum : 4 */ uint t_res_o_flow; /* sum overflow : 4 */ xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */ } xlog_ticket_t; #endif typedef struct xlog_op_header { __be32 oh_tid; /* transaction id of operation : 4 b */ __be32 oh_len; /* bytes in data region : 4 b */ __u8 oh_clientid; /* who sent me this : 1 b */ __u8 oh_flags; /* : 1 b */ __u16 oh_res2; /* 32 bit align : 2 b */ } xlog_op_header_t; /* valid values for h_fmt */ #define XLOG_FMT_UNKNOWN 0 #define XLOG_FMT_LINUX_LE 1 #define XLOG_FMT_LINUX_BE 2 #define XLOG_FMT_IRIX_BE 3 /* our fmt */ #ifdef XFS_NATIVE_HOST #define XLOG_FMT XLOG_FMT_LINUX_BE #else #define XLOG_FMT XLOG_FMT_LINUX_LE #endif typedef struct xlog_rec_header { __be32 h_magicno; /* log record (LR) identifier : 4 */ __be32 h_cycle; /* write cycle of log : 4 */ __be32 h_version; /* LR version : 4 */ __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */ __be64 h_lsn; /* lsn of this LR : 8 */ __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ __be32 h_chksum; /* may not be used; non-zero if used : 4 */ __be32 h_prev_block; /* block number to previous LR : 4 */ __be32 h_num_logops; /* number of log operations in this LR : 4 */ __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* new fields */ __be32 h_fmt; /* format of log record : 4 */ uuid_t h_fs_uuid; /* uuid of FS : 16 */ __be32 h_size; /* iclog size : 4 */ } xlog_rec_header_t; typedef struct xlog_rec_ext_header { __be32 xh_cycle; /* write cycle of log : 4 */ __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ } xlog_rec_ext_header_t; #ifdef __KERNEL__ /* * Quite misnamed, because this union lays out the actual on-disk log buffer. */ typedef union xlog_in_core2 { xlog_rec_header_t hic_header; xlog_rec_ext_header_t hic_xheader; char hic_sector[XLOG_HEADER_SIZE]; } xlog_in_core_2_t; /* * - A log record header is 512 bytes. There is plenty of room to grow the * xlog_rec_header_t into the reserved space. * - ic_data follows, so a write to disk can start at the beginning of * the iclog. * - ic_forcewait is used to implement synchronous forcing of the iclog to disk. * - ic_next is the pointer to the next iclog in the ring. * - ic_bp is a pointer to the buffer used to write this incore log to disk. * - ic_log is a pointer back to the global log structure. * - ic_callback is a linked list of callback function/argument pairs to be * called after an iclog finishes writing. * - ic_size is the full size of the header plus data. * - ic_offset is the current number of bytes written to in this iclog. * - ic_refcnt is bumped when someone is writing to the log. * - ic_state is the state of the iclog. * * Because of cacheline contention on large machines, we need to separate * various resources onto different cachelines. To start with, make the * structure cacheline aligned. The following fields can be contended on * by independent processes: * * - ic_callback_* * - ic_refcnt * - fields protected by the global l_icloglock * * so we need to ensure that these fields are located in separate cachelines. * We'll put all the read-only and l_icloglock fields in the first cacheline, * and move everything else out to subsequent cachelines. */ typedef struct xlog_in_core { wait_queue_head_t ic_force_wait; wait_queue_head_t ic_write_wait; struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; struct log *ic_log; int ic_size; int ic_offset; int ic_bwritecnt; unsigned short ic_state; char *ic_datap; /* pointer to iclog data */ /* Callback structures need their own cacheline */ spinlock_t ic_callback_lock ____cacheline_aligned_in_smp; xfs_log_callback_t *ic_callback; xfs_log_callback_t **ic_callback_tail; /* reference counts need their own cacheline */ atomic_t ic_refcnt ____cacheline_aligned_in_smp; xlog_in_core_2_t *ic_data; #define ic_header ic_data->hic_header } xlog_in_core_t; /* * The CIL context is used to aggregate per-transaction details as well be * passed to the iclog for checkpoint post-commit processing. After being * passed to the iclog, another context needs to be allocated for tracking the * next set of transactions to be aggregated into a checkpoint. */ struct xfs_cil; struct xfs_cil_ctx { struct xfs_cil *cil; xfs_lsn_t sequence; /* chkpt sequence # */ xfs_lsn_t start_lsn; /* first LSN of chkpt commit */ xfs_lsn_t commit_lsn; /* chkpt commit record lsn */ struct xlog_ticket *ticket; /* chkpt ticket */ int nvecs; /* number of regions */ int space_used; /* aggregate size of regions */ struct list_head busy_extents; /* busy extents in chkpt */ struct xfs_log_vec *lv_chain; /* logvecs being pushed */ xfs_log_callback_t log_cb; /* completion callback hook. */ struct list_head committing; /* ctx committing list */ }; /* * Committed Item List structure * * This structure is used to track log items that have been committed but not * yet written into the log. It is used only when the delayed logging mount * option is enabled. * * This structure tracks the list of committing checkpoint contexts so * we can avoid the problem of having to hold out new transactions during a * flush until we have a the commit record LSN of the checkpoint. We can * traverse the list of committing contexts in xlog_cil_push_lsn() to find a * sequence match and extract the commit LSN directly from there. If the * checkpoint is still in the process of committing, we can block waiting for * the commit LSN to be determined as well. This should make synchronous * operations almost as efficient as the old logging methods. */ struct xfs_cil { struct log *xc_log; struct list_head xc_cil; spinlock_t xc_cil_lock; struct xfs_cil_ctx *xc_ctx; struct rw_semaphore xc_ctx_lock; struct list_head xc_committing; wait_queue_head_t xc_commit_wait; xfs_lsn_t xc_current_sequence; }; /* * The amount of log space we allow the CIL to aggregate is difficult to size. * Whatever we choose, we have to make sure we can get a reservation for the * log space effectively, that it is large enough to capture sufficient * relogging to reduce log buffer IO significantly, but it is not too large for * the log or induces too much latency when writing out through the iclogs. We * track both space consumed and the number of vectors in the checkpoint * context, so we need to decide which to use for limiting. * * Every log buffer we write out during a push needs a header reserved, which * is at least one sector and more for v2 logs. Hence we need a reservation of * at least 512 bytes per 32k of log space just for the LR headers. That means * 16KB of reservation per megabyte of delayed logging space we will consume, * plus various headers. The number of headers will vary based on the num of * io vectors, so limiting on a specific number of vectors is going to result * in transactions of varying size. IOWs, it is more consistent to track and * limit space consumed in the log rather than by the number of objects being * logged in order to prevent checkpoint ticket overruns. * * Further, use of static reservations through the log grant mechanism is * problematic. It introduces a lot of complexity (e.g. reserve grant vs write * grant) and a significant deadlock potential because regranting write space * can block on log pushes. Hence if we have to regrant log space during a log * push, we can deadlock. * * However, we can avoid this by use of a dynamic "reservation stealing" * technique during transaction commit whereby unused reservation space in the * transaction ticket is transferred to the CIL ctx commit ticket to cover the * space needed by the checkpoint transaction. This means that we never need to * specifically reserve space for the CIL checkpoint transaction, nor do we * need to regrant space once the checkpoint completes. This also means the * checkpoint transaction ticket is specific to the checkpoint context, rather * than the CIL itself. * * With dynamic reservations, we can effectively make up arbitrary limits for * the checkpoint size so long as they don't violate any other size rules. * Recovery imposes a rule that no transaction exceed half the log, so we are * limited by that. Furthermore, the log transaction reservation subsystem * tries to keep 25% of the log free, so we need to keep below that limit or we * risk running out of free log space to start any new transactions. * * In order to keep background CIL push efficient, we will set a lower * threshold at which background pushing is attempted without blocking current * transaction commits. A separate, higher bound defines when CIL pushes are * enforced to ensure we stay within our maximum checkpoint size bounds. * threshold, yet give us plenty of space for aggregation on large logs. */ #define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3) #define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4)) /* * The reservation head lsn is not made up of a cycle number and block number. * Instead, it uses a cycle number and byte number. Logs don't expect to * overflow 31 bits worth of byte offset, so using a byte number will mean * that round off problems won't occur when releasing partial reservations. */ typedef struct log { /* The following fields don't need locking */ struct xfs_mount *l_mp; /* mount point */ struct xfs_ail *l_ailp; /* AIL log is working with */ struct xfs_cil *l_cilp; /* CIL log is working with */ struct xfs_buf *l_xbuf; /* extra buffer for log * wrapping */ struct xfs_buftarg *l_targ; /* buftarg of log */ uint l_flags; uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ struct list_head *l_buf_cancel_table; int l_iclog_hsize; /* size of iclog header */ int l_iclog_heads; /* # of iclog header sectors */ uint l_sectBBsize; /* sector size in BBs (2^n) */ int l_iclog_size; /* size of log in bytes */ int l_iclog_size_log; /* log power size of log */ int l_iclog_bufs; /* number of iclog buffers */ xfs_daddr_t l_logBBstart; /* start block of log */ int l_logsize; /* size of log in bytes */ int l_logBBsize; /* size of log in BB chunks */ /* The following block of fields are changed while holding icloglock */ wait_queue_head_t l_flush_wait ____cacheline_aligned_in_smp; /* waiting for iclog flush */ int l_covered_state;/* state of "covering disk * log entries" */ xlog_in_core_t *l_iclog; /* head log queue */ spinlock_t l_icloglock; /* grab to change iclog state */ int l_curr_cycle; /* Cycle number of log writes */ int l_prev_cycle; /* Cycle number before last * block increment */ int l_curr_block; /* current logical log block */ int l_prev_block; /* previous logical log block */ /* * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and * read without needing to hold specific locks. To avoid operations * contending with other hot objects, place each of them on a separate * cacheline. */ /* lsn of last LR on disk */ atomic64_t l_last_sync_lsn ____cacheline_aligned_in_smp; /* lsn of 1st LR with unflushed * buffers */ atomic64_t l_tail_lsn ____cacheline_aligned_in_smp; /* * ticket grant locks, queues and accounting have their own cachlines * as these are quite hot and can be operated on concurrently. */ spinlock_t l_grant_reserve_lock ____cacheline_aligned_in_smp; struct list_head l_reserveq; atomic64_t l_grant_reserve_head; spinlock_t l_grant_write_lock ____cacheline_aligned_in_smp; struct list_head l_writeq; atomic64_t l_grant_write_head; /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG char *l_iclog_bak[XLOG_MAX_ICLOGS]; #endif } xlog_t; #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) /* common routines */ extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); extern int xlog_recover(xlog_t *log); extern int xlog_recover_finish(xlog_t *log); extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); extern kmem_zone_t *xfs_log_ticket_zone; struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, int count, char client, uint xflags, int alloc_flags); static inline void xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes) { *ptr += bytes; *len -= bytes; *off += bytes; } void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket); int xlog_write(struct log *log, struct xfs_log_vec *log_vector, struct xlog_ticket *tic, xfs_lsn_t *start_lsn, xlog_in_core_t **commit_iclog, uint flags); /* * When we crack an atomic LSN, we sample it first so that the value will not * change while we are cracking it into the component values. This means we * will always get consistent component values to work from. This should always * be used to smaple and crack LSNs taht are stored and updated in atomic * variables. */ static inline void xlog_crack_atomic_lsn(atomic64_t *lsn, uint *cycle, uint *block) { xfs_lsn_t val = atomic64_read(lsn); *cycle = CYCLE_LSN(val); *block = BLOCK_LSN(val); } /* * Calculate and assign a value to an atomic LSN variable from component pieces. */ static inline void xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block) { atomic64_set(lsn, xlog_assign_lsn(cycle, block)); } /* * When we crack the grant head, we sample it first so that the value will not * change while we are cracking it into the component values. This means we * will always get consistent component values to work from. */ static inline void xlog_crack_grant_head_val(int64_t val, int *cycle, int *space) { *cycle = val >> 32; *space = val & 0xffffffff; } static inline void xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space) { xlog_crack_grant_head_val(atomic64_read(head), cycle, space); } static inline int64_t xlog_assign_grant_head_val(int cycle, int space) { return ((int64_t)cycle << 32) | space; } static inline void xlog_assign_grant_head(atomic64_t *head, int cycle, int space) { atomic64_set(head, xlog_assign_grant_head_val(cycle, space)); } /* * Committed Item List interfaces */ int xlog_cil_init(struct log *log); void xlog_cil_init_post_recovery(struct log *log); void xlog_cil_destroy(struct log *log); /* * CIL force routines */ xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); static inline void xlog_cil_force(struct log *log) { xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); } /* * Unmount record type is used as a pseudo transaction type for the ticket. * It's value must be outside the range of XFS_TRANS_* values. */ #define XLOG_UNMOUNT_REC_TYPE (-1U) /* * Wrapper function for waiting on a wait queue serialised against wakeups * by a spinlock. This matches the semantics of all the wait queues used in the * log code. */ static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) { DECLARE_WAITQUEUE(wait, current); add_wait_queue_exclusive(wq, &wait); __set_current_state(TASK_UNINTERRUPTIBLE); spin_unlock(lock); schedule(); remove_wait_queue(wq, &wait); } #endif /* __KERNEL__ */ #endif /* __XFS_LOG_PRIV_H__ */ xfsprogs-3.1.9ubuntu2/include/parent.h0000664000000000000000000000173011140033220014664 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __PARENT_H__ #define __PARENT_H__ typedef struct parent { __u64 p_ino; __u32 p_gen; __u16 p_reclen; char p_name[1]; } parent_t; typedef struct parent_cursor { __u32 opaque[4]; /* an opaque cookie */ } parent_cursor_t; #endif xfsprogs-3.1.9ubuntu2/include/xfs_inum.h0000664000000000000000000000531211650373061015243 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_INUM_H__ #define __XFS_INUM_H__ /* * Inode number format: * low inopblog bits - offset in block * next agblklog bits - block number in ag * next agno_log bits - ag number * high agno_log-agblklog-inopblog bits - 0 */ typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */ /* * Useful inode bits for this kernel. * Used in some places where having 64-bits in the 32-bit kernels * costs too much. */ #if XFS_BIG_INUMS typedef xfs_ino_t xfs_intino_t; #else typedef __uint32_t xfs_intino_t; #endif #define NULLFSINO ((xfs_ino_t)-1) #define NULLAGINO ((xfs_agino_t)-1) struct xfs_mount; #define XFS_INO_MASK(k) (__uint32_t)((1ULL << (k)) - 1) #define XFS_INO_OFFSET_BITS(mp) (mp)->m_sb.sb_inopblog #define XFS_INO_AGBNO_BITS(mp) (mp)->m_sb.sb_agblklog #define XFS_INO_AGINO_BITS(mp) (mp)->m_agino_log #define XFS_INO_AGNO_BITS(mp) (mp)->m_agno_log #define XFS_INO_BITS(mp) \ XFS_INO_AGNO_BITS(mp) + XFS_INO_AGINO_BITS(mp) #define XFS_INO_TO_AGNO(mp,i) \ ((xfs_agnumber_t)((i) >> XFS_INO_AGINO_BITS(mp))) #define XFS_INO_TO_AGINO(mp,i) \ ((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(mp))) #define XFS_INO_TO_AGBNO(mp,i) \ (((xfs_agblock_t)(i) >> XFS_INO_OFFSET_BITS(mp)) & \ XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp))) #define XFS_INO_TO_OFFSET(mp,i) \ ((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp))) #define XFS_INO_TO_FSB(mp,i) \ XFS_AGB_TO_FSB(mp, XFS_INO_TO_AGNO(mp,i), XFS_INO_TO_AGBNO(mp,i)) #define XFS_AGINO_TO_INO(mp,a,i) \ (((xfs_ino_t)(a) << XFS_INO_AGINO_BITS(mp)) | (i)) #define XFS_AGINO_TO_AGBNO(mp,i) ((i) >> XFS_INO_OFFSET_BITS(mp)) #define XFS_AGINO_TO_OFFSET(mp,i) \ ((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp))) #define XFS_OFFBNO_TO_AGINO(mp,b,o) \ ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o))) #if XFS_BIG_INUMS #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL)) #else #define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 32) - 1ULL)) #endif #define XFS_MAXINUMBER_32 ((xfs_ino_t)((1ULL << 32) - 1ULL)) #endif /* __XFS_INUM_H__ */ xfsprogs-3.1.9ubuntu2/include/install-sh0000775000000000000000000001546112062210562015246 0ustar #! /bin/bash # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # # This script emulates bsd install and also recognises # two environment variables, with the following semantics :- # # $DIST_MANIFEST - if set, the name of the file to append manifest # information in the following format: # File : f mode owner group src target # Directory: d mode owner group target # Symlink : l linkval target # # $DIST_ROOT - if set, prepend to target # # The sematics of all combinations of these two variables # are as follows: # # $DIST_MANIFEST? $DIST_ROOT? | Copy? Append Manifest? # -----------------------------+-------------------------- # not set not set | yes no # not set set | yes no # set not set | no yes # set set | yes yes # _usage() { echo "Usage: $prog [-o owner] [-g group] [-m mode] -d directory" echo "or $prog [-D] [-o owner] [-g group] [-m mode] file directory/file" echo "or $prog [-o owner] [-g group] [-m mode] file [file ...] directory" echo "or $prog -S file target (creates \"target\" symlink)" echo "or $prog -T lt_arg [-o owner] [-g group] [-m mode] libtool.lai directory" echo "" echo "The \$DIST_MANIFEST and \$DIST_ROOT environment variables affect the" echo "behaviour of this command - see comments in the script." echo "The -D flag is only available for the second usage, and causes" echo "the target directory to be created before installing the file." echo "" exit 1 } _chown () { _st=255 if [ $# -eq 3 ] ; then chown $1:$2 $3 _st=$? if [ $_st -ne 0 ] ; then if [ $REAL_UID != '0' ] ; then if [ ! -f $DIST_ROOT/.chown.quiet ] ; then echo '===============================================' echo Ownership of files under ${DIST_ROOT:-/} echo cannot be changed echo '===============================================' if [ -n "$DIST_ROOT" ] ; then touch $DIST_ROOT/.chown.quiet fi fi _st=0 fi fi fi return $_st } _manifest () { echo $* | sed -e 's/\/\//\//g' >>${DIST_MANIFEST:-/dev/null} } prog=`basename $0` HERE=`pwd` dflag=false Dflag=false Sflag=false Tflag=false DIRMODE=755 FILEMODE=644 OWNER=`id -u` GROUP=`id -g` REAL_UID=$OWNER # default is to install and don't append manifest INSTALL=true MANIFEST=: : ${DIST_ROOT:=${DESTDIR}} [ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false [ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest" [ $# -eq 0 ] && _usage if $INSTALL then CP=cp; LN=ln; MKDIR=mkdir; CHMOD=chmod; CHOWN=_chown else CP=true; LN=true; MKDIR=true; CHMOD=true; CHOWN=true fi [ -n "$DIST_ROOT" -a $REAL_UID -ne 0 ] && CHOWN=true while getopts "Dcm:d:S:o:g:T:" c $* do case $c in c) ;; g) GROUP=$OPTARG ;; o) OWNER=$OPTARG ;; m) DIRMODE=`expr $OPTARG` FILEMODE=$DIRMODE ;; D) Dflag=true ;; S) symlink=$OPTARG Sflag=true ;; d) dir=$DIST_ROOT/$OPTARG dflag=true ;; T) lt_install=$OPTARG Tflag=true ;; *) _usage ;; esac done shift `expr $OPTIND - 1` status=0 if $dflag then # # first usage # $MKDIR -p $dir status=$? if [ $status -eq 0 ] then $CHMOD $DIRMODE $dir status=$? fi if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir status=$? fi $MANIFEST d $DIRMODE $OWNER $GROUP ${dir#$DIST_ROOT} elif $Sflag then # # fourth usage (symlink) # if [ $# -ne 1 ] then _usage else target=$DIST_ROOT/$1 fi $LN -s -f $symlink $target status=$? $MANIFEST l $symlink ${target#$DIST_ROOT} elif $Tflag then # # -T (install libs built by libtool) # if [ $# -ne 2 ] then _usage else libtool_lai=$1 # source the libtool variables if [ ! -f $libtool_lai ] then echo "$prog: Unable to find libtool library file $libtool_lai" exit 2 fi . ./$libtool_lai target=$DIST_ROOT/$2 fi case $lt_install in so_dot_version) # Loop until we find libfoo.so.x.y.z, then break out. for solib in $library_names do # does it have enough parts? libfoo.so.x.y.z == 5 cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w` if [ $cnt -eq 5 ] then install_name=$target/$solib $CP $solib $install_name status=$? $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$solib ${install_name#$DIST_ROOT} break fi done ;; so_*) case $lt_install in so_dot_current) # ln -s libfoo.so.x.y.z to libfoo.so.x from_parts=5 # libfoo.so.x.y.z to_parts=3 # libfoo.so.x ;; so_base) # ln -s libfoo.so.x to libfoo.so from_parts=3 # libfoo.so.x to_parts=2 # libfoo.so ;; *) echo "$prog: -T $lt_install invalid" exit 2 ;; esac # Loop until we find the names, then break out. for solib in $library_names do # does it have enough parts? cnt=`echo "$solib" | sed -e 's/\./ /g' | wc -w` if [ $cnt -eq $from_parts ] then from_name=$solib elif [ $cnt -eq $to_parts ] then to_name=$solib fi if [ -n "$from_name" ] && [ -n "$to_name" ] then install_name=$target/$to_name $LN -s -f $from_name $install_name status=$? $MANIFEST l $from_name ${install_name#$DIST_ROOT} break fi done ;; old_lib) install_name=$target/$old_library $CP $old_library $install_name status=$? $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$old_library ${install_name#$DIST_ROOT} ;; *) echo "$prog: -T $lt_install invalid" exit 2 ;; esac case $lt_install in old_lib|so_dot_version) if [ $status -eq 0 ] then $CHMOD $FILEMODE $install_name $CHOWN $OWNER $GROUP $install_name fi ;; esac else list="" dir="" if [ $# -eq 2 ] then # # second usage # f=$1 dir=$DIST_ROOT/$2 if $Dflag then mkdir -p `dirname $dir` fi $CP $f $dir status=$? if [ $status -eq 0 ] then if [ -f $dir/$f ] then $CHMOD $FILEMODE $dir/$f status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir/$f status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f else $CHMOD $FILEMODE $dir status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$dir ${dir#$DIST_ROOT} fi fi else # # third usage # n=1 while [ $# -gt 0 ] do if [ $# -gt 1 ] then list="$list $1" else dir=$DIST_ROOT/$1 fi shift done # echo DIR=$dir list=\"$list\" for f in $list do $CP $f $dir status=$? if [ $status -eq 0 ] then $CHMOD $FILEMODE $dir/$f status=$? if [ $status -eq 0 ] then $CHOWN $OWNER $GROUP $dir/$f status=$? fi $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f fi [ $status -ne 0 ] && break done fi fi exit $status xfsprogs-3.1.9ubuntu2/include/libxlog.h0000664000000000000000000001103311650373060015047 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc.All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LIBXLOG_H #define LIBXLOG_H #include /* * define the userlevel xlog_t to be the subset of the kernel's * xlog_t that we actually need to get our work done, avoiding * the need to define any exotic kernel types in userland. */ typedef struct log { xfs_lsn_t l_tail_lsn; /* lsn of 1st LR w/ unflush buffers */ xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ xfs_mount_t *l_mp; /* mount point */ dev_t l_dev; /* dev_t of log */ xfs_daddr_t l_logBBstart; /* start block of log */ int l_logsize; /* size of log in bytes */ int l_logBBsize; /* size of log in 512 byte chunks */ int l_curr_cycle; /* Cycle number of log writes */ int l_prev_cycle; /* Cycle # b4 last block increment */ int l_curr_block; /* current logical block of log */ int l_prev_block; /* previous logical block of log */ int l_iclog_size; /* size of log in bytes */ int l_iclog_size_log;/* log power size of log */ int l_iclog_bufs; /* number of iclog buffers */ atomic64_t l_grant_reserve_head; atomic64_t l_grant_write_head; uint l_sectbb_log; /* log2 of sector size in bbs */ uint l_sectbb_mask; /* sector size (in BBs) * alignment mask */ int l_sectBBsize; /* size of log sector in 512 byte chunks */ } xlog_t; #include #include #include #include typedef union { xlog_rec_header_t hic_header; xlog_rec_ext_header_t hic_xheader; char hic_sector[XLOG_HEADER_SIZE]; } xlog_in_core_2_t; /* * macros mapping kernel code to user code */ #ifndef EFSCORRUPTED #define EFSCORRUPTED 990 #endif #define STATIC static #define XFS_ERROR(e) (e) #ifdef DEBUG #define XFS_ERROR_REPORT(e,l,mp) fprintf(stderr, "ERROR: %s\n", e) #else #define XFS_ERROR_REPORT(e,l,mp) ((void) 0) #endif #define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) #define XFS_MOUNT_WAS_CLEAN 0x1 #define unlikely(x) (x) #define min(a,b) ((a) < (b) ? (a) : (b)) extern void xlog_warn(char *fmt,...); extern void xlog_exit(char *fmt,...); extern void xlog_panic(char *fmt,...); /* exports */ extern int print_exit; extern int print_skip_uuid; extern int print_record_header; /* libxfs parameters */ extern libxfs_init_t x; extern struct xfs_buf *xlog_get_bp(xlog_t *, int); extern void xlog_put_bp(struct xfs_buf *); extern int xlog_bread(xlog_t *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp, xfs_caddr_t *offset); extern int xlog_bread_noalign(xlog_t *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp); extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle); extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk); extern int xlog_test_footer(xlog_t *log); extern int xlog_recover(xlog_t *log, int readonly); extern void xlog_recover_print_data(xfs_caddr_t p, int len); extern void xlog_recover_print_logitem(xlog_recover_item_t *item); extern void xlog_recover_print_trans_head(xlog_recover_t *tr); extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); /* for transactional view */ extern void xlog_recover_print_trans_head(xlog_recover_t *tr); extern void xlog_recover_print_trans(xlog_recover_t *trans, struct list_head *itemq, int print); extern int xlog_do_recovery_pass(xlog_t *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass); extern int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *trans, int pass); extern int xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head); extern int xlog_header_check_mount(xfs_mount_t *mp, xlog_rec_header_t *head); #define xlog_assign_atomic_lsn(l,a,b) ((void) 0) #define xlog_assign_grant_head(l,a,b) ((void) 0) #endif /* LIBXLOG_H */ xfsprogs-3.1.9ubuntu2/include/xfs_dir_leaf.h0000664000000000000000000001046511140033220016025 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR_LEAF_H__ #define __XFS_DIR_LEAF_H__ /* * Version 1 Directory layout, internal structure, access macros, etc. * to allow various xfsprogs tools to read these structures. * * Large directories are structured around Btrees where all the data * elements are in the leaf nodes. Filenames are hashed into an int, * then that int is used as the index into the Btree. Since the hashval * of a filename may not be unique, we may have duplicate keys. The * internal links in the Btree are logical block offsets into the file. */ /*======================================================================== * Directory Structure when equal to XFS_LBSIZE(mp) bytes. *========================================================================*/ /* * This is the structure of the leaf nodes in the Btree. * * Struct leaf_entry's are packed from the top. Names grow from the bottom * but are not packed. The freemap contains run-length-encoded entries * for the free bytes after the leaf_entry's, but only the N largest such, * smaller runs are dropped. When the freemap doesn't show enough space * for an allocation, we compact the namelist area and try again. If we * still don't have enough space, then we have to split the block. * * Since we have duplicate hash keys, for each key that matches, compare * the actual string. The root and intermediate node search always takes * the first-in-the-block key match found, so we should only have to work * "forw"ard. If none matches, continue with the "forw"ard leaf nodes * until the hash key changes or the filename is found. * * The parent directory and the self-pointer are explicitly represented * (ie: there are entries for "." and ".."). * * Note that the count being a __uint16_t limits us to something like a * blocksize of 1.3MB in the face of worst case (short) filenames. */ #define XFS_DIR_LEAF_MAGIC 0xfeeb #define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */ typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */ __be16 base; /* base of free region */ __be16 size; /* run length of free region */ } xfs_dir_leaf_map_t; typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ __be16 count; /* count of active leaf_entry's */ __be16 namebytes; /* num bytes of name strings stored */ __be16 firstused; /* first used byte in name area */ __u8 holes; /* != 0 if blk needs compaction */ __u8 pad1; xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; } xfs_dir_leaf_hdr_t; typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */ __be32 hashval; /* hash value of name */ __be16 nameidx; /* index into buffer of name */ __u8 namelen; /* length of name string */ __u8 pad2; } xfs_dir_leaf_entry_t; typedef struct xfs_dir_leaf_name { xfs_dir_ino_t inumber; /* inode number for this key */ __u8 name[1]; /* name string itself */ } xfs_dir_leaf_name_t; typedef struct xfs_dir_leafblock { xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */ xfs_dir_leaf_entry_t entries[1]; /* var sized array */ xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */ } xfs_dir_leafblock_t; static inline int xfs_dir_leaf_entsize_byname(int len) { return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; } static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) { return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; } static inline xfs_dir_leaf_name_t * xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) { return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; } #endif /* __XFS_DIR_LEAF_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_mount.h0000664000000000000000000003642611650373061015447 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_MOUNT_H__ #define __XFS_MOUNT_H__ typedef struct xfs_trans_reservations { uint tr_write; /* extent alloc trans */ uint tr_itruncate; /* truncate trans */ uint tr_rename; /* rename trans */ uint tr_link; /* link trans */ uint tr_remove; /* unlink trans */ uint tr_symlink; /* symlink trans */ uint tr_create; /* create trans */ uint tr_mkdir; /* mkdir trans */ uint tr_ifree; /* inode free trans */ uint tr_ichange; /* inode update trans */ uint tr_growdata; /* fs data section grow trans */ uint tr_swrite; /* sync write inode trans */ uint tr_addafork; /* cvt inode to attributed trans */ uint tr_writeid; /* write setuid/setgid file */ uint tr_attrinval; /* attr fork buffer invalidation */ uint tr_attrset; /* set/create an attribute */ uint tr_attrrm; /* remove an attribute */ uint tr_clearagi; /* clear bad agi unlinked ino bucket */ uint tr_growrtalloc; /* grow realtime allocations */ uint tr_growrtzero; /* grow realtime zeroing */ uint tr_growrtfree; /* grow realtime freeing */ } xfs_trans_reservations_t; #ifndef __KERNEL__ #define xfs_daddr_to_agno(mp,d) \ ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) #define xfs_daddr_to_agbno(mp,d) \ ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) #else /* __KERNEL__ */ #include "xfs_sync.h" struct log; struct xfs_mount_args; struct xfs_inode; struct xfs_bmbt_irec; struct xfs_bmap_free; struct xfs_extdelta; struct xfs_swapext; struct xfs_mru_cache; struct xfs_nameops; struct xfs_ail; struct xfs_quotainfo; #ifdef HAVE_PERCPU_SB /* * Valid per-cpu incore superblock counters. Note that if you add new counters, * you may need to define new counter disabled bit field descriptors as there * are more possible fields in the superblock that can fit in a bitfield on a * 32 bit platform. The XFS_SBS_* values for the current current counters just * fit. */ typedef struct xfs_icsb_cnts { uint64_t icsb_fdblocks; uint64_t icsb_ifree; uint64_t icsb_icount; unsigned long icsb_flags; } xfs_icsb_cnts_t; #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ extern int xfs_icsb_init_counters(struct xfs_mount *); extern void xfs_icsb_reinit_counters(struct xfs_mount *); extern void xfs_icsb_destroy_counters(struct xfs_mount *); extern void xfs_icsb_sync_counters(struct xfs_mount *, int); extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); extern int xfs_icsb_modify_counters(struct xfs_mount *, xfs_sb_field_t, int64_t, int); #else #define xfs_icsb_init_counters(mp) (0) #define xfs_icsb_destroy_counters(mp) do { } while (0) #define xfs_icsb_reinit_counters(mp) do { } while (0) #define xfs_icsb_sync_counters(mp, flags) do { } while (0) #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) #define xfs_icsb_modify_counters(mp, field, delta, rsvd) \ xfs_mod_incore_sb(mp, field, delta, rsvd) #endif /* dynamic preallocation free space thresholds, 5% down to 1% */ enum { XFS_LOWSP_1_PCNT = 0, XFS_LOWSP_2_PCNT, XFS_LOWSP_3_PCNT, XFS_LOWSP_4_PCNT, XFS_LOWSP_5_PCNT, XFS_LOWSP_MAX, }; typedef struct xfs_mount { struct super_block *m_super; xfs_tid_t m_tid; /* next unused tid for fs */ struct xfs_ail *m_ail; /* fs active log item list */ xfs_sb_t m_sb; /* copy of fs superblock */ spinlock_t m_sb_lock; /* sb counter lock */ struct xfs_buf *m_sb_bp; /* buffer for superblock */ char *m_fsname; /* filesystem name */ int m_fsname_len; /* strlen of fs name */ char *m_rtname; /* realtime device name */ char *m_logname; /* external log device name */ int m_bsize; /* fs logical block size */ xfs_agnumber_t m_agfrotor; /* last ag where space found */ xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ spinlock_t m_agirotor_lock;/* .. and lock protecting it */ xfs_agnumber_t m_maxagi; /* highest inode alloc group */ uint m_readio_log; /* min read size log bytes */ uint m_readio_blocks; /* min read size blocks */ uint m_writeio_log; /* min write size log bytes */ uint m_writeio_blocks; /* min write size blocks */ struct log *m_log; /* log specific stuff */ int m_logbufs; /* number of log buffers */ int m_logbsize; /* size of each log buffer */ uint m_rsumlevels; /* rt summary levels */ uint m_rsumsize; /* size of rt summary, bytes */ struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ struct xfs_inode *m_rsumip; /* pointer to summary inode */ struct xfs_inode *m_rootip; /* pointer to root directory */ struct xfs_quotainfo *m_quotainfo; /* disk quota information */ xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ __uint8_t m_blkbit_log; /* blocklog + NBBY */ __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ __uint8_t m_agno_log; /* log #ag's */ __uint8_t m_agino_log; /* #bits for agino in inum */ __uint16_t m_inode_cluster_size;/* min inode buf size */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwmask; /* blockwsize-1 */ uint m_alloc_mxr[2]; /* max alloc btree records */ uint m_alloc_mnr[2]; /* min alloc btree records */ uint m_bmap_dmxr[2]; /* max bmap btree records */ uint m_bmap_dmnr[2]; /* min bmap btree records */ uint m_inobt_mxr[2]; /* max inobt btree records */ uint m_inobt_mnr[2]; /* min inobt btree records */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* max inobt btree levels. */ struct radix_tree_root m_perag_tree; /* per-ag accounting info */ spinlock_t m_perag_lock; /* lock for m_perag_tree */ struct mutex m_growlock; /* growfs mutex */ int m_fixedfsid[2]; /* unchanged for life of FS */ uint m_dmevmask; /* DMI events for this FS */ __uint64_t m_flags; /* global mount flags */ uint m_dir_node_ents; /* #entries in a dir danode */ uint m_attr_node_ents; /* #entries in attr danode */ int m_ialloc_inos; /* inodes in inode allocation */ int m_ialloc_blks; /* blocks in inode allocation */ int m_inoalign_mask;/* mask sb_inoalignmt if used */ uint m_qflags; /* quota status flags */ xfs_trans_reservations_t m_reservations;/* precomputed res values */ __uint64_t m_maxicount; /* maximum inode count */ __uint64_t m_maxioffset; /* maximum inode offset */ __uint64_t m_resblks; /* total reserved blocks */ __uint64_t m_resblks_avail;/* available reserved blocks */ __uint64_t m_resblks_save; /* reserved blks @ remount,ro */ int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ int m_sinoalign; /* stripe unit inode alignment */ int m_attr_magicpct;/* 37% of the blocksize */ int m_dir_magicpct; /* 37% of the dir blocksize */ __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ int m_dirblksize; /* directory block sz--bytes */ int m_dirblkfsbs; /* directory block sz--fsbs */ xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ uint m_chsize; /* size of next field */ struct xfs_chash *m_chash; /* fs private inode per-cluster * hash table */ atomic_t m_active_trans; /* number trans frozen */ #ifdef HAVE_PERCPU_SB xfs_icsb_cnts_t __percpu *m_sb_cnts; /* per-cpu superblock counters */ unsigned long m_icsb_counters; /* disabled per-cpu counters */ struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ struct mutex m_icsb_mutex; /* balancer sync lock */ #endif struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ struct task_struct *m_sync_task; /* generalised sync thread */ xfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ struct list_head m_sync_list; /* sync thread work item list */ spinlock_t m_sync_lock; /* work item list lock */ int m_sync_seq; /* sync thread generation no. */ wait_queue_head_t m_wait_single_sync_task; __int64_t m_update_flags; /* sb flags we need to update on the next remount,rw */ struct shrinker m_inode_shrink; /* inode reclaim shrinker */ int64_t m_low_space[XFS_LOWSP_MAX]; /* low free space thresholds */ } xfs_mount_t; /* * Flags for m_flags. */ #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops must be synchronous except for space allocations */ #define XFS_MOUNT_DELAYLOG (1ULL << 1) /* delayed logging is enabled */ #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem operations, typically for disk errors in metadata */ #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to user */ #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment allocations */ #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above * 32 bits in size */ #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred * I/O size in stat() */ #define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams allocator */ #define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ /* * Default minimum read and write sizes. */ #define XFS_READIO_LOG_LARGE 16 #define XFS_WRITEIO_LOG_LARGE 16 /* * Max and min values for mount-option defined I/O * preallocation sizes. */ #define XFS_MAX_IO_LOG 30 /* 1G */ #define XFS_MIN_IO_LOG PAGE_SHIFT /* * Synchronous read and write sizes. This should be * better for NFSv2 wsync filesystems. */ #define XFS_WSYNC_READIO_LOG 15 /* 32k */ #define XFS_WSYNC_WRITEIO_LOG 14 /* 16k */ /* * Allow large block sizes to be reported to userspace programs if the * "largeio" mount option is used. * * If compatibility mode is specified, simply return the basic unit of caching * so that we don't get inefficient read/modify/write I/O from user apps. * Otherwise.... * * If the underlying volume is a stripe, then return the stripe width in bytes * as the recommended I/O size. It is not a stripe and we've set a default * buffered I/O size, return that, otherwise return the compat default. */ static inline unsigned long xfs_preferred_iosize(xfs_mount_t *mp) { if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE) return PAGE_CACHE_SIZE; return (mp->m_swidth ? (mp->m_swidth << mp->m_sb.sb_blocklog) : ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ? (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) : PAGE_CACHE_SIZE)); } #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, int lnnum); #define xfs_force_shutdown(m,f) \ xfs_do_force_shutdown(m, f, __FILE__, __LINE__) #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ #define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */ #define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */ #define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */ #define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */ #define xfs_test_for_freeze(mp) ((mp)->m_super->s_frozen) #define xfs_wait_for_freeze(mp,l) vfs_check_frozen((mp)->m_super, (l)) /* * Flags for xfs_mountfs */ #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ static inline xfs_agnumber_t xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) { xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); do_div(ld, mp->m_sb.sb_agblocks); return (xfs_agnumber_t) ld; } static inline xfs_agblock_t xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) { xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); } /* * Per-cpu superblock locking functions */ #ifdef HAVE_PERCPU_SB static inline void xfs_icsb_lock(xfs_mount_t *mp) { mutex_lock(&mp->m_icsb_mutex); } static inline void xfs_icsb_unlock(xfs_mount_t *mp) { mutex_unlock(&mp->m_icsb_mutex); } #else #define xfs_icsb_lock(mp) #define xfs_icsb_unlock(mp) #endif /* * This structure is for use by the xfs_mod_incore_sb_batch() routine. * xfs_growfs can specify a few fields which are more than int limit */ typedef struct xfs_mod_sb { xfs_sb_field_t msb_field; /* Field to modify, see below */ int64_t msb_delta; /* Change to make to specified field */ } xfs_mod_sb_t; extern int xfs_log_sbcount(xfs_mount_t *, uint); extern __uint64_t xfs_default_resblks(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp); extern void xfs_unmountfs(xfs_mount_t *); extern int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); extern int xfs_fs_writable(xfs_mount_t *); extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); extern int xfs_dev_is_read_only(struct xfs_mount *, char *); extern void xfs_set_low_space_thresholds(struct xfs_mount *); #endif /* __KERNEL__ */ /* * perag get/put wrappers for ref counting */ struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, int tag); void xfs_perag_put(struct xfs_perag *pag); extern void xfs_mod_sb(struct xfs_trans *, __int64_t); extern int xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t, xfs_agnumber_t *); extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); #endif /* __XFS_MOUNT_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_arch.h0000664000000000000000000001014711650373060015211 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_ARCH_H__ #define __XFS_ARCH_H__ #ifndef XFS_BIG_INUMS # error XFS_BIG_INUMS must be defined true or false #endif #ifdef __KERNEL__ #include #ifdef __BIG_ENDIAN #define XFS_NATIVE_HOST 1 #else #undef XFS_NATIVE_HOST #endif #else /* __KERNEL__ */ #if __BYTE_ORDER == __BIG_ENDIAN #define XFS_NATIVE_HOST 1 #else #undef XFS_NATIVE_HOST #endif #ifdef XFS_NATIVE_HOST #define cpu_to_be16(val) ((__force __be16)(__u16)(val)) #define cpu_to_be32(val) ((__force __be32)(__u32)(val)) #define cpu_to_be64(val) ((__force __be64)(__u64)(val)) #define be16_to_cpu(val) ((__force __u16)(__be16)(val)) #define be32_to_cpu(val) ((__force __u32)(__be32)(val)) #define be64_to_cpu(val) ((__force __u64)(__be64)(val)) #else #define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val))) #define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val))) #define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val))) #define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val))) #define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val))) #define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val))) #endif static inline void be16_add_cpu(__be16 *a, __s16 b) { *a = cpu_to_be16(be16_to_cpu(*a) + b); } static inline void be32_add_cpu(__be32 *a, __s32 b) { *a = cpu_to_be32(be32_to_cpu(*a) + b); } static inline void be64_add_cpu(__be64 *a, __s64 b) { *a = cpu_to_be64(be64_to_cpu(*a) + b); } #endif /* __KERNEL__ */ /* * get and set integers from potentially unaligned locations */ #define INT_GET_UNALIGNED_16_BE(pointer) \ ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1]))) #define INT_SET_UNALIGNED_16_BE(pointer,value) \ { \ ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \ ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ } /* * In directories inode numbers are stored as unaligned arrays of unsigned * 8bit integers on disk. * * For v1 directories or v2 directories that contain inode numbers that * do not fit into 32bit the array has eight members, but the first member * is always zero: * * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7| * * For v2 directories that only contain entries with inode numbers that fit * into 32bits a four-member array is used: * * |24-31|16-23| 8-15| 0- 7| */ #define XFS_GET_DIR_INO4(di) \ (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) #define XFS_PUT_DIR_INO4(from, di) \ do { \ (di).i[0] = (((from) & 0xff000000ULL) >> 24); \ (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \ (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \ (di).i[3] = ((from) & 0x000000ffULL); \ } while (0) #define XFS_DI_HI(di) \ (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) #define XFS_DI_LO(di) \ (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7])) #define XFS_GET_DIR_INO8(di) \ (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \ ((xfs_ino_t)XFS_DI_HI(di) << 32)) #define XFS_PUT_DIR_INO8(from, di) \ do { \ (di).i[0] = 0; \ (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \ (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \ (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \ (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \ (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \ (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \ (di).i[7] = ((from) & 0x00000000000000ffULL); \ } while (0) #endif /* __XFS_ARCH_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2_data.h0000664000000000000000000001255311650373061016131 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_DATA_H__ #define __XFS_DIR2_DATA_H__ /* * Directory format 2, data block structures. */ struct xfs_dabuf; struct xfs_da_args; struct xfs_inode; struct xfs_trans; /* * Constants. */ #define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */ #define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */ #define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG) #define XFS_DIR2_DATA_FREE_TAG 0xffff #define XFS_DIR2_DATA_FD_COUNT 3 /* * Directory address space divided into sections, * spaces separated by 32GB. */ #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) #define XFS_DIR2_DATA_SPACE 0 #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_DATA_FIRSTDB(mp) \ xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) /* * Offsets of . and .. in data space (always block 0) */ #define XFS_DIR2_DATA_DOT_OFFSET \ ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) #define XFS_DIR2_DATA_DOTDOT_OFFSET \ (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1)) #define XFS_DIR2_DATA_FIRST_OFFSET \ (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2)) /* * Structures. */ /* * Describe a free area in the data block. * The freespace will be formatted as a xfs_dir2_data_unused_t. */ typedef struct xfs_dir2_data_free { __be16 offset; /* start of freespace */ __be16 length; /* length of freespace */ } xfs_dir2_data_free_t; /* * Header for the data blocks. * Always at the beginning of a directory-sized block. * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. */ typedef struct xfs_dir2_data_hdr { __be32 magic; /* XFS_DIR2_DATA_MAGIC */ /* or XFS_DIR2_BLOCK_MAGIC */ xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; } xfs_dir2_data_hdr_t; /* * Active entry in a data block. Aligned to 8 bytes. * Tag appears as the last 2 bytes. */ typedef struct xfs_dir2_data_entry { __be64 inumber; /* inode number */ __u8 namelen; /* name length */ __u8 name[1]; /* name bytes, no null */ /* variable offset */ __be16 tag; /* starting offset of us */ } xfs_dir2_data_entry_t; /* * Unused entry in a data block. Aligned to 8 bytes. * Tag appears as the last 2 bytes. */ typedef struct xfs_dir2_data_unused { __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */ __be16 length; /* total free length */ /* variable offset */ __be16 tag; /* starting offset of us */ } xfs_dir2_data_unused_t; typedef union { xfs_dir2_data_entry_t entry; xfs_dir2_data_unused_t unused; } xfs_dir2_data_union_t; /* * Generic data block structure, for xfs_db. */ typedef struct xfs_dir2_data { xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */ xfs_dir2_data_union_t u[1]; } xfs_dir2_data_t; /* * Macros. */ /* * Size of a data entry. */ static inline int xfs_dir2_data_entsize(int n) { return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN); } /* * Pointer to an entry's tag word. */ static inline __be16 * xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) { return (__be16 *)((char *)dep + xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); } /* * Pointer to a freespace's tag word. */ static inline __be16 * xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) { return (__be16 *)((char *)dup + be16_to_cpu(dup->length) - sizeof(__be16)); } /* * Function declarations. */ #ifdef DEBUG extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp); #else #define xfs_dir2_data_check(dp,bp) #endif extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, xfs_dir2_data_unused_t *dup); extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, xfs_dir2_data_unused_t *dup, int *loghead); extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, int *loghead); extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, struct xfs_dabuf **bpp); extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, xfs_dir2_data_entry_t *dep); extern void xfs_dir2_data_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp); extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp, xfs_dir2_data_unused_t *dup); extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp, xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp, xfs_dir2_data_unused_t *dup, xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); #endif /* __XFS_DIR2_DATA_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_types.h0000664000000000000000000001230611650373061015440 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_TYPES_H__ #define __XFS_TYPES_H__ #ifdef __KERNEL__ /* * Additional type declarations for XFS */ typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef signed short int __int16_t; typedef unsigned short int __uint16_t; typedef signed int __int32_t; typedef unsigned int __uint32_t; typedef signed long long int __int64_t; typedef unsigned long long int __uint64_t; typedef enum { B_FALSE,B_TRUE } boolean_t; typedef __uint32_t prid_t; /* project ID */ typedef __uint32_t inst_t; /* an instruction */ typedef __s64 xfs_off_t; /* type */ typedef unsigned long long xfs_ino_t; /* type */ typedef __s64 xfs_daddr_t; /* type */ typedef char * xfs_caddr_t; /* type */ typedef __u32 xfs_dev_t; typedef __u32 xfs_nlink_t; /* __psint_t is the same size as a pointer */ #if (BITS_PER_LONG == 32) typedef __int32_t __psint_t; typedef __uint32_t __psunsigned_t; #elif (BITS_PER_LONG == 64) typedef __int64_t __psint_t; typedef __uint64_t __psunsigned_t; #else #error BITS_PER_LONG must be 32 or 64 #endif #endif /* __KERNEL__ */ typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */ typedef __uint32_t xfs_extlen_t; /* extent length in blocks */ typedef __uint32_t xfs_agnumber_t; /* allocation group number */ typedef __int32_t xfs_extnum_t; /* # of extents in a file */ typedef __int16_t xfs_aextnum_t; /* # extents in an attribute fork */ typedef __int64_t xfs_fsize_t; /* bytes in a file */ typedef __uint64_t xfs_ufsize_t; /* unsigned bytes in a file */ typedef __int32_t xfs_suminfo_t; /* type of bitmap summary info */ typedef __int32_t xfs_rtword_t; /* word type for bitmap manipulations */ typedef __int64_t xfs_lsn_t; /* log sequence number */ typedef __int32_t xfs_tid_t; /* transaction identifier */ typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */ typedef __uint32_t xlog_tid_t; /* transaction ID type */ /* * These types are 64 bits on disk but are either 32 or 64 bits in memory. * Disk based types: */ typedef __uint64_t xfs_dfsbno_t; /* blockno in filesystem (agno|agbno) */ typedef __uint64_t xfs_drfsbno_t; /* blockno in filesystem (raw) */ typedef __uint64_t xfs_drtbno_t; /* extent (block) in realtime area */ typedef __uint64_t xfs_dfiloff_t; /* block number in a file */ typedef __uint64_t xfs_dfilblks_t; /* number of blocks in a file */ /* * Memory based types are conditional. */ #if XFS_BIG_BLKNOS typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ typedef __uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ typedef __uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ typedef __int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ #else typedef __uint32_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ typedef __uint32_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ typedef __uint32_t xfs_rtblock_t; /* extent (block) in realtime area */ typedef __int32_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ #endif typedef __uint64_t xfs_fileoff_t; /* block number in a file */ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ /* * Null values for the types. */ #define NULLDFSBNO ((xfs_dfsbno_t)-1) #define NULLDRFSBNO ((xfs_drfsbno_t)-1) #define NULLDRTBNO ((xfs_drtbno_t)-1) #define NULLDFILOFF ((xfs_dfiloff_t)-1) #define NULLFSBLOCK ((xfs_fsblock_t)-1) #define NULLRFSBLOCK ((xfs_rfsblock_t)-1) #define NULLRTBLOCK ((xfs_rtblock_t)-1) #define NULLFILEOFF ((xfs_fileoff_t)-1) #define NULLAGBLOCK ((xfs_agblock_t)-1) #define NULLAGNUMBER ((xfs_agnumber_t)-1) #define NULLEXTNUM ((xfs_extnum_t)-1) #define NULLCOMMITLSN ((xfs_lsn_t)-1) /* * Max values for extlen, extnum, aextnum. */ #define MAXEXTLEN ((xfs_extlen_t)0x001fffff) /* 21 bits */ #define MAXEXTNUM ((xfs_extnum_t)0x7fffffff) /* signed int */ #define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */ /* * Min numbers of data/attr fork btree root pointers. */ #define MINDBTPTRS 3 #define MINABTPTRS 2 /* * MAXNAMELEN is the length (including the terminating null) of * the longest permissible file (component) name. */ #define MAXNAMELEN 256 typedef enum { XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi } xfs_lookup_t; typedef enum { XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { const unsigned char *name; int len; }; #endif /* __XFS_TYPES_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_btree.h0000664000000000000000000003413711650373060015402 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BTREE_H__ #define __XFS_BTREE_H__ struct xfs_buf; struct xfs_bmap_free; struct xfs_inode; struct xfs_mount; struct xfs_trans; extern kmem_zone_t *xfs_btree_cur_zone; /* * This nonsense is to make -wlint happy. */ #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) /* * Generic btree header. * * This is a combination of the actual format used on disk for short and long * format btrees. The first three fields are shared by both format, but * the pointers are different and should be used with care. * * To get the size of the actual short or long form headers please use * the size macros below. Never use sizeof(xfs_btree_block). */ struct xfs_btree_block { __be32 bb_magic; /* magic number for block type */ __be16 bb_level; /* 0 is a leaf */ __be16 bb_numrecs; /* current # of data records */ union { struct { __be32 bb_leftsib; __be32 bb_rightsib; } s; /* short form pointers */ struct { __be64 bb_leftsib; __be64 bb_rightsib; } l; /* long form pointers */ } bb_u; /* rest */ }; #define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */ #define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */ /* * Generic key, ptr and record wrapper structures. * * These are disk format structures, and are converted where necessary * by the btree specific code that needs to interpret them. */ union xfs_btree_ptr { __be32 s; /* short form ptr */ __be64 l; /* long form ptr */ }; union xfs_btree_key { xfs_bmbt_key_t bmbt; xfs_bmdr_key_t bmbr; /* bmbt root block */ xfs_alloc_key_t alloc; xfs_inobt_key_t inobt; }; union xfs_btree_rec { xfs_bmbt_rec_t bmbt; xfs_bmdr_rec_t bmbr; /* bmbt root block */ xfs_alloc_rec_t alloc; xfs_inobt_rec_t inobt; }; /* * For logging record fields. */ #define XFS_BB_MAGIC 0x01 #define XFS_BB_LEVEL 0x02 #define XFS_BB_NUMRECS 0x04 #define XFS_BB_LEFTSIB 0x08 #define XFS_BB_RIGHTSIB 0x10 #define XFS_BB_NUM_BITS 5 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) /* * Magic numbers for btree blocks. */ extern const __uint32_t xfs_magics[]; /* * Generic stats interface */ #define __XFS_BTREE_STATS_INC(type, stat) \ XFS_STATS_INC(xs_ ## type ## _2_ ## stat) #define XFS_BTREE_STATS_INC(cur, stat) \ do { \ switch (cur->bc_btnum) { \ case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) #define __XFS_BTREE_STATS_ADD(type, stat, val) \ XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) #define XFS_BTREE_STATS_ADD(cur, stat, val) \ do { \ switch (cur->bc_btnum) { \ case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ struct xfs_btree_ops { /* size of the key and record structures */ size_t key_len; size_t rec_len; /* cursor operations */ struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); void (*update_cursor)(struct xfs_btree_cur *src, struct xfs_btree_cur *dst); /* update btree root pointer */ void (*set_root)(struct xfs_btree_cur *cur, union xfs_btree_ptr *nptr, int level_change); /* block allocation / freeing */ int (*alloc_block)(struct xfs_btree_cur *cur, union xfs_btree_ptr *start_bno, union xfs_btree_ptr *new_bno, int length, int *stat); int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); /* update last record information */ void (*update_lastrec)(struct xfs_btree_cur *cur, struct xfs_btree_block *block, union xfs_btree_rec *rec, int ptr, int reason); /* records in block/level */ int (*get_minrecs)(struct xfs_btree_cur *cur, int level); int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); /* records on disk. Matter for the root in inode case. */ int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level); /* init values of btree structures */ void (*init_key_from_rec)(union xfs_btree_key *key, union xfs_btree_rec *rec); void (*init_rec_from_key)(union xfs_btree_key *key, union xfs_btree_rec *rec); void (*init_rec_from_cur)(struct xfs_btree_cur *cur, union xfs_btree_rec *rec); void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr); /* difference between key value and cursor value */ __int64_t (*key_diff)(struct xfs_btree_cur *cur, union xfs_btree_key *key); #ifdef DEBUG /* check that k1 is lower than k2 */ int (*keys_inorder)(struct xfs_btree_cur *cur, union xfs_btree_key *k1, union xfs_btree_key *k2); /* check that r1 is lower than r2 */ int (*recs_inorder)(struct xfs_btree_cur *cur, union xfs_btree_rec *r1, union xfs_btree_rec *r2); #endif /* btree tracing */ #ifdef XFS_BTREE_TRACE void (*trace_enter)(struct xfs_btree_cur *, const char *, char *, int, int, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t, __psunsigned_t); void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *, __uint64_t *, __uint64_t *); void (*trace_key)(struct xfs_btree_cur *, union xfs_btree_key *, __uint64_t *, __uint64_t *); void (*trace_record)(struct xfs_btree_cur *, union xfs_btree_rec *, __uint64_t *, __uint64_t *, __uint64_t *); #endif }; /* * Reasons for the update_lastrec method to be called. */ #define LASTREC_UPDATE 0 #define LASTREC_INSREC 1 #define LASTREC_DELREC 2 /* * Btree cursor structure. * This collects all information needed by the btree code in one place. */ typedef struct xfs_btree_cur { struct xfs_trans *bc_tp; /* transaction we're in, if any */ struct xfs_mount *bc_mp; /* file system mount struct */ const struct xfs_btree_ops *bc_ops; uint bc_flags; /* btree features - below */ union { xfs_alloc_rec_incore_t a; xfs_bmbt_irec_t b; xfs_inobt_rec_incore_t i; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ __uint8_t bc_nlevels; /* number of levels in the tree */ __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ xfs_btnum_t bc_btnum; /* identifies which btree type */ union { struct { /* needed for BNO, CNT, INO */ struct xfs_buf *agbp; /* agf/agi buffer pointer */ xfs_agnumber_t agno; /* ag number */ } a; struct { /* needed for BMAP */ struct xfs_inode *ip; /* pointer to our inode */ struct xfs_bmap_free *flist; /* list to free after */ xfs_fsblock_t firstblock; /* 1st blk allocated */ int allocated; /* count of alloced */ short forksize; /* fork's inode space */ char whichfork; /* data or attr fork */ char flags; /* flags */ #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ } b; } bc_private; /* per-btree type data */ } xfs_btree_cur_t; /* cursor flags */ #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ #define XFS_BTREE_NOERROR 0 #define XFS_BTREE_ERROR 1 /* * Convert from buffer to btree block header. */ #define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)XFS_BUF_PTR(bp)) /* * Check that block header is ok. */ int xfs_btree_check_block( struct xfs_btree_cur *cur, /* btree cursor */ struct xfs_btree_block *block, /* generic btree block pointer */ int level, /* level of the btree block */ struct xfs_buf *bp); /* buffer containing block, if any */ /* * Check that (long) pointer is ok. */ int /* error (0 or EFSCORRUPTED) */ xfs_btree_check_lptr( struct xfs_btree_cur *cur, /* btree cursor */ xfs_dfsbno_t ptr, /* btree block disk address */ int level); /* btree block level */ /* * Delete the btree cursor. */ void xfs_btree_del_cursor( xfs_btree_cur_t *cur, /* btree cursor */ int error); /* del because of error */ /* * Duplicate the btree cursor. * Allocate a new one, copy the record, re-get the buffers. */ int /* error */ xfs_btree_dup_cursor( xfs_btree_cur_t *cur, /* input cursor */ xfs_btree_cur_t **ncur);/* output cursor */ /* * Get a buffer for the block, return it with no data read. * Long-form addressing. */ struct xfs_buf * /* buffer for fsbno */ xfs_btree_get_bufl( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t fsbno, /* file system block number */ uint lock); /* lock flags for get_buf */ /* * Get a buffer for the block, return it with no data read. * Short-form addressing. */ struct xfs_buf * /* buffer for agno/agbno */ xfs_btree_get_bufs( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ uint lock); /* lock flags for get_buf */ /* * Check for the cursor referring to the last block at the given level. */ int /* 1=is last block, 0=not last block */ xfs_btree_islastblock( xfs_btree_cur_t *cur, /* btree cursor */ int level); /* level to check */ /* * Compute first and last byte offsets for the fields given. * Interprets the offsets table, which contains struct field offsets. */ void xfs_btree_offsets( __int64_t fields, /* bitmask of fields */ const short *offsets,/* table of field offsets */ int nbits, /* number of bits to inspect */ int *first, /* output: first byte offset */ int *last); /* output: last byte offset */ /* * Get a buffer for the block, return it read in. * Long-form addressing. */ int /* error */ xfs_btree_read_bufl( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t fsbno, /* file system block number */ uint lock, /* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ int refval);/* ref count value for buffer */ /* * Read-ahead the block, don't wait for it, don't return a buffer. * Long-form addressing. */ void /* error */ xfs_btree_reada_bufl( struct xfs_mount *mp, /* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ xfs_extlen_t count); /* count of filesystem blocks */ /* * Read-ahead the block, don't wait for it, don't return a buffer. * Short-form addressing. */ void /* error */ xfs_btree_reada_bufs( struct xfs_mount *mp, /* file system mount point */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ xfs_extlen_t count); /* count of filesystem blocks */ /* * Common btree core entry points. */ int xfs_btree_increment(struct xfs_btree_cur *, int, int *); int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); int xfs_btree_insert(struct xfs_btree_cur *, int *); int xfs_btree_delete(struct xfs_btree_cur *, int *); int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); /* * Internal btree helpers also used by xfs_bmap.c. */ void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int); /* * Helpers. */ static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block) { return be16_to_cpu(block->bb_numrecs); } static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, __uint16_t numrecs) { block->bb_numrecs = cpu_to_be16(numrecs); } static inline int xfs_btree_get_level(struct xfs_btree_block *block) { return be16_to_cpu(block->bb_level); } /* * Min and max functions for extlen, agblock, fileoff, and filblks types. */ #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) #define XFS_FSB_SANITY_CHECK(mp,fsb) \ (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) #endif /* __XFS_BTREE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dinode.h0000664000000000000000000002025711650373060015541 0ustar /* * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DINODE_H__ #define __XFS_DINODE_H__ #define XFS_DINODE_MAGIC 0x494e /* 'IN' */ #define XFS_DINODE_GOOD_VERSION(v) (((v) == 1 || (v) == 2)) typedef struct xfs_timestamp { __be32 t_sec; /* timestamp seconds */ __be32 t_nsec; /* timestamp nanoseconds */ } xfs_timestamp_t; /* * On-disk inode structure. * * This is just the header or "dinode core", the inode is expanded to fill a * variable size the leftover area split into a data and an attribute fork. * The format of the data and attribute fork depends on the format of the * inode as indicated by di_format and di_aformat. To access the data and * attribute use the XFS_DFORK_PTR, XFS_DFORK_DPTR, and XFS_DFORK_PTR macros * below. * * There is a very similar struct icdinode in xfs_inode which matches the * layout of the first 96 bytes of this structure, but is kept in native * format instead of big endian. */ typedef struct xfs_dinode { __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ __be16 di_mode; /* mode and type of file */ __u8 di_version; /* inode version */ __u8 di_format; /* format of di_c data */ __be16 di_onlink; /* old number of links to file */ __be32 di_uid; /* owner's user id */ __be32 di_gid; /* owner's group id */ __be32 di_nlink; /* number of links to file */ __be16 di_projid_lo; /* lower part of owner's project id */ __be16 di_projid_hi; /* higher part owner's project id */ __u8 di_pad[6]; /* unused, zeroed space */ __be16 di_flushiter; /* incremented on flush */ xfs_timestamp_t di_atime; /* time last accessed */ xfs_timestamp_t di_mtime; /* time last modified */ xfs_timestamp_t di_ctime; /* time created/inode modified */ __be64 di_size; /* number of bytes in file */ __be64 di_nblocks; /* # of direct & btree blocks used */ __be32 di_extsize; /* basic/minimum extent size for file */ __be32 di_nextents; /* number of extents in data fork */ __be16 di_anextents; /* number of extents in attribute fork*/ __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */ __s8 di_aformat; /* format of attr fork's data */ __be32 di_dmevmask; /* DMIG event mask */ __be16 di_dmstate; /* DMIG state info */ __be16 di_flags; /* random flags, XFS_DIFLAG_... */ __be32 di_gen; /* generation number */ /* di_next_unlinked is the only non-core field in the old dinode */ __be32 di_next_unlinked;/* agi unlinked list ptr */ } __attribute__((packed)) xfs_dinode_t; #define DI_MAX_FLUSH 0xffff /* * The 32 bit link count in the inode theoretically maxes out at UINT_MAX. * Since the pathconf interface is signed, we use 2^31 - 1 instead. * The old inode format had a 16 bit link count, so its maximum is USHRT_MAX. */ #define XFS_MAXLINK ((1U << 31) - 1U) #define XFS_MAXLINK_1 65535U /* * Values for di_format */ typedef enum xfs_dinode_fmt { XFS_DINODE_FMT_DEV, /* xfs_dev_t */ XFS_DINODE_FMT_LOCAL, /* bulk data */ XFS_DINODE_FMT_EXTENTS, /* struct xfs_bmbt_rec */ XFS_DINODE_FMT_BTREE, /* struct xfs_bmdr_block */ XFS_DINODE_FMT_UUID /* uuid_t */ } xfs_dinode_fmt_t; /* * Inode minimum and maximum sizes. */ #define XFS_DINODE_MIN_LOG 8 #define XFS_DINODE_MAX_LOG 11 #define XFS_DINODE_MIN_SIZE (1 << XFS_DINODE_MIN_LOG) #define XFS_DINODE_MAX_SIZE (1 << XFS_DINODE_MAX_LOG) /* * Inode size for given fs. */ #define XFS_LITINO(mp) \ ((int)(((mp)->m_sb.sb_inodesize) - sizeof(struct xfs_dinode))) #define XFS_BROOT_SIZE_ADJ \ (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t)) /* * Inode data & attribute fork sizes, per inode. */ #define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0) #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3)) #define XFS_DFORK_DSIZE(dip,mp) \ (XFS_DFORK_Q(dip) ? \ XFS_DFORK_BOFF(dip) : \ XFS_LITINO(mp)) #define XFS_DFORK_ASIZE(dip,mp) \ (XFS_DFORK_Q(dip) ? \ XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \ 0) #define XFS_DFORK_SIZE(dip,mp,w) \ ((w) == XFS_DATA_FORK ? \ XFS_DFORK_DSIZE(dip, mp) : \ XFS_DFORK_ASIZE(dip, mp)) /* * Return pointers to the data or attribute forks. */ #define XFS_DFORK_DPTR(dip) \ ((char *)(dip) + sizeof(struct xfs_dinode)) #define XFS_DFORK_APTR(dip) \ (XFS_DFORK_DPTR(dip) + XFS_DFORK_BOFF(dip)) #define XFS_DFORK_PTR(dip,w) \ ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip)) #define XFS_DFORK_FORMAT(dip,w) \ ((w) == XFS_DATA_FORK ? \ (dip)->di_format : \ (dip)->di_aformat) #define XFS_DFORK_NEXTENTS(dip,w) \ ((w) == XFS_DATA_FORK ? \ be32_to_cpu((dip)->di_nextents) : \ be16_to_cpu((dip)->di_anextents)) #define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) /* * For block and character special files the 32bit dev_t is stored at the * beginning of the data fork. */ static inline xfs_dev_t xfs_dinode_get_rdev(struct xfs_dinode *dip) { return be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(dip)); } static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) { *(__be32 *)XFS_DFORK_DPTR(dip) = cpu_to_be32(rdev); } /* * Values for di_flags * There should be a one-to-one correspondence between these flags and the * XFS_XFLAG_s. */ #define XFS_DIFLAG_REALTIME_BIT 0 /* file's blocks come from rt area */ #define XFS_DIFLAG_PREALLOC_BIT 1 /* file space has been preallocated */ #define XFS_DIFLAG_NEWRTBM_BIT 2 /* for rtbitmap inode, new format */ #define XFS_DIFLAG_IMMUTABLE_BIT 3 /* inode is immutable */ #define XFS_DIFLAG_APPEND_BIT 4 /* inode is append-only */ #define XFS_DIFLAG_SYNC_BIT 5 /* inode is written synchronously */ #define XFS_DIFLAG_NOATIME_BIT 6 /* do not update atime */ #define XFS_DIFLAG_NODUMP_BIT 7 /* do not dump */ #define XFS_DIFLAG_RTINHERIT_BIT 8 /* create with realtime bit set */ #define XFS_DIFLAG_PROJINHERIT_BIT 9 /* create with parents projid */ #define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ #define XFS_DIFLAG_FILESTREAM_BIT 14 /* use filestream allocator */ #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) #define XFS_DIFLAG_IMMUTABLE (1 << XFS_DIFLAG_IMMUTABLE_BIT) #define XFS_DIFLAG_APPEND (1 << XFS_DIFLAG_APPEND_BIT) #define XFS_DIFLAG_SYNC (1 << XFS_DIFLAG_SYNC_BIT) #define XFS_DIFLAG_NOATIME (1 << XFS_DIFLAG_NOATIME_BIT) #define XFS_DIFLAG_NODUMP (1 << XFS_DIFLAG_NODUMP_BIT) #define XFS_DIFLAG_RTINHERIT (1 << XFS_DIFLAG_RTINHERIT_BIT) #define XFS_DIFLAG_PROJINHERIT (1 << XFS_DIFLAG_PROJINHERIT_BIT) #define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) #ifdef CONFIG_XFS_RT #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) #else #define XFS_IS_REALTIME_INODE(ip) (0) #endif #define XFS_DIFLAG_ANY \ (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) #endif /* __XFS_DINODE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2_node.h0000664000000000000000000000647011650373061016146 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_NODE_H__ #define __XFS_DIR2_NODE_H__ /* * Directory version 2, btree node format structures */ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_da_state; struct xfs_da_state_blk; struct xfs_inode; struct xfs_trans; /* * Offset of the freespace index. */ #define XFS_DIR2_FREE_SPACE 2 #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_FREE_FIRSTDB(mp) \ xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET) #define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */ typedef struct xfs_dir2_free_hdr { __be32 magic; /* XFS_DIR2_FREE_MAGIC */ __be32 firstdb; /* db of first entry */ __be32 nvalid; /* count of valid entries */ __be32 nused; /* count of used entries */ } xfs_dir2_free_hdr_t; typedef struct xfs_dir2_free { xfs_dir2_free_hdr_t hdr; /* block header */ __be16 bests[1]; /* best free counts */ /* unused entries are -1 */ } xfs_dir2_free_t; #define XFS_DIR2_MAX_FREE_BESTS(mp) \ (((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \ (uint)sizeof(xfs_dir2_data_off_t)) /* * Convert data space db to the corresponding free db. */ static inline xfs_dir2_db_t xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) { return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp)); } /* * Convert data space db to the corresponding index in a free db. */ static inline int xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) { return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp)); } extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, struct xfs_dabuf *lbp); extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count); extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp, struct xfs_da_args *args, int *indexp, struct xfs_da_state *state); extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp, struct xfs_dabuf *leaf2_bp); extern int xfs_dir2_leafn_split(struct xfs_da_state *state, struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action); extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state, struct xfs_da_state_blk *drop_blk, struct xfs_da_state_blk *save_blk); extern int xfs_dir2_node_addname(struct xfs_da_args *args); extern int xfs_dir2_node_lookup(struct xfs_da_args *args); extern int xfs_dir2_node_removename(struct xfs_da_args *args); extern int xfs_dir2_node_replace(struct xfs_da_args *args); extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo, int *rvalp); #endif /* __XFS_DIR2_NODE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_btree_trace.h0000664000000000000000000000646211650373060016560 0ustar /* * Copyright (c) 2008 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BTREE_TRACE_H__ #define __XFS_BTREE_TRACE_H__ struct xfs_btree_cur; struct xfs_buf; /* * Trace hooks. * i,j = integer (32 bit) * b = btree block buffer (xfs_buf_t) * p = btree ptr * r = btree record * k = btree key */ #ifdef XFS_BTREE_TRACE /* * Trace buffer entry types. */ #define XFS_BTREE_KTRACE_ARGBI 1 #define XFS_BTREE_KTRACE_ARGBII 2 #define XFS_BTREE_KTRACE_ARGFFFI 3 #define XFS_BTREE_KTRACE_ARGI 4 #define XFS_BTREE_KTRACE_ARGIPK 5 #define XFS_BTREE_KTRACE_ARGIPR 6 #define XFS_BTREE_KTRACE_ARGIK 7 #define XFS_BTREE_KTRACE_ARGR 8 #define XFS_BTREE_KTRACE_CUR 9 /* * Sub-types for cursor traces. */ #define XBT_ARGS 0 #define XBT_ENTRY 1 #define XBT_ERROR 2 #define XBT_EXIT 3 void xfs_btree_trace_argbi(const char *, struct xfs_btree_cur *, struct xfs_buf *, int, int); void xfs_btree_trace_argbii(const char *, struct xfs_btree_cur *, struct xfs_buf *, int, int, int); void xfs_btree_trace_argi(const char *, struct xfs_btree_cur *, int, int); void xfs_btree_trace_argipk(const char *, struct xfs_btree_cur *, int, union xfs_btree_ptr, union xfs_btree_key *, int); void xfs_btree_trace_argipr(const char *, struct xfs_btree_cur *, int, union xfs_btree_ptr, union xfs_btree_rec *, int); void xfs_btree_trace_argik(const char *, struct xfs_btree_cur *, int, union xfs_btree_key *, int); void xfs_btree_trace_argr(const char *, struct xfs_btree_cur *, union xfs_btree_rec *, int); void xfs_btree_trace_cursor(const char *, struct xfs_btree_cur *, int, int); #define XFS_BTREE_TRACE_ARGBI(c, b, i) \ xfs_btree_trace_argbi(__func__, c, b, i, __LINE__) #define XFS_BTREE_TRACE_ARGBII(c, b, i, j) \ xfs_btree_trace_argbii(__func__, c, b, i, j, __LINE__) #define XFS_BTREE_TRACE_ARGI(c, i) \ xfs_btree_trace_argi(__func__, c, i, __LINE__) #define XFS_BTREE_TRACE_ARGIPK(c, i, p, k) \ xfs_btree_trace_argipk(__func__, c, i, p, k, __LINE__) #define XFS_BTREE_TRACE_ARGIPR(c, i, p, r) \ xfs_btree_trace_argipr(__func__, c, i, p, r, __LINE__) #define XFS_BTREE_TRACE_ARGIK(c, i, k) \ xfs_btree_trace_argik(__func__, c, i, k, __LINE__) #define XFS_BTREE_TRACE_ARGR(c, r) \ xfs_btree_trace_argr(__func__, c, r, __LINE__) #define XFS_BTREE_TRACE_CURSOR(c, t) \ xfs_btree_trace_cursor(__func__, c, t, __LINE__) #else #define XFS_BTREE_TRACE_ARGBI(c, b, i) #define XFS_BTREE_TRACE_ARGBII(c, b, i, j) #define XFS_BTREE_TRACE_ARGI(c, i) #define XFS_BTREE_TRACE_ARGIPK(c, i, p, s) #define XFS_BTREE_TRACE_ARGIPR(c, i, p, r) #define XFS_BTREE_TRACE_ARGIK(c, i, k) #define XFS_BTREE_TRACE_ARGR(c, r) #define XFS_BTREE_TRACE_CURSOR(c, t) #endif /* XFS_BTREE_TRACE */ #endif /* __XFS_BTREE_TRACE_H__ */ xfsprogs-3.1.9ubuntu2/include/path.h0000664000000000000000000000436311650373060014353 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __PATH_H__ #define __PATH_H__ #include /* * XFS Filesystem Paths * * Utility routines for iterating and searching through the list * of known mounted filesystems and project paths. */ #define FS_MOUNT_POINT (1<<0) #define FS_PROJECT_PATH (1<<1) typedef struct fs_path { char *fs_name; /* Data device for filesystem */ dev_t fs_datadev; char *fs_log; /* External log device, if any */ dev_t fs_logdev; char *fs_rt; /* Realtime device, if any */ dev_t fs_rtdev; char *fs_dir; /* Directory / mount point */ uint fs_flags; /* FS_{MOUNT_POINT,PROJECT_PATH}*/ uint fs_prid; /* Project ID for tree root */ } fs_path_t; extern int fs_count; /* number of entries in fs table */ extern fs_path_t *fs_table; /* array of entries in fs table */ extern fs_path_t *fs_path; /* current entry in the fs table */ extern char *mtab_file; extern void fs_table_initialise(int, char *[], int, char *[]); extern void fs_table_destroy(void); extern void fs_table_insert_project_path(char *__dir, uint __projid); extern fs_path_t *fs_table_lookup(const char *__dir, uint __flags); typedef struct fs_cursor { uint count; /* total count of mount entries */ uint index; /* current position in table */ uint flags; /* iterator flags: mounts/trees */ fs_path_t *table; /* local/global table pointer */ fs_path_t local; /* space for single-entry table */ } fs_cursor_t; extern void fs_cursor_initialise(char *__dir, uint __flags, fs_cursor_t *__cp); extern fs_path_t *fs_cursor_next_entry(fs_cursor_t *__cp); #endif /* __PATH_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_trace.h0000664000000000000000000001030711650373061015371 0ustar /* * Copyright (c) 2011 RedHat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TRACE_H__ #define __TRACE_H__ #define trace_xfs_alloc_exact_done(a) ((void) 0) #define trace_xfs_alloc_exact_notfound(a) ((void) 0) #define trace_xfs_alloc_exact_error(a) ((void) 0) #define trace_xfs_alloc_near_nominleft(a) ((void) 0) #define trace_xfs_alloc_near_first(a) ((void) 0) #define trace_xfs_alloc_near_greater(a) ((void) 0) #define trace_xfs_alloc_near_lesser(a) ((void) 0) #define trace_xfs_alloc_near_error(a) ((void) 0) #define trace_xfs_alloc_size_neither(a) ((void) 0) #define trace_xfs_alloc_size_noentry(a) ((void) 0) #define trace_xfs_alloc_size_nominleft(a) ((void) 0) #define trace_xfs_alloc_size_done(a) ((void) 0) #define trace_xfs_alloc_size_error(a) ((void) 0) #define trace_xfs_alloc_small_freelist(a) ((void) 0) #define trace_xfs_alloc_small_notenough(a) ((void) 0) #define trace_xfs_alloc_small_done(a) ((void) 0) #define trace_xfs_alloc_small_error(a) ((void) 0) #define trace_xfs_alloc_vextent_badargs(a) ((void) 0) #define trace_xfs_alloc_vextent_nofix(a) ((void) 0) #define trace_xfs_alloc_vextent_noagbp(a) ((void) 0) #define trace_xfs_alloc_vextent_loopfailed(a) ((void) 0) #define trace_xfs_alloc_vextent_allfailed(a) ((void) 0) #define trace_xfs_log_recover_item_reorder_head(a,b,c,d) ((void) 0) #define trace_xfs_log_recover_item_reorder_tail(a,b,c,d) ((void) 0) #define trace_xfs_log_recover_item_add_cont(a,b,c,d) ((void) 0) #define trace_xfs_log_recover_item_add(a,b,c,d) ((void) 0) #define trace_xfs_btree_corrupt(a,b) ((void) 0) #define trace_xfs_da_btree_corrupt(a,b) ((void) 0) #define trace_xfs_free_extent(a,b,c,d,e,f,g) ((void) 0) #define trace_xfs_agf(a,b,c,d) ((void) 0) #define trace_xfs_iext_insert(a,b,c,d,e) ((void) 0) #define trace_xfs_iext_remove(a,b,c,d) ((void) 0) #define trace_xfs_dir2_grow_inode(a,b) ((void) 0) #define trace_xfs_dir2_shrink_inode(a,b) ((void) 0) #define trace_xfs_dir2_leaf_to_node(a) ((void) 0) #define trace_xfs_dir2_leaf_to_block(a) ((void) 0) #define trace_xfs_dir2_leaf_addname(a) ((void) 0) #define trace_xfs_dir2_leaf_lookup(a) ((void) 0) #define trace_xfs_dir2_leaf_removename(a) ((void) 0) #define trace_xfs_dir2_leaf_replace(a) ((void) 0) #define trace_xfs_dir2_block_addname(a) ((void) 0) #define trace_xfs_dir2_block_to_leaf(a) ((void) 0) #define trace_xfs_dir2_block_to_sf(a) ((void) 0) #define trace_xfs_dir2_block_lookup(a) ((void) 0) #define trace_xfs_dir2_block_removename(a) ((void) 0) #define trace_xfs_dir2_block_replace(a) ((void) 0) #define trace_xfs_dir2_leafn_add(a,b) ((void) 0) #define trace_xfs_dir2_leafn_remove(a,b) ((void) 0) #define trace_xfs_dir2_leafn_moveents(a,b,c,d) ((void) 0) #define trace_xfs_dir2_node_to_leaf(a) ((void) 0) #define trace_xfs_dir2_node_addname(a) ((void) 0) #define trace_xfs_dir2_node_lookup(a) ((void) 0) #define trace_xfs_dir2_node_removename(a) ((void) 0) #define trace_xfs_dir2_node_replace(a) ((void) 0) #define trace_xfs_dir2_sf_to_block(a) ((void) 0) #define trace_xfs_dir2_sf_addname(a) ((void) 0) #define trace_xfs_dir2_sf_create(a) ((void) 0) #define trace_xfs_dir2_sf_lookup(a) ((void) 0) #define trace_xfs_dir2_sf_removename(a) ((void) 0) #define trace_xfs_dir2_sf_replace(a) ((void) 0) #define trace_xfs_dir2_sf_toino4(a) ((void) 0) #define trace_xfs_dir2_sf_toino8(a) ((void) 0) #define trace_xfs_bmap_pre_update(a,b,c,d) ((void) 0) #define trace_xfs_bmap_post_update(a,b,c,d) ((void) 0) #define trace_xfs_extlist(a,b,c,d) ((void) 0) #define trace_xfs_bunmap(a,b,c,d,e) ((void) 0) #define trace_xfs_perag_get(a,b,c,d) ((void) 0) #define trace_xfs_perag_put(a,b,c,d) ((void) 0) #endif /* __TRACE_H__ */ xfsprogs-3.1.9ubuntu2/include/builddefs.in0000664000000000000000000000752612062210562015536 0ustar # # Copyright (c) 2004-2006 Silicon Graphics, Inc. # All Rights Reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # @configure_input@ # ifndef _BUILDDEFS_INCLUDED_ _BUILDDEFS_INCLUDED_ = 1 DEBUG = @debug_build@ OPTIMIZER = @opt_build@ MALLOCLIB = @malloc_lib@ LOADERFLAGS = @LDFLAGS@ LTLDFLAGS = @LDFLAGS@ CFLAGS = @CFLAGS@ LIBRT = @librt@ LIBUUID = @libuuid@ LIBPTHREAD = @libpthread@ LIBTERMCAP = @libtermcap@ LIBEDITLINE = @libeditline@ LIBREADLINE = @libreadline@ LIBBLKID = @libblkid@ LIBXFS = $(TOPDIR)/libxfs/libxfs.la LIBXCMD = $(TOPDIR)/libxcmd/libxcmd.la LIBXLOG = $(TOPDIR)/libxlog/libxlog.la LIBDISK = $(TOPDIR)/libdisk/libdisk.la LIBHANDLE = $(TOPDIR)/libhandle/libhandle.la PKG_NAME = @pkg_name@ PKG_USER = @pkg_user@ PKG_GROUP = @pkg_group@ PKG_RELEASE = @pkg_release@ PKG_VERSION = @pkg_version@ PKG_PLATFORM = @pkg_platform@ PKG_DISTRIBUTION= @pkg_distribution@ prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ top_builddir = @top_builddir@ PKG_SBIN_DIR = @sbindir@ PKG_ROOT_SBIN_DIR = @root_sbindir@ PKG_ROOT_LIB_DIR= @root_libdir@@libdirsuffix@ PKG_LIB_DIR = @libdir@@libdirsuffix@ PKG_INC_DIR = @includedir@/xfs DK_INC_DIR = @includedir@/disk PKG_MAN_DIR = @mandir@ PKG_DOC_DIR = @datadir@/doc/@pkg_name@ PKG_LOCALE_DIR = @datadir@/locale CC = @cc@ AWK = @awk@ SED = @sed@ TAR = @tar@ ZIP = @zip@ MAKE = @make@ ECHO = @echo@ SORT = @sort@ LN_S = @LN_S@ SHELL = @SHELL@ LIBTOOL = @LIBTOOL@ MAKEDEPEND = @makedepend@ MSGFMT = @msgfmt@ MSGMERGE = @msgmerge@ XGETTEXT = @xgettext@ LOCALIZED_FILES = @LOCALIZED_FILES@ RPM = @rpm@ RPMBUILD = @rpmbuild@ RPM_VERSION = @rpm_version@ ENABLE_SHARED = @enable_shared@ ENABLE_GETTEXT = @enable_gettext@ ENABLE_EDITLINE = @enable_editline@ ENABLE_READLINE = @enable_readline@ ENABLE_BLKID = @enable_blkid@ HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@ HAVE_FADVISE = @have_fadvise@ HAVE_MADVISE = @have_madvise@ HAVE_MINCORE = @have_mincore@ HAVE_SENDFILE = @have_sendfile@ HAVE_GETMNTENT = @have_getmntent@ HAVE_GETMNTINFO = @have_getmntinfo@ HAVE_FALLOCATE = @have_fallocate@ HAVE_FIEMAP = @have_fiemap@ HAVE_PREADV = @have_preadv@ HAVE_SYNC_FILE_RANGE = @have_sync_file_range@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl ifeq ($(PKG_PLATFORM),linux) PCFLAGS = -D_GNU_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=500 -D_FILE_OFFSET_BITS=64 $(GCCFLAGS) DEPENDFLAGS = -D__linux__ endif ifeq ($(PKG_PLATFORM),gnukfreebsd) PCFLAGS = -D_GNU_SOURCE $(GCCFLAGS) endif ifeq ($(PKG_PLATFORM),darwin) PCFLAGS = -traditional-cpp $(GCCFLAGS) DEPENDFLAGS = -D__APPLE__ endif ifeq ($(PKG_PLATFORM),irix) PLDLIBS = -ldisk -lgen DEPENDFLAGS = -D__sgi__ endif ifeq ($(PKG_PLATFORM),freebsd) PLDLIBS = -L/usr/local/lib -lintl PCFLAGS = -I/usr/local/include $(GCCFLAGS) DEPENDFLAGS = -D__FreeBSD__ endif GCFLAGS = $(OPTIMIZER) $(DEBUG) \ -DVERSION=\"$(PKG_VERSION)\" -DLOCALEDIR=\"$(PKG_LOCALE_DIR)\" \ -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include ifeq ($(ENABLE_GETTEXT),yes) GCFLAGS += -DENABLE_GETTEXT endif # First, Global, Platform, Local CFLAGS CFLAGS += $(FCFLAGS) $(GCFLAGS) $(PCFLAGS) $(LCFLAGS) include $(TOPDIR)/include/buildmacros endif # # For targets that should always be rebuilt, # define a target that is never up-to-date. # Targets needing this should depend on $(_FORCE) _FORCE = __force_build xfsprogs-3.1.9ubuntu2/include/buildrules0000664000000000000000000000460011432652134015335 0ustar # # Copyright (c) 1999, 2001-2003 Silicon Graphics, Inc. All Rights Reserved. # ifndef _BUILDRULES_INCLUDED_ _BUILDRULES_INCLUDED_ = 1 include $(TOPDIR)/include/builddefs clean clobber : $(addsuffix -clean,$(SUBDIRS)) @rm -f $(DIRT) .ltdep .dep @rm -fr $(DIRDIRT) %-clean: @echo "Cleaning $*" $(Q)$(MAKE) $(MAKEOPTS) -C $* clean # Never blow away subdirs ifdef SUBDIRS .PRECIOUS: $(SUBDIRS) .PHONY: $(SUBDIRS) $(SUBDIRS): @echo "Building $@" $(Q)$(MAKE) $(MAKEOPTS) -q -C $@ || $(MAKE) $(MAKEOPTS) -C $@ endif source-link: @test -z "$$DIR" && DIR="."; \ for f in `echo $(SRCFILES) $(SUBDIRS) $(POTHEAD)`; do \ if test -d $$f ; then \ mkdir $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION)/$$DIR/$$f || exit $$?; \ $(MAKEF) DIR=$$DIR/$$f -C $$f $@ || exit $$?; \ else \ ln $$f $(TOPDIR)/$(PKG_NAME)-$(PKG_VERSION)/$$DIR/$$f || exit $$?; \ fi; \ done # # Standard targets # ifdef LTCOMMAND $(LTCOMMAND) : $(SUBDIRS) $(OBJECTS) $(LTDEPENDENCIES) @echo " [LD] $@" $(Q)$(LTLINK) -o $@ $(LDFLAGS) $(OBJECTS) $(LDLIBS) endif ifdef LTLIBRARY $(LTLIBRARY) : $(SUBDIRS) $(LTOBJECTS) @echo " [LD] $@" $(Q)$(LTLINK) $(LTLDFLAGS) -o $(LTLIBRARY) $(LTOBJECTS) $(LTLIBS) %.lo: %.c @echo " [CC] $@" $(Q)$(LTCOMPILE) -c $< else %.o: %.c @echo " [CC] $@" $(Q)$(CC) $(CFLAGS) -c $< endif ifdef POTHEAD $(POTHEAD): $(XGETTEXTFILES) @echo " [GETTXT] $@" $(Q)$(XGETTEXT) --language=C --keyword=_ --keyword=N_ -o $@ $(XGETTEXTFILES) # Update translations update-po: $(POTHEAD) $(wildcard $(TOPDIR)/po/*.po) catalogs="$(wildcard $(TOPDIR)/po/*.po)"; \ for cat in $$catalogs; do \ lang=`basename $$cat .po`; \ mv $$lang.po $$lang.old.po; \ echo "$$lang:"; \ if $(MSGMERGE) $$lang.old.po $(POTHEAD) -o $$lang.po; then \ rm -f $$lang.old.po; \ else \ echo "msgmerge for $$lang failed!"; \ rm -f $$lang.po; \ mv $$lang.old.po $$lang.po; \ fi; \ done %.mo: %.po @echo " [MSGFMT] $@" $(Q)$(MSGFMT) -c --statistics -o $@ $< endif endif # _BUILDRULES_INCLUDED_ $(_FORCE): # dependency build is automatic, relies on gcc -MM to generate. .PHONY : depend ltdepend install-qa MAKEDEP := $(MAKEDEPEND) $(CFLAGS) ltdepend: .ltdep .ltdep: $(CFILES) $(HFILES) @echo " [LTDEP]" $(Q)$(MAKEDEP) $(CFILES) | $(SED) -e 's,^\([^:]*\)\.o,\1.lo,' > .ltdep depend: .dep .dep: $(CFILES) $(HFILES) @echo " [DEP]" $(Q)$(MAKEDEP) $(CFILES) > .dep xfsprogs-3.1.9ubuntu2/include/freebsd.h0000664000000000000000000000654411307015331015025 0ustar /* * Copyright (c) 2004-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_FREEBSD_H__ #define __XFS_FREEBSD_H__ #include #include #include #include #include #include #include #include #include #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN /* FreeBSD file API is 64-bit aware */ #define fstat64 fstat #define ftruncate64 ftruncate #define lseek64 lseek #define stat64 stat #define pwrite64 pwrite #define pread64 pread #define fdatasync fsync #define memalign(a,sz) valloc(sz) #define constpp char * const * #define EFSCORRUPTED 990 /* Filesystem is corrupted */ typedef off_t xfs_off_t; typedef off_t off64_t; typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; typedef char* xfs_caddr_t; typedef off_t loff_t; #ifndef _UCHAR_T_DEFINED typedef unsigned char uchar_t; #define _UCHAR_T_DEFINED 1 #endif typedef enum { B_FALSE,B_TRUE } boolean_t; #define O_LARGEFILE 0 #define HAVE_FID 1 static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { return ioctl(fd, cmd, p); } static __inline__ int platform_test_xfs_fd(int fd) { struct statfs buf; if (fstatfs(fd, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_test_xfs_path(const char *path) { struct statfs buf; if (statfs(path, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) { return fstatfs(fd, buf); } static __inline__ void platform_getoptreset(void) { extern int optind; optind = 0; } static __inline__ int platform_uuid_compare(uuid_t *uu1, uuid_t *uu2) { return uuid_compare(uu1, uu2, NULL); } static __inline__ void platform_uuid_unparse(uuid_t *uu, char *buffer) { uint32_t status; char *s; uuid_to_string(uu, &s, &status); if (status == uuid_s_ok) strcpy(buffer, s); else buffer[0] = '\0'; free(s); } static __inline__ int platform_uuid_parse(char *buffer, uuid_t *uu) { uint32_t status; uuid_from_string(buffer, uu, &status); return (status == uuid_s_ok); } static __inline__ int platform_uuid_is_null(uuid_t *uu) { return uuid_is_nil(uu, NULL); } static __inline__ void platform_uuid_generate(uuid_t *uu) { uuid_create(uu, NULL); } static __inline__ void platform_uuid_clear(uuid_t *uu) { uuid_create_nil(uu, NULL); } static __inline__ void platform_uuid_copy(uuid_t *dst, uuid_t *src) { memcpy(dst, src, sizeof(uuid_t)); } static __inline__ int platform_discard_blocks(int fd, uint64_t start, uint64_t len) { return 0; } #endif /* __XFS_FREEBSD_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dfrag.h0000664000000000000000000000263411650373060015361 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DFRAG_H__ #define __XFS_DFRAG_H__ /* * Structure passed to xfs_swapext */ typedef struct xfs_swapext { __int64_t sx_version; /* version */ __int64_t sx_fdtarget; /* fd of target file */ __int64_t sx_fdtmp; /* fd of tmp file */ xfs_off_t sx_offset; /* offset into file */ xfs_off_t sx_length; /* leng from offset */ char sx_pad[16]; /* pad space, unused */ xfs_bstat_t sx_stat; /* stat of target b4 copy */ } xfs_swapext_t; /* * Version flag */ #define XFS_SX_VERSION 0 #ifdef __KERNEL__ /* * Prototypes for visible xfs_dfrag.c routines. */ /* * Syscall interface for xfs_swapext */ int xfs_swapext(struct xfs_swapext *sx); #endif /* __KERNEL__ */ #endif /* __XFS_DFRAG_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_ag.h0000664000000000000000000002420211650373060014660 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_AG_H__ #define __XFS_AG_H__ /* * Allocation group header * This is divided into three structures, placed in sequential 512-byte * buffers after a copy of the superblock (also in a 512-byte buffer). */ struct xfs_buf; struct xfs_mount; struct xfs_trans; #define XFS_AGF_MAGIC 0x58414746 /* 'XAGF' */ #define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */ #define XFS_AGF_VERSION 1 #define XFS_AGI_VERSION 1 #define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION) #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION) /* * Btree number 0 is bno, 1 is cnt. This value gives the size of the * arrays below. */ #define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1) /* * The second word of agf_levels in the first a.g. overlaps the EFS * superblock's magic number. Since the magic numbers valid for EFS * are > 64k, our value cannot be confused for an EFS superblock's. */ typedef struct xfs_agf { /* * Common allocation group header information */ __be32 agf_magicnum; /* magic number == XFS_AGF_MAGIC */ __be32 agf_versionnum; /* header version == XFS_AGF_VERSION */ __be32 agf_seqno; /* sequence # starting from 0 */ __be32 agf_length; /* size in blocks of a.g. */ /* * Freespace information */ __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */ __be32 agf_spare0; /* spare field */ __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ __be32 agf_spare1; /* spare field */ __be32 agf_flfirst; /* first freelist block's index */ __be32 agf_fllast; /* last freelist block's index */ __be32 agf_flcount; /* count of blocks in freelist */ __be32 agf_freeblks; /* total free blocks */ __be32 agf_longest; /* longest free space */ __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ } xfs_agf_t; #define XFS_AGF_MAGICNUM 0x00000001 #define XFS_AGF_VERSIONNUM 0x00000002 #define XFS_AGF_SEQNO 0x00000004 #define XFS_AGF_LENGTH 0x00000008 #define XFS_AGF_ROOTS 0x00000010 #define XFS_AGF_LEVELS 0x00000020 #define XFS_AGF_FLFIRST 0x00000040 #define XFS_AGF_FLLAST 0x00000080 #define XFS_AGF_FLCOUNT 0x00000100 #define XFS_AGF_FREEBLKS 0x00000200 #define XFS_AGF_LONGEST 0x00000400 #define XFS_AGF_BTREEBLKS 0x00000800 #define XFS_AGF_NUM_BITS 12 #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) #define XFS_AGF_FLAGS \ { XFS_AGF_MAGICNUM, "MAGICNUM" }, \ { XFS_AGF_VERSIONNUM, "VERSIONNUM" }, \ { XFS_AGF_SEQNO, "SEQNO" }, \ { XFS_AGF_LENGTH, "LENGTH" }, \ { XFS_AGF_ROOTS, "ROOTS" }, \ { XFS_AGF_LEVELS, "LEVELS" }, \ { XFS_AGF_FLFIRST, "FLFIRST" }, \ { XFS_AGF_FLLAST, "FLLAST" }, \ { XFS_AGF_FLCOUNT, "FLCOUNT" }, \ { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ { XFS_AGF_LONGEST, "LONGEST" }, \ { XFS_AGF_BTREEBLKS, "BTREEBLKS" } /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) #define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); /* * Size of the unlinked inode hash table in the agi. */ #define XFS_AGI_UNLINKED_BUCKETS 64 typedef struct xfs_agi { /* * Common allocation group header information */ __be32 agi_magicnum; /* magic number == XFS_AGI_MAGIC */ __be32 agi_versionnum; /* header version == XFS_AGI_VERSION */ __be32 agi_seqno; /* sequence # starting from 0 */ __be32 agi_length; /* size in blocks of a.g. */ /* * Inode information * Inodes are mapped by interpreting the inode number, so no * mapping data is needed here. */ __be32 agi_count; /* count of allocated inodes */ __be32 agi_root; /* root of inode btree */ __be32 agi_level; /* levels in inode btree */ __be32 agi_freecount; /* number of free inodes */ __be32 agi_newino; /* new inode just allocated */ __be32 agi_dirino; /* last directory inode chunk */ /* * Hash table of inodes which have been unlinked but are * still being referenced. */ __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS]; } xfs_agi_t; #define XFS_AGI_MAGICNUM 0x00000001 #define XFS_AGI_VERSIONNUM 0x00000002 #define XFS_AGI_SEQNO 0x00000004 #define XFS_AGI_LENGTH 0x00000008 #define XFS_AGI_COUNT 0x00000010 #define XFS_AGI_ROOT 0x00000020 #define XFS_AGI_LEVEL 0x00000040 #define XFS_AGI_FREECOUNT 0x00000080 #define XFS_AGI_NEWINO 0x00000100 #define XFS_AGI_DIRINO 0x00000200 #define XFS_AGI_UNLINKED 0x00000400 #define XFS_AGI_NUM_BITS 11 #define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1) /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) #define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) #define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, struct xfs_buf **bpp); /* * The third a.g. block contains the a.g. freelist, an array * of block pointers to blocks owned by the allocation btree code. */ #define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) #define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) #define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) typedef struct xfs_agfl { __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ } xfs_agfl_t; /* * Busy block/extent entry. Indexed by a rbtree in perag to mark blocks that * have been freed but whose transactions aren't committed to disk yet. * * Note that we use the transaction ID to record the transaction, not the * transaction structure itself. See xfs_alloc_busy_insert() for details. */ struct xfs_busy_extent { #ifdef __KERNEL__ struct rb_node rb_node; /* ag by-bno indexed search tree */ #endif struct list_head list; /* transaction busy extent list */ xfs_agnumber_t agno; xfs_agblock_t bno; xfs_extlen_t length; xlog_tid_t tid; /* transaction that created this */ }; /* * Per-ag incore structure, copies of information in agf and agi, * to improve the performance of allocation group selection. */ #define XFS_PAGB_NUM_SLOTS 128 typedef struct xfs_perag { struct xfs_mount *pag_mount; /* owner filesystem */ xfs_agnumber_t pag_agno; /* AG this structure belongs to */ atomic_t pag_ref; /* perag reference count */ char pagf_init; /* this agf's entry is initialized */ char pagi_init; /* this agi's entry is initialized */ char pagf_metadata; /* the agf is preferred to be metadata */ char pagi_inodeok; /* The agi is ok for inodes */ __uint8_t pagf_levels[XFS_BTNUM_AGF]; /* # of levels in bno & cnt btree */ __uint32_t pagf_flcount; /* count of blocks in freelist */ xfs_extlen_t pagf_freeblks; /* total free blocks */ xfs_extlen_t pagf_longest; /* longest free space */ __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ xfs_agino_t pagi_freecount; /* number of free inodes */ xfs_agino_t pagi_count; /* number of allocated inodes */ /* * Inode allocation search lookup optimisation. * If the pagino matches, the search for new inodes * doesn't need to search the near ones again straight away */ xfs_agino_t pagl_pagino; xfs_agino_t pagl_leftrec; xfs_agino_t pagl_rightrec; #ifdef __KERNEL__ spinlock_t pagb_lock; /* lock for pagb_tree */ struct rb_root pagb_tree; /* ordered tree of busy extents */ atomic_t pagf_fstrms; /* # of filestreams active in this AG */ spinlock_t pag_ici_lock; /* incore inode cache lock */ struct radix_tree_root pag_ici_root; /* incore inode cache root */ int pag_ici_reclaimable; /* reclaimable inodes */ struct mutex pag_ici_reclaim_lock; /* serialisation point */ unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */ /* buffer cache index */ spinlock_t pag_buf_lock; /* lock for pag_buf_tree */ struct rb_root pag_buf_tree; /* ordered tree of active buffers */ /* for rcu-safe freeing */ struct rcu_head rcu_head; #endif int pagb_count; /* pagb slots in use */ } xfs_perag_t; /* * tags for inode radix tree */ #define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup in xfs_inode_ag_iterator */ #define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */ #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) #define XFS_MIN_FREELIST_RAW(bl,cl,mp) \ (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp))) #define XFS_MIN_FREELIST(a,mp) \ (XFS_MIN_FREELIST_RAW( \ be32_to_cpu((a)->agf_levels[XFS_BTNUM_BNOi]), \ be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp)) #define XFS_MIN_FREELIST_PAG(pag,mp) \ (XFS_MIN_FREELIST_RAW( \ (unsigned int)(pag)->pagf_levels[XFS_BTNUM_BNOi], \ (unsigned int)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)) #define XFS_AGB_TO_FSB(mp,agno,agbno) \ (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno)) #define XFS_FSB_TO_AGNO(mp,fsbno) \ ((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog)) #define XFS_FSB_TO_AGBNO(mp,fsbno) \ ((xfs_agblock_t)((fsbno) & xfs_mask32lo((mp)->m_sb.sb_agblklog))) #define XFS_AGB_TO_DADDR(mp,agno,agbno) \ ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \ (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno))) #define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d)) /* * For checking for bad ranges of xfs_daddr_t's, covering multiple * allocation groups or a single xfs_daddr_t that's a superblock copy. */ #define XFS_AG_CHECK_DADDR(mp,d,len) \ ((len) == 1 ? \ ASSERT((d) == XFS_SB_DADDR || \ xfs_daddr_to_agbno(mp, d) != XFS_SB_DADDR) : \ ASSERT(xfs_daddr_to_agno(mp, d) == \ xfs_daddr_to_agno(mp, (d) + (len) - 1))) #endif /* __XFS_AG_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_trans_space.h0000664000000000000000000000664211650373061016604 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_TRANS_SPACE_H__ #define __XFS_TRANS_SPACE_H__ /* * Components of space reservations. */ #define XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) \ (((mp)->m_alloc_mxr[0]) - ((mp)->m_alloc_mnr[0])) #define XFS_EXTENTADD_SPACE_RES(mp,w) (XFS_BM_MAXLEVELS(mp,w) - 1) #define XFS_NEXTENTADD_SPACE_RES(mp,b,w)\ (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \ XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \ XFS_EXTENTADD_SPACE_RES(mp,w)) #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) #define XFS_DAENTER_DBS(mp,w) \ (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) #define XFS_DAENTER_BLOCKS(mp,w) \ (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) #define XFS_DAENTER_BMAP1B(mp,w) \ XFS_NEXTENTADD_SPACE_RES(mp, XFS_DAENTER_1B(mp, w), w) #define XFS_DAENTER_BMAPS(mp,w) \ (XFS_DAENTER_DBS(mp,w) * XFS_DAENTER_BMAP1B(mp,w)) #define XFS_DAENTER_SPACE_RES(mp,w) \ (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) #define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1 #define XFS_DIRENTER_SPACE_RES(mp,nl) \ (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ XFS_DIRENTER_MAX_SPLIT(mp,nl)) #define XFS_DIRREMOVE_SPACE_RES(mp) \ XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) #define XFS_IALLOC_SPACE_RES(mp) \ (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1) /* * Space reservation values for various transactions. */ #define XFS_ADDAFORK_SPACE_RES(mp) \ ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) #define XFS_ATTRRM_SPACE_RES(mp) \ XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) /* This macro is not used - see inline code in xfs_attr_set */ #define XFS_ATTRSET_SPACE_RES(mp, v) \ (XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + XFS_B_TO_FSB(mp, v)) #define XFS_CREATE_SPACE_RES(mp,nl) \ (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_DIOSTRAT_SPACE_RES(mp, v) \ (XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + (v)) #define XFS_GROWFS_SPACE_RES(mp) \ (2 * XFS_AG_MAXLEVELS(mp)) #define XFS_GROWFSRT_SPACE_RES(mp,b) \ ((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK)) #define XFS_LINK_SPACE_RES(mp,nl) \ XFS_DIRENTER_SPACE_RES(mp,nl) #define XFS_MKDIR_SPACE_RES(mp,nl) \ (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_QM_DQALLOC_SPACE_RES(mp) \ (XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \ XFS_DQUOT_CLUSTER_SIZE_FSB) #define XFS_QM_QINOCREATE_SPACE_RES(mp) \ XFS_IALLOC_SPACE_RES(mp) #define XFS_REMOVE_SPACE_RES(mp) \ XFS_DIRREMOVE_SPACE_RES(mp) #define XFS_RENAME_SPACE_RES(mp,nl) \ (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_SYMLINK_SPACE_RES(mp,nl,b) \ (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b)) #endif /* __XFS_TRANS_SPACE_H__ */ xfsprogs-3.1.9ubuntu2/include/hlist.h0000664000000000000000000000402311650373060014533 0ustar /* * double-linked hash list with single head implementation taken from linux * kernel headers as of 2.6.38-rc1. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __HLIST_H__ #define __HLIST_H__ struct hlist_node { struct hlist_node *next; struct hlist_node **pprev; }; struct hlist_head { struct hlist_node *first; }; #define HLIST_HEAD_INIT { .first = NULL } static inline void INIT_HLIST_NODE(struct hlist_node *h) { h->next = NULL; h->pprev = NULL; } static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; if (first) first->pprev = &n->next; h->first = n; n->pprev = &h->first; } static inline void __hlist_del(struct hlist_node *n) { struct hlist_node *next = n->next; struct hlist_node **pprev = n->pprev; *pprev = next; if (next) next->pprev = pprev; } static inline void hlist_del(struct hlist_node *n) { __hlist_del(n); } #define hlist_entry(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define hlist_for_each(pos, head) \ for (pos = (head)->first; pos; pos = pos->next) #define hlist_for_each_entry(tpos, pos, head, member) \ for (pos = (head)->first; \ pos && ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) #endif /* __LIST_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_sb.h0000664000000000000000000004574211650373061014712 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_SB_H__ #define __XFS_SB_H__ /* * Super block * Fits into a sector-sized buffer at address 0 of each allocation group. * Only the first of these is ever updated except during growfs. */ struct xfs_buf; struct xfs_mount; #define XFS_SB_MAGIC 0x58465342 /* 'XFSB' */ #define XFS_SB_VERSION_1 1 /* 5.3, 6.0.1, 6.1 */ #define XFS_SB_VERSION_2 2 /* 6.2 - attributes */ #define XFS_SB_VERSION_3 3 /* 6.2 - new inode version */ #define XFS_SB_VERSION_4 4 /* 6.2+ - bitmask version */ #define XFS_SB_VERSION_NUMBITS 0x000f #define XFS_SB_VERSION_ALLFBITS 0xfff0 #define XFS_SB_VERSION_SASHFBITS 0xf000 #define XFS_SB_VERSION_REALFBITS 0x0ff0 #define XFS_SB_VERSION_ATTRBIT 0x0010 #define XFS_SB_VERSION_NLINKBIT 0x0020 #define XFS_SB_VERSION_QUOTABIT 0x0040 #define XFS_SB_VERSION_ALIGNBIT 0x0080 #define XFS_SB_VERSION_DALIGNBIT 0x0100 #define XFS_SB_VERSION_SHAREDBIT 0x0200 #define XFS_SB_VERSION_LOGV2BIT 0x0400 #define XFS_SB_VERSION_SECTORBIT 0x0800 #define XFS_SB_VERSION_EXTFLGBIT 0x1000 #define XFS_SB_VERSION_DIRV2BIT 0x2000 #define XFS_SB_VERSION_BORGBIT 0x4000 /* ASCII only case-insens. */ #define XFS_SB_VERSION_MOREBITSBIT 0x8000 #define XFS_SB_VERSION_OKSASHFBITS \ (XFS_SB_VERSION_EXTFLGBIT | \ XFS_SB_VERSION_DIRV2BIT | \ XFS_SB_VERSION_BORGBIT) #define XFS_SB_VERSION_OKREALFBITS \ (XFS_SB_VERSION_ATTRBIT | \ XFS_SB_VERSION_NLINKBIT | \ XFS_SB_VERSION_QUOTABIT | \ XFS_SB_VERSION_ALIGNBIT | \ XFS_SB_VERSION_DALIGNBIT | \ XFS_SB_VERSION_SHAREDBIT | \ XFS_SB_VERSION_LOGV2BIT | \ XFS_SB_VERSION_SECTORBIT | \ XFS_SB_VERSION_MOREBITSBIT) #define XFS_SB_VERSION_OKREALBITS \ (XFS_SB_VERSION_NUMBITS | \ XFS_SB_VERSION_OKREALFBITS | \ XFS_SB_VERSION_OKSASHFBITS) /* * There are two words to hold XFS "feature" bits: the original * word, sb_versionnum, and sb_features2. Whenever a bit is set in * sb_features2, the feature bit XFS_SB_VERSION_MOREBITSBIT must be set. * * These defines represent bits in sb_features2. */ #define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */ #define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 #define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ XFS_SB_VERSION2_PROJID32BIT) #define XFS_SB_VERSION2_OKSASHFBITS \ (0) #define XFS_SB_VERSION2_OKREALBITS \ (XFS_SB_VERSION2_OKREALFBITS | \ XFS_SB_VERSION2_OKSASHFBITS ) /* * Superblock - in core version. Must match the ondisk version below. * Must be padded to 64 bit alignment. */ typedef struct xfs_sb { __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ __uint32_t sb_blocksize; /* logical block size, bytes */ xfs_drfsbno_t sb_dblocks; /* number of data blocks */ xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */ xfs_drtbno_t sb_rextents; /* number of realtime extents */ uuid_t sb_uuid; /* file system unique id */ xfs_dfsbno_t sb_logstart; /* starting block of log if internal */ xfs_ino_t sb_rootino; /* root inode number */ xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */ xfs_agblock_t sb_rextsize; /* realtime extent size, blocks */ xfs_agblock_t sb_agblocks; /* size of an allocation group */ xfs_agnumber_t sb_agcount; /* number of allocation groups */ xfs_extlen_t sb_rbmblocks; /* number of rt bitmap blocks */ xfs_extlen_t sb_logblocks; /* number of log blocks */ __uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */ __uint16_t sb_sectsize; /* volume sector size, bytes */ __uint16_t sb_inodesize; /* inode size, bytes */ __uint16_t sb_inopblock; /* inodes per block */ char sb_fname[12]; /* file system name */ __uint8_t sb_blocklog; /* log2 of sb_blocksize */ __uint8_t sb_sectlog; /* log2 of sb_sectsize */ __uint8_t sb_inodelog; /* log2 of sb_inodesize */ __uint8_t sb_inopblog; /* log2 of sb_inopblock */ __uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */ __uint8_t sb_rextslog; /* log2 of sb_rextents */ __uint8_t sb_inprogress; /* mkfs is in progress, don't mount */ __uint8_t sb_imax_pct; /* max % of fs for inode space */ /* statistics */ /* * These fields must remain contiguous. If you really * want to change their layout, make sure you fix the * code in xfs_trans_apply_sb_deltas(). */ __uint64_t sb_icount; /* allocated inodes */ __uint64_t sb_ifree; /* free inodes */ __uint64_t sb_fdblocks; /* free data blocks */ __uint64_t sb_frextents; /* free realtime extents */ /* * End contiguous fields. */ xfs_ino_t sb_uquotino; /* user quota inode */ xfs_ino_t sb_gquotino; /* group quota inode */ __uint16_t sb_qflags; /* quota flags */ __uint8_t sb_flags; /* misc. flags */ __uint8_t sb_shared_vn; /* shared version number */ xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */ __uint32_t sb_unit; /* stripe or raid unit */ __uint32_t sb_width; /* stripe or raid width */ __uint8_t sb_dirblklog; /* log2 of dir block size (fsbs) */ __uint8_t sb_logsectlog; /* log2 of the log sector size */ __uint16_t sb_logsectsize; /* sector size for the log, bytes */ __uint32_t sb_logsunit; /* stripe unit size for the log */ __uint32_t sb_features2; /* additional feature bits */ /* * bad features2 field as a result of failing to pad the sb * structure to 64 bits. Some machines will be using this field * for features2 bits. Easiest just to mark it bad and not use * it for anything else. */ __uint32_t sb_bad_features2; /* must be padded to 64 bit alignment */ } xfs_sb_t; /* * Superblock - on disk version. Must match the in core version above. * Must be padded to 64 bit alignment. */ typedef struct xfs_dsb { __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ __be32 sb_blocksize; /* logical block size, bytes */ __be64 sb_dblocks; /* number of data blocks */ __be64 sb_rblocks; /* number of realtime blocks */ __be64 sb_rextents; /* number of realtime extents */ uuid_t sb_uuid; /* file system unique id */ __be64 sb_logstart; /* starting block of log if internal */ __be64 sb_rootino; /* root inode number */ __be64 sb_rbmino; /* bitmap inode for realtime extents */ __be64 sb_rsumino; /* summary inode for rt bitmap */ __be32 sb_rextsize; /* realtime extent size, blocks */ __be32 sb_agblocks; /* size of an allocation group */ __be32 sb_agcount; /* number of allocation groups */ __be32 sb_rbmblocks; /* number of rt bitmap blocks */ __be32 sb_logblocks; /* number of log blocks */ __be16 sb_versionnum; /* header version == XFS_SB_VERSION */ __be16 sb_sectsize; /* volume sector size, bytes */ __be16 sb_inodesize; /* inode size, bytes */ __be16 sb_inopblock; /* inodes per block */ char sb_fname[12]; /* file system name */ __u8 sb_blocklog; /* log2 of sb_blocksize */ __u8 sb_sectlog; /* log2 of sb_sectsize */ __u8 sb_inodelog; /* log2 of sb_inodesize */ __u8 sb_inopblog; /* log2 of sb_inopblock */ __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */ __u8 sb_rextslog; /* log2 of sb_rextents */ __u8 sb_inprogress; /* mkfs is in progress, don't mount */ __u8 sb_imax_pct; /* max % of fs for inode space */ /* statistics */ /* * These fields must remain contiguous. If you really * want to change their layout, make sure you fix the * code in xfs_trans_apply_sb_deltas(). */ __be64 sb_icount; /* allocated inodes */ __be64 sb_ifree; /* free inodes */ __be64 sb_fdblocks; /* free data blocks */ __be64 sb_frextents; /* free realtime extents */ /* * End contiguous fields. */ __be64 sb_uquotino; /* user quota inode */ __be64 sb_gquotino; /* group quota inode */ __be16 sb_qflags; /* quota flags */ __u8 sb_flags; /* misc. flags */ __u8 sb_shared_vn; /* shared version number */ __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */ __be32 sb_unit; /* stripe or raid unit */ __be32 sb_width; /* stripe or raid width */ __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */ __u8 sb_logsectlog; /* log2 of the log sector size */ __be16 sb_logsectsize; /* sector size for the log, bytes */ __be32 sb_logsunit; /* stripe unit size for the log */ __be32 sb_features2; /* additional feature bits */ /* * bad features2 field as a result of failing to pad the sb * structure to 64 bits. Some machines will be using this field * for features2 bits. Easiest just to mark it bad and not use * it for anything else. */ __be32 sb_bad_features2; /* must be padded to 64 bit alignment */ } xfs_dsb_t; /* * Sequence number values for the fields. */ typedef enum { XFS_SBS_MAGICNUM, XFS_SBS_BLOCKSIZE, XFS_SBS_DBLOCKS, XFS_SBS_RBLOCKS, XFS_SBS_REXTENTS, XFS_SBS_UUID, XFS_SBS_LOGSTART, XFS_SBS_ROOTINO, XFS_SBS_RBMINO, XFS_SBS_RSUMINO, XFS_SBS_REXTSIZE, XFS_SBS_AGBLOCKS, XFS_SBS_AGCOUNT, XFS_SBS_RBMBLOCKS, XFS_SBS_LOGBLOCKS, XFS_SBS_VERSIONNUM, XFS_SBS_SECTSIZE, XFS_SBS_INODESIZE, XFS_SBS_INOPBLOCK, XFS_SBS_FNAME, XFS_SBS_BLOCKLOG, XFS_SBS_SECTLOG, XFS_SBS_INODELOG, XFS_SBS_INOPBLOG, XFS_SBS_AGBLKLOG, XFS_SBS_REXTSLOG, XFS_SBS_INPROGRESS, XFS_SBS_IMAX_PCT, XFS_SBS_ICOUNT, XFS_SBS_IFREE, XFS_SBS_FDBLOCKS, XFS_SBS_FREXTENTS, XFS_SBS_UQUOTINO, XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG, XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2, XFS_SBS_FIELDCOUNT } xfs_sb_field_t; /* * Mask values, defined based on the xfs_sb_field_t values. * Only define the ones we're using. */ #define XFS_SB_MVAL(x) (1LL << XFS_SBS_ ## x) #define XFS_SB_UUID XFS_SB_MVAL(UUID) #define XFS_SB_FNAME XFS_SB_MVAL(FNAME) #define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO) #define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO) #define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO) #define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM) #define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO) #define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO) #define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS) #define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) #define XFS_SB_UNIT XFS_SB_MVAL(UNIT) #define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) #define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) #define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) #define XFS_SB_MOD_BITS \ (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ XFS_SB_BAD_FEATURES2) /* * Misc. Flags - warning - these will be cleared by xfs_repair unless * a feature bit is set when the flag is used. */ #define XFS_SBF_NOFLAGS 0x00 /* no flags set */ #define XFS_SBF_READONLY 0x01 /* only read-only mounts allowed */ /* * define max. shared version we can interoperate with */ #define XFS_SB_MAX_SHARED_VN 0 #define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS) static inline int xfs_sb_good_version(xfs_sb_t *sbp) { /* We always support version 1-3 */ if (sbp->sb_versionnum >= XFS_SB_VERSION_1 && sbp->sb_versionnum <= XFS_SB_VERSION_3) return 1; /* We support version 4 if all feature bits are supported */ if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) { if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) return 0; #ifdef __KERNEL__ if (sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN) return 0; #else if ((sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) && sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN) return 0; #endif return 1; } return 0; } /* * Detect a mismatched features2 field. Older kernels read/wrote * this into the wrong slot, so to be safe we keep them in sync. */ static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp) { return (sbp->sb_bad_features2 != sbp->sb_features2); } static inline unsigned xfs_sb_version_tonew(unsigned v) { if (v == XFS_SB_VERSION_1) return XFS_SB_VERSION_4; if (v == XFS_SB_VERSION_2) return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT; return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT | XFS_SB_VERSION_NLINKBIT; } static inline unsigned xfs_sb_version_toold(unsigned v) { if (v & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) return 0; if (v & XFS_SB_VERSION_NLINKBIT) return XFS_SB_VERSION_3; if (v & XFS_SB_VERSION_ATTRBIT) return XFS_SB_VERSION_2; return XFS_SB_VERSION_1; } static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) { return sbp->sb_versionnum == XFS_SB_VERSION_2 || sbp->sb_versionnum == XFS_SB_VERSION_3 || (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)); } static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) { if (sbp->sb_versionnum == XFS_SB_VERSION_1) sbp->sb_versionnum = XFS_SB_VERSION_2; else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT; else sbp->sb_versionnum = XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT; } static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) { return sbp->sb_versionnum == XFS_SB_VERSION_3 || (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)); } static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) { if (sbp->sb_versionnum <= XFS_SB_VERSION_2) sbp->sb_versionnum = XFS_SB_VERSION_3; else sbp->sb_versionnum |= XFS_SB_VERSION_NLINKBIT; } static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT); } static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) { if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT; else sbp->sb_versionnum = xfs_sb_version_tonew(sbp->sb_versionnum) | XFS_SB_VERSION_QUOTABIT; } static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT); } static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT); } static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT); } static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT); } static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); } static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); } static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT); } static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT); } static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT); } /* * sb_features2 bit version macros. * * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro: * * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp) * ((xfs_sb_version_hasmorebits(sbp) && * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) */ static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) { return xfs_sb_version_hasmorebits(sbp) && (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT); } static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) { return xfs_sb_version_hasmorebits(sbp) && (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT); } static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) { sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT; } static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp) { sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT; if (!sbp->sb_features2) sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; } static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) { return xfs_sb_version_hasmorebits(sbp) && (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT); } static inline void xfs_sb_version_addprojid32bit(xfs_sb_t *sbp) { sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT; sbp->sb_bad_features2 |= XFS_SB_VERSION2_PROJID32BIT; } /* * end of superblock version macros */ #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) #define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ xfs_daddr_to_agno(mp,d), xfs_daddr_to_agbno(mp,d)) #define XFS_FSB_TO_DADDR(mp,fsbno) XFS_AGB_TO_DADDR(mp, \ XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno)) /* * File system sector to basic block conversions. */ #define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log) /* * File system block to basic block conversions. */ #define XFS_FSB_TO_BB(mp,fsbno) ((fsbno) << (mp)->m_blkbb_log) #define XFS_BB_TO_FSB(mp,bb) \ (((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log) #define XFS_BB_TO_FSBT(mp,bb) ((bb) >> (mp)->m_blkbb_log) #define XFS_BB_FSB_OFFSET(mp,bb) ((bb) & ((mp)->m_bsize - 1)) /* * File system block to byte conversions. */ #define XFS_FSB_TO_B(mp,fsbno) ((xfs_fsize_t)(fsbno) << (mp)->m_sb.sb_blocklog) #define XFS_B_TO_FSB(mp,b) \ ((((__uint64_t)(b)) + (mp)->m_blockmask) >> (mp)->m_sb.sb_blocklog) #define XFS_B_TO_FSBT(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_blocklog) #define XFS_B_FSB_OFFSET(mp,b) ((b) & (mp)->m_blockmask) #endif /* __XFS_SB_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_ialloc_btree.h0000664000000000000000000000633711650373061016727 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_IALLOC_BTREE_H__ #define __XFS_IALLOC_BTREE_H__ /* * Inode map on-disk structures */ struct xfs_buf; struct xfs_btree_cur; struct xfs_mount; /* * There is a btree for the inode map per allocation group. */ #define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ typedef __uint64_t xfs_inofree_t; #define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) #define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) #define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) { return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i; } /* * Data record structure */ typedef struct xfs_inobt_rec { __be32 ir_startino; /* starting inode number */ __be32 ir_freecount; /* count of free inodes (set bits) */ __be64 ir_free; /* free inode mask */ } xfs_inobt_rec_t; typedef struct xfs_inobt_rec_incore { xfs_agino_t ir_startino; /* starting inode number */ __int32_t ir_freecount; /* count of free inodes (set bits) */ xfs_inofree_t ir_free; /* free inode mask */ } xfs_inobt_rec_incore_t; /* * Key structure */ typedef struct xfs_inobt_key { __be32 ir_startino; /* starting inode number */ } xfs_inobt_key_t; /* btree pointer type */ typedef __be32 xfs_inobt_ptr_t; /* * block numbers in the AG. */ #define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) #define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) /* * Btree block header size depends on a superblock flag. * * (not quite yet, but soon) */ #define XFS_INOBT_BLOCK_LEN(mp) XFS_BTREE_SBLOCK_LEN /* * Record, key, and pointer address macros for btree blocks. * * (note that some of these may appear unused, but they are used in userspace) */ #define XFS_INOBT_REC_ADDR(mp, block, index) \ ((xfs_inobt_rec_t *) \ ((char *)(block) + \ XFS_INOBT_BLOCK_LEN(mp) + \ (((index) - 1) * sizeof(xfs_inobt_rec_t)))) #define XFS_INOBT_KEY_ADDR(mp, block, index) \ ((xfs_inobt_key_t *) \ ((char *)(block) + \ XFS_INOBT_BLOCK_LEN(mp) + \ ((index) - 1) * sizeof(xfs_inobt_key_t))) #define XFS_INOBT_PTR_ADDR(mp, block, index, maxrecs) \ ((xfs_inobt_ptr_t *) \ ((char *)(block) + \ XFS_INOBT_BLOCK_LEN(mp) + \ (maxrecs) * sizeof(xfs_inobt_key_t) + \ ((index) - 1) * sizeof(xfs_inobt_ptr_t))) extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t); extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); #endif /* __XFS_IALLOC_BTREE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_log.h0000664000000000000000000001332711650373061015061 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_LOG_H__ #define __XFS_LOG_H__ /* get lsn fields */ #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) #define BLOCK_LSN(lsn) ((uint)(lsn)) /* this is used in a spot where we might otherwise double-endian-flip */ #define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) #ifdef __KERNEL__ /* * By comparing each component, we don't have to worry about extra * endian issues in treating two 32 bit numbers as one 64 bit number */ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) { if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) return (CYCLE_LSN(lsn1) $$d.gz; _sfx=.gz; \ fi; \ u=$$m.$(MAN_SECTION)$$_sfx; \ echo $(INSTALL) -m 644 $${d}$$_sfx $${t}$$_sfx;\ $(INSTALL) -m 644 $${d}$$_sfx $${t}$$_sfx; \ else \ echo $(INSTALL) -S $$u $${t}$$_sfx; \ $(INSTALL) -S $$u $${t}$$_sfx; \ fi; \ first=false; \ done; \ done ifeq ($(ENABLE_GETTEXT),yes) INSTALL_LINGUAS = \ @for l in $(LINGUAS) ""; do \ if test -f "$$l.mo" ; then \ ldir=$(PKG_LOCALE_DIR)/$$l/LC_MESSAGES; \ $(INSTALL) -m 755 -d $$ldir; \ $(INSTALL) -m 644 $$l.mo $$ldir/$(PKG_NAME).mo; \ fi; \ done endif MAN_MAKERULE = \ @for f in *.[12345678] ""; do \ if test ! -z "$$f"; then \ $(ZIP) --best -c < $$f > $$f.gz; \ fi; \ done xfsprogs-3.1.9ubuntu2/include/linux.h0000664000000000000000000000620011650373060014546 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_LINUX_H__ #define __XFS_LINUX_H__ #include #include #include #include #include #include #include #include #include #include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { return ioctl(fd, cmd, p); } static __inline__ int platform_test_xfs_fd(int fd) { struct statfs buf; if (fstatfs(fd, &buf) < 0) return 0; return (buf.f_type == 0x58465342); /* XFSB */ } static __inline__ int platform_test_xfs_path(const char *path) { struct statfs buf; if (statfs(path, &buf) < 0) return 0; return (buf.f_type == 0x58465342); /* XFSB */ } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) { return fstatfs(fd, buf); } static __inline__ void platform_getoptreset(void) { extern int optind; optind = 0; } static __inline__ int platform_uuid_compare(uuid_t *uu1, uuid_t *uu2) { return uuid_compare(*uu1, *uu2); } static __inline__ void platform_uuid_unparse(uuid_t *uu, char *buffer) { uuid_unparse(*uu, buffer); } static __inline__ int platform_uuid_parse(char *buffer, uuid_t *uu) { return uuid_parse(buffer, *uu); } static __inline__ int platform_uuid_is_null(uuid_t *uu) { return uuid_is_null(*uu); } static __inline__ void platform_uuid_generate(uuid_t *uu) { uuid_generate(*uu); } static __inline__ void platform_uuid_clear(uuid_t *uu) { uuid_clear(*uu); } static __inline__ void platform_uuid_copy(uuid_t *dst, uuid_t *src) { uuid_copy(*dst, *src); } #ifndef BLKDISCARD #define BLKDISCARD _IO(0x12,119) #endif static __inline__ int platform_discard_blocks(int fd, uint64_t start, uint64_t len) { __uint64_t range[2] = { start, len }; if (ioctl(fd, BLKDISCARD, &range) < 0) return errno; return 0; } #if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 1)) # define constpp const char * const * #else # define constpp char * const * #endif #define ENOATTR ENODATA /* Attribute not found */ #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ typedef loff_t xfs_off_t; typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; typedef char* xfs_caddr_t; #ifndef _UCHAR_T_DEFINED typedef unsigned char uchar_t; #define _UCHAR_T_DEFINED 1 #endif #ifndef _BOOLEAN_T_DEFINED typedef enum {B_FALSE, B_TRUE} boolean_t; #define _BOOLEAN_T_DEFINED 1 #endif #endif /* __XFS_LINUX_H__ */ xfsprogs-3.1.9ubuntu2/include/libxfs.h0000664000000000000000000005235712062210562014707 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LIBXFS_H__ #define __LIBXFS_H__ #define XFS_BIG_INUMS 1 #define XFS_BIG_BLKNOS 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif #ifndef XFS_SUPER_MAGIC #define XFS_SUPER_MAGIC 0x58465342 #endif #define xfs_isset(a,i) ((a)[(i)/(sizeof((a))*NBBY)] & (1<<((i)%(sizeof((a))*NBBY)))) #define __round_mask(x, y) ((__typeof__(x))((y)-1)) #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) #define round_down(x, y) ((x) & ~__round_mask(x, y)) /* * Argument structure for libxfs_init(). */ typedef struct { /* input parameters */ char *volname; /* pathname of volume */ char *dname; /* pathname of data "subvolume" */ char *logname; /* pathname of log "subvolume" */ char *rtname; /* pathname of realtime "subvolume" */ int isreadonly; /* filesystem is only read in applic */ int isdirect; /* we can attempt to use direct I/O */ int disfile; /* data "subvolume" is a regular file */ int dcreat; /* try to create data subvolume */ int lisfile; /* log "subvolume" is a regular file */ int lcreat; /* try to create log subvolume */ int risfile; /* realtime "subvolume" is a reg file */ int rcreat; /* try to create realtime subvolume */ int setblksize; /* attempt to set device blksize */ int usebuflock; /* lock xfs_buf_t's - for MT usage */ /* output results */ dev_t ddev; /* device for data subvolume */ dev_t logdev; /* device for log subvolume */ dev_t rtdev; /* device for realtime subvolume */ long long dsize; /* size of data subvolume (BBs) */ long long logBBsize; /* size of log subvolume (BBs) */ /* (blocks allocated for use as * log is stored in mount structure) */ long long logBBstart; /* start block of log subvolume (BBs) */ long long rtsize; /* size of realtime subvolume (BBs) */ int dbsize; /* data subvolume device blksize */ int lbsize; /* log subvolume device blksize */ int rtbsize; /* realtime subvolume device blksize */ int dfd; /* data subvolume file descriptor */ int logfd; /* log subvolume file descriptor */ int rtfd; /* realtime subvolume file descriptor */ } libxfs_init_t; #define LIBXFS_EXIT_ON_FAILURE 0x0001 /* exit the program if a call fails */ #define LIBXFS_ISREADONLY 0x0002 /* disallow all mounted filesystems */ #define LIBXFS_ISINACTIVE 0x0004 /* allow mounted only if mounted ro */ #define LIBXFS_DANGEROUSLY 0x0008 /* repairing a device mounted ro */ #define LIBXFS_EXCLUSIVELY 0x0010 /* disallow other accesses (O_EXCL) */ #define LIBXFS_DIRECT 0x0020 /* can use direct I/O, not buffered */ extern char *progname; extern int libxfs_init (libxfs_init_t *); extern void libxfs_destroy (void); extern int libxfs_device_to_fd (dev_t); extern dev_t libxfs_device_open (char *, int, int, int); extern void libxfs_device_zero (dev_t, xfs_daddr_t, uint); extern void libxfs_device_close (dev_t); extern int libxfs_device_alignment (void); extern void libxfs_report(FILE *); extern void platform_findsizes(char *path, int fd, long long *sz, int *bsz); /* check or write log footer: specify device, log size in blocks & uuid */ typedef xfs_caddr_t (libxfs_get_block_t)(xfs_caddr_t, int, void *); extern int libxfs_log_clear (dev_t, xfs_daddr_t, uint, uuid_t *, int, int, int); extern int libxfs_log_header (xfs_caddr_t, uuid_t *, int, int, int, libxfs_get_block_t *, void *); /* * Define a user-level mount structure with all we need * in order to make use of the numerous XFS_* macros. */ typedef struct xfs_mount { xfs_sb_t m_sb; /* copy of fs superblock */ char *m_fsname; /* filesystem name */ int m_bsize; /* fs logical block size */ xfs_agnumber_t m_agfrotor; /* last ag where space found */ xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ xfs_agnumber_t m_maxagi; /* highest inode alloc group */ uint m_rsumlevels; /* rt summary levels */ uint m_rsumsize; /* size of rt summary, bytes */ struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ struct xfs_inode *m_rsumip; /* pointer to summary inode */ struct xfs_inode *m_rootip; /* pointer to root directory */ dev_t m_dev; dev_t m_logdev; dev_t m_rtdev; __uint8_t m_dircook_elog; /* log d-cookie entry bits */ __uint8_t m_blkbit_log; /* blocklog + NBBY */ __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ __uint8_t m_sectbb_log; /* sectorlog - BBSHIFT */ __uint8_t m_agno_log; /* log #ag's */ __uint8_t m_agino_log; /* #bits for agino in inum */ __uint16_t m_inode_cluster_size;/* min inode buf size */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwmask; /* blockwsize-1 */ uint m_alloc_mxr[2]; /* XFS_ALLOC_BLOCK_MAXRECS */ uint m_alloc_mnr[2]; /* XFS_ALLOC_BLOCK_MINRECS */ uint m_bmap_dmxr[2]; /* XFS_BMAP_BLOCK_DMAXRECS */ uint m_bmap_dmnr[2]; /* XFS_BMAP_BLOCK_DMINRECS */ uint m_inobt_mxr[2]; /* XFS_INOBT_BLOCK_MAXRECS */ uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ struct radix_tree_root m_perag_tree; uint m_flags; /* global mount flags */ uint m_qflags; /* quota status flags */ uint m_attroffset; /* inode attribute offset */ uint m_dir_node_ents; /* #entries in a dir danode */ uint m_attr_node_ents; /* #entries in attr danode */ int m_ialloc_inos; /* inodes in inode allocation */ int m_ialloc_blks; /* blocks in inode allocation */ int m_litino; /* size of inode union area */ int m_inoalign_mask;/* mask sb_inoalignmt if used */ xfs_trans_reservations_t m_reservations;/* precomputed res values */ __uint64_t m_maxicount; /* maximum inode count */ int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ int m_sinoalign; /* stripe unit inode alignmnt */ int m_attr_magicpct;/* 37% of the blocksize */ int m_dir_magicpct; /* 37% of the dir blocksize */ const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ int m_dirblksize; /* directory block sz--bytes */ int m_dirblkfsbs; /* directory block sz--fsbs */ xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ } xfs_mount_t; #define LIBXFS_MOUNT_ROOTINOS 0x0001 #define LIBXFS_MOUNT_DEBUGGER 0x0002 #define LIBXFS_MOUNT_32BITINODES 0x0004 #define LIBXFS_MOUNT_32BITINOOPT 0x0008 #define LIBXFS_MOUNT_COMPAT_ATTR 0x0010 #define LIBXFS_MOUNT_ATTR2 0x0020 #define LIBXFS_IHASHSIZE(sbp) (1<<10) #define LIBXFS_BHASHSIZE(sbp) (1<<10) extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *, dev_t, dev_t, dev_t, int); extern void libxfs_umount (xfs_mount_t *); extern void libxfs_rtmount_destroy (xfs_mount_t *); /* * Simple I/O interface */ typedef struct xfs_buf { struct cache_node b_node; unsigned int b_flags; xfs_daddr_t b_blkno; unsigned b_bcount; dev_t b_dev; pthread_mutex_t b_lock; pthread_t b_holder; unsigned int b_recur; void *b_fsprivate; void *b_fsprivate2; void *b_fsprivate3; char *b_addr; int b_error; #ifdef XFS_BUF_TRACING struct list_head b_lock_list; const char *b_func; const char *b_file; int b_line; #endif } xfs_buf_t; enum xfs_buf_flags_t { /* b_flags bits */ LIBXFS_B_EXIT = 0x0001, /* ==LIBXFS_EXIT_ON_FAILURE */ LIBXFS_B_DIRTY = 0x0002, /* buffer has been modified */ LIBXFS_B_STALE = 0x0004, /* buffer marked as invalid */ LIBXFS_B_UPTODATE = 0x0008 /* buffer is sync'd to disk */ }; #define XFS_BUF_PTR(bp) ((bp)->b_addr) #define xfs_buf_offset(bp, offset) (XFS_BUF_PTR(bp) + (offset)) #define XFS_BUF_ADDR(bp) ((bp)->b_blkno) #define XFS_BUF_SIZE(bp) ((bp)->b_bcount) #define XFS_BUF_COUNT(bp) ((bp)->b_bcount) #define XFS_BUF_TARGET(bp) ((bp)->b_dev) #define XFS_BUF_SET_PTR(bp,p,cnt) ({ \ (bp)->b_addr = (char *)(p); \ XFS_BUF_SET_COUNT(bp,cnt); \ }) #define XFS_BUF_SET_ADDR(bp,blk) ((bp)->b_blkno = (blk)) #define XFS_BUF_SET_COUNT(bp,cnt) ((bp)->b_bcount = (cnt)) #define XFS_BUF_FSPRIVATE(bp,type) ((type)(bp)->b_fsprivate) #define XFS_BUF_SET_FSPRIVATE(bp,val) (bp)->b_fsprivate = (void *)(val) #define XFS_BUF_FSPRIVATE2(bp,type) ((type)(bp)->b_fsprivate2) #define XFS_BUF_SET_FSPRIVATE2(bp,val) (bp)->b_fsprivate2 = (void *)(val) #define XFS_BUF_FSPRIVATE3(bp,type) ((type)(bp)->b_fsprivate3) #define XFS_BUF_SET_FSPRIVATE3(bp,val) (bp)->b_fsprivate3 = (void *)(val) #define XFS_BUF_SET_PRIORITY(bp,pri) cache_node_set_priority( \ libxfs_bcache, \ (struct cache_node *)(bp), \ (pri)) #define XFS_BUF_PRIORITY(bp) (cache_node_get_priority( \ (struct cache_node *)(bp))) /* Buffer Cache Interfaces */ extern struct cache *libxfs_bcache; extern struct cache_operations libxfs_bcache_operations; #define LIBXFS_GETBUF_TRYLOCK (1 << 0) #ifdef XFS_BUF_TRACING #define libxfs_readbuf(dev, daddr, len, flags) \ libxfs_trace_readbuf(__FUNCTION__, __FILE__, __LINE__, \ (dev), (daddr), (len), (flags)) #define libxfs_writebuf(buf, flags) \ libxfs_trace_writebuf(__FUNCTION__, __FILE__, __LINE__, \ (buf), (flags)) #define libxfs_getbuf(dev, daddr, len) \ libxfs_trace_getbuf(__FUNCTION__, __FILE__, __LINE__, \ (dev), (daddr), (len)) #define libxfs_getbuf_flags(dev, daddr, len, flags) \ libxfs_trace_getbuf(__FUNCTION__, __FILE__, __LINE__, \ (dev), (daddr), (len), (flags)) #define libxfs_putbuf(buf) \ libxfs_trace_putbuf(__FUNCTION__, __FILE__, __LINE__, (buf)) extern xfs_buf_t *libxfs_trace_readbuf(const char *, const char *, int, dev_t, xfs_daddr_t, int, int); extern int libxfs_trace_writebuf(const char *, const char *, int, xfs_buf_t *, int); extern xfs_buf_t *libxfs_trace_getbuf(const char *, const char *, int, dev_t, xfs_daddr_t, int); extern xfs_buf_t *libxfs_trace_getbuf_flags(const char *, const char *, int, dev_t, xfs_daddr_t, int, unsigned int); extern void libxfs_trace_putbuf (const char *, const char *, int, xfs_buf_t *); #else extern xfs_buf_t *libxfs_readbuf(dev_t, xfs_daddr_t, int, int); extern int libxfs_writebuf(xfs_buf_t *, int); extern xfs_buf_t *libxfs_getbuf(dev_t, xfs_daddr_t, int); extern xfs_buf_t *libxfs_getbuf_flags(dev_t, xfs_daddr_t, int, unsigned int); extern void libxfs_putbuf (xfs_buf_t *); #endif extern xfs_buf_t *libxfs_getsb(xfs_mount_t *, int); extern void libxfs_bcache_purge(void); extern void libxfs_bcache_flush(void); extern void libxfs_purgebuf(xfs_buf_t *); extern int libxfs_bcache_overflowed(void); extern int libxfs_bcache_usage(void); /* Buffer (Raw) Interfaces */ extern xfs_buf_t *libxfs_getbufr(dev_t, xfs_daddr_t, int); extern void libxfs_putbufr(xfs_buf_t *); extern int libxfs_writebuf_int(xfs_buf_t *, int); extern int libxfs_readbufr(dev_t, xfs_daddr_t, xfs_buf_t *, int, int); extern int libxfs_bhash_size; extern int libxfs_ihash_size; #define LIBXFS_BREAD 0x1 #define LIBXFS_BWRITE 0x2 #define LIBXFS_BZERO 0x4 extern void libxfs_iomove (xfs_buf_t *, uint, int, void *, int); /* * Transaction interface */ typedef struct xfs_log_item { struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ struct xfs_mount *li_mountp; /* ptr to fs mount */ uint li_type; /* item type */ } xfs_log_item_t; typedef struct xfs_inode_log_item { xfs_log_item_t ili_item; /* common portion */ struct xfs_inode *ili_inode; /* inode pointer */ unsigned short ili_flags; /* misc flags */ unsigned int ili_last_fields; /* fields when flushed*/ xfs_inode_log_format_t ili_format; /* logged structure */ int ili_lock_flags; } xfs_inode_log_item_t; typedef struct xfs_buf_log_item { xfs_log_item_t bli_item; /* common item structure */ struct xfs_buf *bli_buf; /* real buffer pointer */ unsigned int bli_flags; /* misc flags */ unsigned int bli_recur; /* recursion count */ xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; #include typedef struct xfs_trans { unsigned int t_type; /* transaction type */ unsigned int t_log_res; /* amt of log space resvd */ unsigned int t_log_count; /* count for perm log res */ xfs_mount_t *t_mountp; /* ptr to fs mount struct */ unsigned int t_flags; /* misc flags */ long t_icount_delta; /* superblock icount change */ long t_ifree_delta; /* superblock ifree change */ long t_fdblocks_delta; /* superblock fdblocks chg */ long t_frextents_delta; /* superblock freextents chg */ struct list_head t_items; /* first log item desc chunk */ } xfs_trans_t; extern xfs_trans_t *libxfs_trans_alloc (xfs_mount_t *, int); extern xfs_trans_t *libxfs_trans_dup (xfs_trans_t *); extern int libxfs_trans_reserve (xfs_trans_t *, uint,uint,uint,uint,uint); extern int libxfs_trans_commit (xfs_trans_t *, uint); extern void libxfs_trans_cancel (xfs_trans_t *, int); extern void libxfs_mod_sb (xfs_trans_t *, __int64_t); extern xfs_buf_t *libxfs_trans_getsb (xfs_trans_t *, xfs_mount_t *, int); extern int libxfs_trans_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, uint, uint, struct xfs_inode **); extern void libxfs_trans_iput(xfs_trans_t *, struct xfs_inode *, uint); extern void libxfs_trans_ijoin (xfs_trans_t *, struct xfs_inode *, uint); extern void libxfs_trans_ihold (xfs_trans_t *, struct xfs_inode *); extern void libxfs_trans_ijoin_ref(xfs_trans_t *, struct xfs_inode *, int); extern void libxfs_trans_log_inode (xfs_trans_t *, struct xfs_inode *, uint); extern void libxfs_trans_brelse (xfs_trans_t *, struct xfs_buf *); extern void libxfs_trans_binval (xfs_trans_t *, struct xfs_buf *); extern void libxfs_trans_bjoin (xfs_trans_t *, struct xfs_buf *); extern void libxfs_trans_bhold (xfs_trans_t *, struct xfs_buf *); extern void libxfs_trans_log_buf (xfs_trans_t *, struct xfs_buf *, uint, uint); extern xfs_buf_t *libxfs_trans_get_buf (xfs_trans_t *, dev_t, xfs_daddr_t, int, uint); extern int libxfs_trans_read_buf (xfs_mount_t *, xfs_trans_t *, dev_t, xfs_daddr_t, int, uint, struct xfs_buf **); /* * Inode interface */ typedef struct xfs_inode { struct cache_node i_node; xfs_mount_t *i_mount; /* fs mount struct ptr */ xfs_ino_t i_ino; /* inode number (agno/agino) */ struct xfs_imap i_imap; /* location for xfs_imap() */ dev_t i_dev; /* dev for this inode */ xfs_ifork_t *i_afp; /* attribute fork pointer */ xfs_ifork_t i_df; /* data fork */ xfs_trans_t *i_transp; /* ptr to owning transaction */ xfs_inode_log_item_t *i_itemp; /* logging information */ unsigned int i_delayed_blks; /* count of delay alloc blks */ xfs_icdinode_t i_d; /* most of ondisk inode */ xfs_fsize_t i_size; /* in-memory size */ } xfs_inode_t; #define LIBXFS_ATTR_ROOT 0x0002 /* use attrs in root namespace */ #define LIBXFS_ATTR_SECURE 0x0008 /* use attrs in security namespace */ #define LIBXFS_ATTR_CREATE 0x0010 /* create, but fail if attr exists */ #define LIBXFS_ATTR_REPLACE 0x0020 /* set, but fail if attr not exists */ typedef struct cred { uid_t cr_uid; gid_t cr_gid; } cred_t; extern int libxfs_inode_alloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t, xfs_dev_t, struct cred *, struct fsxattr *, xfs_inode_t **); extern void libxfs_trans_inode_alloc_buf (xfs_trans_t *, xfs_buf_t *); extern void libxfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); extern int libxfs_iflush_int (xfs_inode_t *, xfs_buf_t *); extern int libxfs_iread (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_inode_t *, xfs_daddr_t); /* Inode Cache Interfaces */ extern struct cache *libxfs_icache; extern struct cache_operations libxfs_icache_operations; extern void libxfs_icache_purge (void); extern int libxfs_iget (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, uint, xfs_inode_t **, xfs_daddr_t); extern void libxfs_iput (xfs_inode_t *, uint); extern int xfs_imap_to_bp(xfs_mount_t *mp, xfs_trans_t *tp, struct xfs_imap *imap, xfs_buf_t **bpp, uint buf_flags, uint iget_flags); #include /* dirv1 support in db & repair */ #include #include #include #include /* Shared utility routines */ extern unsigned int libxfs_log2_roundup(unsigned int i); extern int libxfs_alloc_file_space (xfs_inode_t *, xfs_off_t, xfs_off_t, int, int); extern int libxfs_bmap_finish(xfs_trans_t **, xfs_bmap_free_t *, int *); extern void libxfs_da_bjoin (xfs_trans_t *, xfs_dabuf_t *); extern void libxfs_da_bhold (xfs_trans_t *, xfs_dabuf_t *); extern int libxfs_da_read_bufr(xfs_trans_t *, xfs_inode_t *, xfs_dablk_t, xfs_daddr_t, xfs_dabuf_t **, int); extern void libxfs_fs_repair_cmn_err(int, struct xfs_mount *, char *, ...); extern void libxfs_fs_cmn_err(int, struct xfs_mount *, char *, ...); extern void cmn_err(int, char *, ...); enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC }; #define LIBXFS_BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT) extern int libxfs_nproc(void); extern unsigned long libxfs_physmem(void); /* in kilobytes */ #include #include #include #include #include #include #include #define XFS_INOBT_IS_FREE_DISK(rp,i) \ ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) /* * public xfs kernel routines to be called as libxfs_* */ /* xfs_alloc.c */ int libxfs_alloc_fix_freelist(xfs_alloc_arg_t *, int); /* xfs_attr.c */ int libxfs_attr_get(struct xfs_inode *, const unsigned char *, unsigned char *, int *, int); int libxfs_attr_set(struct xfs_inode *, const unsigned char *, unsigned char *, int, int); int libxfs_attr_remove(struct xfs_inode *, const unsigned char *, int); /* xfs_bmap.c */ xfs_bmbt_rec_host_t *xfs_bmap_search_extents(xfs_inode_t *, xfs_fileoff_t, int, int *, xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); /* xfs_attr_leaf.h */ #define libxfs_attr_leaf_newentsize xfs_attr_leaf_newentsize /* xfs_bit.h */ #define libxfs_highbit32 xfs_highbit32 #define libxfs_highbit64 xfs_highbit64 /* xfs_bmap.h */ #define libxfs_bmap_cancel xfs_bmap_cancel #define libxfs_bmap_last_offset xfs_bmap_last_offset #define libxfs_bmapi xfs_bmapi #define libxfs_bunmapi xfs_bunmapi /* xfs_bmap_btree.h */ #define libxfs_bmbt_disk_get_all xfs_bmbt_disk_get_all /* xfs_da_btree.h */ #define libxfs_da_brelse xfs_da_brelse #define libxfs_da_hashname xfs_da_hashname #define libxfs_da_shrink_inode xfs_da_shrink_inode /* xfs_dir2.h */ #define libxfs_dir_createname xfs_dir_createname #define libxfs_dir_init xfs_dir_init #define libxfs_dir_lookup xfs_dir_lookup #define libxfs_dir_replace xfs_dir_replace #define libxfs_dir2_isblock xfs_dir2_isblock #define libxfs_dir2_isleaf xfs_dir2_isleaf /* xfs_dir2_data.h */ #define libxfs_dir2_data_freescan xfs_dir2_data_freescan #define libxfs_dir2_data_log_entry xfs_dir2_data_log_entry #define libxfs_dir2_data_log_header xfs_dir2_data_log_header #define libxfs_dir2_data_make_free xfs_dir2_data_make_free #define libxfs_dir2_data_use_free xfs_dir2_data_use_free #define libxfs_dir2_shrink_inode xfs_dir2_shrink_inode /* xfs_inode.h */ #define libxfs_dinode_from_disk xfs_dinode_from_disk #define libxfs_dinode_to_disk xfs_dinode_to_disk #define libxfs_idata_realloc xfs_idata_realloc #define libxfs_idestroy_fork xfs_idestroy_fork /* xfs_mount.h */ #define libxfs_mod_sb xfs_mod_sb #define libxfs_sb_from_disk xfs_sb_from_disk #define libxfs_sb_to_disk xfs_sb_to_disk /* xfs_rtalloc.c */ int libxfs_rtfree_extent(struct xfs_trans *, xfs_rtblock_t, xfs_extlen_t); #endif /* __LIBXFS_H__ */ xfsprogs-3.1.9ubuntu2/include/bitops.h0000664000000000000000000000123011140033220014666 0ustar #ifndef __BITOPS_H__ #define __BITOPS_H__ /* * fls: find last bit set. */ static inline int fls(int x) { int r = 32; if (!x) return 0; if (!(x & 0xffff0000u)) { x <<= 16; r -= 16; } if (!(x & 0xff000000u)) { x <<= 8; r -= 8; } if (!(x & 0xf0000000u)) { x <<= 4; r -= 4; } if (!(x & 0xc0000000u)) { x <<= 2; r -= 2; } if (!(x & 0x80000000u)) { x <<= 1; r -= 1; } return r; } static inline int fls64(__u64 x) { __u32 h = x >> 32; if (h) return fls(h) + 32; return fls(x); } static inline unsigned fls_long(unsigned long l) { if (sizeof(l) == 4) return fls(l); return fls64(l); } #endif xfsprogs-3.1.9ubuntu2/include/xfs_attr_leaf.h0000664000000000000000000002461411650373060016241 0ustar /* * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_ATTR_LEAF_H__ #define __XFS_ATTR_LEAF_H__ /* * Attribute storage layout, internal structure, access macros, etc. * * Attribute lists are structured around Btrees where all the data * elements are in the leaf nodes. Attribute names are hashed into an int, * then that int is used as the index into the Btree. Since the hashval * of an attribute name may not be unique, we may have duplicate keys. The * internal links in the Btree are logical block offsets into the file. */ struct attrlist; struct attrlist_cursor_kern; struct xfs_attr_list_context; struct xfs_dabuf; struct xfs_da_args; struct xfs_da_state; struct xfs_da_state_blk; struct xfs_inode; struct xfs_trans; /*======================================================================== * Attribute structure when equal to XFS_LBSIZE(mp) bytes. *========================================================================*/ /* * This is the structure of the leaf nodes in the Btree. * * Struct leaf_entry's are packed from the top. Name/values grow from the * bottom but are not packed. The freemap contains run-length-encoded entries * for the free bytes after the leaf_entry's, but only the N largest such, * smaller runs are dropped. When the freemap doesn't show enough space * for an allocation, we compact the name/value area and try again. If we * still don't have enough space, then we have to split the block. The * name/value structs (both local and remote versions) must be 32bit aligned. * * Since we have duplicate hash keys, for each key that matches, compare * the actual name string. The root and intermediate node search always * takes the first-in-the-block key match found, so we should only have * to work "forw"ard. If none matches, continue with the "forw"ard leaf * nodes until the hash key changes or the attribute name is found. * * We store the fact that an attribute is a ROOT/USER/SECURE attribute in * the leaf_entry. The namespaces are independent only because we also look * at the namespace bit when we are looking for a matching attribute name. * * We also store an "incomplete" bit in the leaf_entry. It shows that an * attribute is in the middle of being created and should not be shown to * the user if we crash during the time that the bit is set. We clear the * bit when we have finished setting up the attribute. We do this because * we cannot create some large attributes inside a single transaction, and we * need some indication that we weren't finished if we crash in the middle. */ #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ __be16 base; /* base of free region */ __be16 size; /* length of free region */ } xfs_attr_leaf_map_t; typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ __be16 count; /* count of active leaf_entry's */ __be16 usedbytes; /* num bytes of names/values stored */ __be16 firstused; /* first used byte in name area */ __u8 holes; /* != 0 if blk needs compaction */ __u8 pad1; xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE]; /* N largest free regions */ } xfs_attr_leaf_hdr_t; typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */ __be32 hashval; /* hash value of name */ __be16 nameidx; /* index into buffer of name/value */ __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ __u8 pad2; /* unused pad byte */ } xfs_attr_leaf_entry_t; typedef struct xfs_attr_leaf_name_local { __be16 valuelen; /* number of bytes in value */ __u8 namelen; /* length of name bytes */ __u8 nameval[1]; /* name/value bytes */ } xfs_attr_leaf_name_local_t; typedef struct xfs_attr_leaf_name_remote { __be32 valueblk; /* block number of value bytes */ __be32 valuelen; /* number of bytes in value */ __u8 namelen; /* length of name bytes */ __u8 name[1]; /* name bytes */ } xfs_attr_leaf_name_remote_t; typedef struct xfs_attr_leafblock { xfs_attr_leaf_hdr_t hdr; /* constant-structure header block */ xfs_attr_leaf_entry_t entries[1]; /* sorted on key, not name */ xfs_attr_leaf_name_local_t namelist; /* grows from bottom of buf */ xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */ } xfs_attr_leafblock_t; /* * Flags used in the leaf_entry[i].flags field. * NOTE: the INCOMPLETE bit must not collide with the flags bits specified * on the system call, they are "or"ed together for various operations. */ #define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ #define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ #define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ #define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ #define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) #define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) #define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) /* * Conversion macros for converting namespace bits from argument flags * to ondisk flags. */ #define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) #define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) #define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) #define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) #define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) #define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) /* * Alignment for namelist and valuelist entries (since they are mixed * there can be only one alignment value) */ #define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t)) /* * Cast typed pointers for "local" and "remote" name/value structs. */ static inline xfs_attr_leaf_name_remote_t * xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { return (xfs_attr_leaf_name_remote_t *) &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } static inline xfs_attr_leaf_name_local_t * xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) { return (xfs_attr_leaf_name_local_t *) &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) { return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } /* * Calculate total bytes used (including trailing pad for alignment) for * a "local" name/value structure, a "remote" name/value structure, and * a pointer which might be either. */ static inline int xfs_attr_leaf_entsize_remote(int nlen) { return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \ XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); } static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen) { return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) + XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); } static inline int xfs_attr_leaf_entsize_local_max(int bsize) { return (((bsize) >> 1) + ((bsize) >> 2)); } /* * Used to keep a list of "remote value" extents when unlinking an inode. */ typedef struct xfs_attr_inactive_list { xfs_dablk_t valueblk; /* block number of value bytes */ int valuelen; /* number of bytes in value */ } xfs_attr_inactive_list_t; /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ /* * Internal routines when attribute fork size < XFS_LITINO(mp). */ void xfs_attr_shortform_create(struct xfs_da_args *args); void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); int xfs_attr_shortform_lookup(struct xfs_da_args *args); int xfs_attr_shortform_getvalue(struct xfs_da_args *args); int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); int xfs_attr_shortform_remove(struct xfs_da_args *args); int xfs_attr_shortform_list(struct xfs_attr_list_context *context); int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp); int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); /* * Internal routines when attribute fork size == XFS_LBSIZE(mp). */ int xfs_attr_leaf_to_node(struct xfs_da_args *args); int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp, struct xfs_da_args *args, int forkoff); int xfs_attr_leaf_clearflag(struct xfs_da_args *args); int xfs_attr_leaf_setflag(struct xfs_da_args *args); int xfs_attr_leaf_flipflags(xfs_da_args_t *args); /* * Routines used for growing the Btree. */ int xfs_attr_leaf_split(struct xfs_da_state *state, struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); int xfs_attr_leaf_lookup_int(struct xfs_dabuf *leaf, struct xfs_da_args *args); int xfs_attr_leaf_getvalue(struct xfs_dabuf *bp, struct xfs_da_args *args); int xfs_attr_leaf_add(struct xfs_dabuf *leaf_buffer, struct xfs_da_args *args); int xfs_attr_leaf_remove(struct xfs_dabuf *leaf_buffer, struct xfs_da_args *args); int xfs_attr_leaf_list_int(struct xfs_dabuf *bp, struct xfs_attr_list_context *context); /* * Routines used for shrinking the Btree. */ int xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval); void xfs_attr_leaf_unbalance(struct xfs_da_state *state, struct xfs_da_state_blk *drop_blk, struct xfs_da_state_blk *save_blk); int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); /* * Utility routines. */ xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count); int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp, struct xfs_dabuf *leaf2_bp); int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local); #endif /* __XFS_ATTR_LEAF_H__ */ xfsprogs-3.1.9ubuntu2/include/xqm.h0000664000000000000000000001423311175243422014221 0ustar /* * Copyright (c) 1995, 2001, 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XQM_H__ #define __XQM_H__ #include /* * Disk quota - quotactl(2) commands for the XFS Quota Manager (XQM). */ #define XQM_CMD(x) (('X'<<8)+(x)) /* note: forms first QCMD argument */ #define Q_XQUOTAON XQM_CMD(1) /* enable accounting/enforcement */ #define Q_XQUOTAOFF XQM_CMD(2) /* disable accounting/enforcement */ #define Q_XGETQUOTA XQM_CMD(3) /* get disk limits and usage */ #define Q_XSETQLIM XQM_CMD(4) /* set disk limits */ #define Q_XGETQSTAT XQM_CMD(5) /* get quota subsystem status */ #define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */ #define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */ /* * fs_disk_quota structure: * * This contains the current quota information regarding a user/proj/group. * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of * 512 bytes. */ #define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */ typedef struct fs_disk_quota { __s8 d_version; /* version of this structure */ __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ __u16 d_fieldmask; /* field specifier */ __u32 d_id; /* user, project, or group ID */ __u64 d_blk_hardlimit;/* absolute limit on disk blks */ __u64 d_blk_softlimit;/* preferred limit on disk blks */ __u64 d_ino_hardlimit;/* maximum # allocated inodes */ __u64 d_ino_softlimit;/* preferred inode limit */ __u64 d_bcount; /* # disk blocks owned by the user */ __u64 d_icount; /* # inodes owned by the user */ __s32 d_itimer; /* zero if within inode limits */ /* if not, we refuse service */ __s32 d_btimer; /* similar to above; for disk blocks */ __u16 d_iwarns; /* # warnings issued wrt num inodes */ __u16 d_bwarns; /* # warnings issued wrt disk blocks */ __s32 d_padding2; /* padding2 - for future use */ __u64 d_rtb_hardlimit;/* absolute limit on realtime blks */ __u64 d_rtb_softlimit;/* preferred limit on RT disk blks */ __u64 d_rtbcount; /* # realtime blocks owned */ __s32 d_rtbtimer; /* similar to above; for RT disk blks */ __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */ __s16 d_padding3; /* padding3 - for future use */ char d_padding4[8]; /* yet more padding */ } fs_disk_quota_t; /* * These fields are sent to Q_XSETQLIM to specify fields that need to change. */ #define FS_DQ_ISOFT (1<<0) #define FS_DQ_IHARD (1<<1) #define FS_DQ_BSOFT (1<<2) #define FS_DQ_BHARD (1<<3) #define FS_DQ_RTBSOFT (1<<4) #define FS_DQ_RTBHARD (1<<5) #define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD) /* * These timers can only be set in super user's dquot. For others, timers are * automatically started and stopped. Superusers timer values set the limits * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values * defined below are used. * These values also apply only to the d_fieldmask field for Q_XSETQLIM. */ #define FS_DQ_BTIMER (1<<6) #define FS_DQ_ITIMER (1<<7) #define FS_DQ_RTBTIMER (1<<8) #define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER) /* * Warning counts are set in both super user's dquot and others. For others, * warnings are set/cleared by the administrators (or automatically by going * below the soft limit). Superusers warning values set the warning limits * for the rest. In case these values are zero, the DQ_{F,B}WARNLIMIT values * defined below are used. * These values also apply only to the d_fieldmask field for Q_XSETQLIM. */ #define FS_DQ_BWARNS (1<<9) #define FS_DQ_IWARNS (1<<10) #define FS_DQ_RTBWARNS (1<<11) #define FS_DQ_WARNS_MASK (FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS) /* * Various flags related to quotactl(2). Only relevant to XFS filesystems. */ #define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */ #define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */ #define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */ #define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */ #define XFS_QUOTA_PDQ_ACCT (1<<4) /* project quota accounting */ #define XFS_QUOTA_PDQ_ENFD (1<<5) /* project quota limits enforcement */ #define XFS_USER_QUOTA (1<<0) /* user quota type */ #define XFS_PROJ_QUOTA (1<<1) /* project quota type */ #define XFS_GROUP_QUOTA (1<<2) /* group quota type */ /* * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system. * Provides a centralized way to get meta information about the quota subsystem. * eg. space taken up for user and group quotas, number of dquots currently * incore. */ #define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */ /* * Some basic information about 'quota files'. */ typedef struct fs_qfilestat { __u64 qfs_ino; /* inode number */ __u64 qfs_nblks; /* number of BBs 512-byte-blks */ __u32 qfs_nextents; /* number of extents */ } fs_qfilestat_t; typedef struct fs_quota_stat { __s8 qs_version; /* version number for future changes */ __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */ __s8 qs_pad; /* unused */ fs_qfilestat_t qs_uquota; /* user quota storage information */ fs_qfilestat_t qs_gquota; /* group quota storage information */ __u32 qs_incoredqs; /* number of dquots incore */ __s32 qs_btimelimit; /* limit for blks timer */ __s32 qs_itimelimit; /* limit for inodes timer */ __s32 qs_rtbtimelimit;/* limit for rt blks timer */ __u16 qs_bwarnlimit; /* limit for num warnings */ __u16 qs_iwarnlimit; /* limit for num warnings */ } fs_quota_stat_t; #endif /* __XQM_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2_leaf.h0000664000000000000000000001574011140033220016110 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_LEAF_H__ #define __XFS_DIR2_LEAF_H__ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_inode; struct xfs_mount; struct xfs_trans; /* * Offset of the leaf/node space. First block in this space * is the btree root. */ #define XFS_DIR2_LEAF_SPACE 1 #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_LEAF_FIRSTDB(mp) \ xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET) /* * Offset in data space of a data entry. */ typedef __uint32_t xfs_dir2_dataptr_t; #define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff) #define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0) /* * Leaf block header. */ typedef struct xfs_dir2_leaf_hdr { xfs_da_blkinfo_t info; /* header for da routines */ __be16 count; /* count of entries */ __be16 stale; /* count of stale entries */ } xfs_dir2_leaf_hdr_t; /* * Leaf block entry. */ typedef struct xfs_dir2_leaf_entry { __be32 hashval; /* hash value of name */ __be32 address; /* address of data entry */ } xfs_dir2_leaf_entry_t; /* * Leaf block tail. */ typedef struct xfs_dir2_leaf_tail { __be32 bestcount; } xfs_dir2_leaf_tail_t; /* * Leaf block. * bests and tail are at the end of the block for single-leaf only * (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC). */ typedef struct xfs_dir2_leaf { xfs_dir2_leaf_hdr_t hdr; /* leaf header */ xfs_dir2_leaf_entry_t ents[1]; /* entries */ /* ... */ xfs_dir2_data_off_t bests[1]; /* best free counts */ xfs_dir2_leaf_tail_t tail; /* leaf tail */ } xfs_dir2_leaf_t; /* * DB blocks here are logical directory block numbers, not filesystem blocks. */ static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) { return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / (uint)sizeof(xfs_dir2_leaf_entry_t)); } /* * Get address of the bestcount field in the single-leaf block. */ static inline xfs_dir2_leaf_tail_t * xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) { return (xfs_dir2_leaf_tail_t *) ((char *)(lp) + (mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_tail_t)); } /* * Get address of the bests array in the single-leaf block. */ static inline __be16 * xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) { return (__be16 *)ltp - be32_to_cpu(ltp->bestcount); } /* * Convert dataptr to byte in file space */ static inline xfs_dir2_off_t xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG; } /* * Convert byte in file space to dataptr. It had better be aligned. */ static inline xfs_dir2_dataptr_t xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) { return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG); } /* * Convert byte in space to (DB) block */ static inline xfs_dir2_db_t xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) { return (xfs_dir2_db_t)((by) >> \ ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)); } /* * Convert dataptr to a block number */ static inline xfs_dir2_db_t xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp)); } /* * Convert byte in space to offset in a block */ static inline xfs_dir2_data_aoff_t xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) { return (xfs_dir2_data_aoff_t)((by) & \ ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1)); } /* * Convert dataptr to a byte offset in a block */ static inline xfs_dir2_data_aoff_t xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) { return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp)); } /* * Convert block and offset to byte in space */ static inline xfs_dir2_off_t xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, xfs_dir2_data_aoff_t o) { return ((xfs_dir2_off_t)(db) << \ ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o); } /* * Convert block (DB) to block (dablk) */ static inline xfs_dablk_t xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) { return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog); } /* * Convert byte in space to (DA) block */ static inline xfs_dablk_t xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) { return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by)); } /* * Convert block and offset to dataptr */ static inline xfs_dir2_dataptr_t xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, xfs_dir2_data_aoff_t o) { return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o)); } /* * Convert block (dablk) to block (DB) */ static inline xfs_dir2_db_t xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) { return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog); } /* * Convert block (dablk) to byte offset in space */ static inline xfs_dir2_off_t xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) { return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0); } /* * Function declarations. */ extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, struct xfs_dabuf *dbp); extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, struct xfs_dabuf *bp); extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, size_t bufsize, xfs_off_t *offset, filldir_t filldir); extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, struct xfs_dabuf **bpp, int magic); extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, int first, int last); extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp); extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); extern int xfs_dir2_leaf_replace(struct xfs_da_args *args); extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, struct xfs_dabuf *lbp); extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, struct xfs_dabuf *lbp, xfs_dir2_db_t db); extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); #endif /* __XFS_DIR2_LEAF_H__ */ xfsprogs-3.1.9ubuntu2/include/cache.h0000664000000000000000000001002311140033220014431 0ustar /* * Copyright (c) 2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CACHE_H__ #define __CACHE_H__ #define HASH_CACHE_RATIO 8 /* * Cache priorities range from BASE to MAX. * * For prefetch support, the top half of the range starts at * CACHE_PREFETCH_PRIORITY and everytime the buffer is fetched * and is at or above this priority level, it is reduced to * below this level (refer to libxfs_getbuf). */ #define CACHE_BASE_PRIORITY 0 #define CACHE_PREFETCH_PRIORITY 8 #define CACHE_MAX_PRIORITY 15 /* * Simple, generic implementation of a cache (arbitrary data). * Provides a hash table with a capped number of cache entries. */ struct cache; struct cache_node; typedef void *cache_key_t; typedef void (*cache_walk_t)(struct cache_node *); typedef struct cache_node * (*cache_node_alloc_t)(cache_key_t); typedef void (*cache_node_flush_t)(struct cache_node *); typedef void (*cache_node_relse_t)(struct cache_node *); typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int); typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t); typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *); struct cache_operations { cache_node_hash_t hash; cache_node_alloc_t alloc; cache_node_flush_t flush; cache_node_relse_t relse; cache_node_compare_t compare; cache_bulk_relse_t bulkrelse; /* optional */ }; struct cache_hash { struct list_head ch_list; /* hash chain head */ unsigned int ch_count; /* hash chain length */ pthread_mutex_t ch_mutex; /* hash chain mutex */ }; struct cache_mru { struct list_head cm_list; /* MRU head */ unsigned int cm_count; /* MRU length */ pthread_mutex_t cm_mutex; /* MRU lock */ }; struct cache_node { struct list_head cn_hash; /* hash chain */ struct list_head cn_mru; /* MRU chain */ unsigned int cn_count; /* reference count */ unsigned int cn_hashidx; /* hash chain index */ int cn_priority; /* priority, -1 = free list */ pthread_mutex_t cn_mutex; /* node mutex */ }; struct cache { unsigned int c_maxcount; /* max cache nodes */ unsigned int c_count; /* count of nodes */ pthread_mutex_t c_mutex; /* node count mutex */ cache_node_hash_t hash; /* node hash function */ cache_node_alloc_t alloc; /* allocation function */ cache_node_flush_t flush; /* flush dirty data function */ cache_node_relse_t relse; /* memory free function */ cache_node_compare_t compare; /* comparison routine */ cache_bulk_relse_t bulkrelse; /* bulk release routine */ unsigned int c_hashsize; /* hash bucket count */ struct cache_hash *c_hash; /* hash table buckets */ struct cache_mru c_mrus[CACHE_MAX_PRIORITY + 1]; unsigned long long c_misses; /* cache misses */ unsigned long long c_hits; /* cache hits */ unsigned int c_max; /* max nodes ever used */ }; struct cache *cache_init(unsigned int, struct cache_operations *); void cache_destroy(struct cache *); void cache_walk(struct cache *, cache_walk_t); void cache_purge(struct cache *); void cache_flush(struct cache *); int cache_node_get(struct cache *, cache_key_t, struct cache_node **); void cache_node_put(struct cache *, struct cache_node *); void cache_node_set_priority(struct cache *, struct cache_node *, int); int cache_node_get_priority(struct cache_node *); int cache_node_purge(struct cache *, cache_key_t, struct cache_node *); void cache_report(FILE *fp, const char *, struct cache *); int cache_overflowed(struct cache *); #endif /* __CACHE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_attr_sf.h0000664000000000000000000000541611650373060015741 0ustar /* * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_ATTR_SF_H__ #define __XFS_ATTR_SF_H__ /* * Attribute storage when stored inside the inode. * * Small attribute lists are packed as tightly as possible so as * to fit into the literal area of the inode. */ /* * Entries are packed toward the top as tight as possible. */ typedef struct xfs_attr_shortform { struct xfs_attr_sf_hdr { /* constant-structure header block */ __be16 totsize; /* total bytes in shortform list */ __u8 count; /* count of active entries */ } hdr; struct xfs_attr_sf_entry { __uint8_t namelen; /* actual length of name (no NULL) */ __uint8_t valuelen; /* actual length of value (no NULL) */ __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ __uint8_t nameval[1]; /* name & value bytes concatenated */ } list[1]; /* variable sized array */ } xfs_attr_shortform_t; typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; /* * We generate this then sort it, attr_list() must return things in hash-order. */ typedef struct xfs_attr_sf_sort { __uint8_t entno; /* entry number in original list */ __uint8_t namelen; /* length of name value (no null) */ __uint8_t valuelen; /* length of value */ __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ xfs_dahash_t hash; /* this entry's hash value */ unsigned char *name; /* name value, pointer into buffer */ } xfs_attr_sf_sort_t; #define XFS_ATTR_SF_ENTSIZE_BYNAME(nlen,vlen) /* space name/value uses */ \ (((int)sizeof(xfs_attr_sf_entry_t)-1 + (nlen)+(vlen))) #define XFS_ATTR_SF_ENTSIZE_MAX /* max space for name&value */ \ ((1 << (NBBY*(int)sizeof(__uint8_t))) - 1) #define XFS_ATTR_SF_ENTSIZE(sfep) /* space an entry uses */ \ ((int)sizeof(xfs_attr_sf_entry_t)-1 + (sfep)->namelen+(sfep)->valuelen) #define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \ ((xfs_attr_sf_entry_t *)((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep))) #define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \ (be16_to_cpu(((xfs_attr_shortform_t *) \ ((dp)->i_afp->if_u1.if_data))->hdr.totsize)) #endif /* __XFS_ATTR_SF_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_rtalloc.h0000664000000000000000000001234211650373061015734 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_RTALLOC_H__ #define __XFS_RTALLOC_H__ struct xfs_mount; struct xfs_trans; /* Min and max rt extent sizes, specified in bytes */ #define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ #define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */ #define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */ /* * Constants for bit manipulations. */ #define XFS_NBBYLOG 3 /* log2(NBBY) */ #define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */ #define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG) #define XFS_NBWORD (1 << XFS_NBWORDLOG) #define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) #define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize) #define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) #define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize) #define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask) /* * Summary and bit manipulation macros. */ #define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb))) #define XFS_SUMOFFSTOBLOCK(mp,s) \ (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) #define XFS_SUMPTR(mp,bp,so) \ ((xfs_suminfo_t *)((char *)XFS_BUF_PTR(bp) + \ (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) #define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) #define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log) #define XFS_BITTOWORD(mp,bi) \ ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp))) #define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) #define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) #define XFS_RTLOBIT(w) xfs_lowbit32(w) #define XFS_RTHIBIT(w) xfs_highbit32(w) #if XFS_BIG_BLKNOS #define XFS_RTBLOCKLOG(b) xfs_highbit64(b) #else #define XFS_RTBLOCKLOG(b) xfs_highbit32(b) #endif #ifdef __KERNEL__ #ifdef CONFIG_XFS_RT /* * Function prototypes for exported functions. */ /* * Allocate an extent in the realtime subvolume, with the usual allocation * parameters. The length units are all in realtime extents, as is the * result block number. */ int /* error */ xfs_rtallocate_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to allocate */ xfs_extlen_t minlen, /* minimum length to allocate */ xfs_extlen_t maxlen, /* maximum length to allocate */ xfs_extlen_t *len, /* out: actual length allocated */ xfs_alloctype_t type, /* allocation type XFS_ALLOCTYPE... */ int wasdel, /* was a delayed allocation extent */ xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock); /* out: start block allocated */ /* * Free an extent in the realtime subvolume. Length is expressed in * realtime extents, as is the block number. */ int /* error */ xfs_rtfree_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to free */ xfs_extlen_t len); /* length of extent freed */ /* * Initialize realtime fields in the mount structure. */ int /* error */ xfs_rtmount_init( struct xfs_mount *mp); /* file system mount structure */ void xfs_rtunmount_inodes( struct xfs_mount *mp); /* * Get the bitmap and summary inodes into the mount structure * at mount time. */ int /* error */ xfs_rtmount_inodes( struct xfs_mount *mp); /* file system mount structure */ /* * Pick an extent for allocation at the start of a new realtime file. * Use the sequence number stored in the atime field of the bitmap inode. * Translate this to a fraction of the rtextents, and return the product * of rtextents and the fraction. * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... */ int /* error */ xfs_rtpick_extent( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ xfs_extlen_t len, /* allocation length (rtextents) */ xfs_rtblock_t *pick); /* result rt extent */ /* * Grow the realtime area of the filesystem. */ int xfs_growfs_rt( struct xfs_mount *mp, /* file system mount structure */ xfs_growfs_rt_t *in); /* user supplied growfs struct */ #else # define xfs_rtallocate_extent(t,b,min,max,l,a,f,p,rb) (ENOSYS) # define xfs_rtfree_extent(t,b,l) (ENOSYS) # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) # define xfs_growfs_rt(mp,in) (ENOSYS) static inline int /* error */ xfs_rtmount_init( xfs_mount_t *mp) /* file system mount structure */ { if (mp->m_sb.sb_rblocks == 0) return 0; cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT"); return ENOSYS; } # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) # define xfs_rtunmount_inodes(m) #endif /* CONFIG_XFS_RT */ #endif /* __KERNEL__ */ #endif /* __XFS_RTALLOC_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2.h0000664000000000000000000000676611650373060015150 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_H__ #define __XFS_DIR2_H__ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_dir2_put_args; struct xfs_bmap_free; struct xfs_inode; struct xfs_mount; struct xfs_trans; /* * Directory version 2. * There are 4 possible formats: * shortform * single block - data with embedded leaf at the end * multiple data blocks, single leaf+freeindex block * data blocks, node&leaf blocks (btree), freeindex blocks * * The shortform format is in xfs_dir2_sf.h. * The single block format is in xfs_dir2_block.h. * The data block format is in xfs_dir2_data.h. * The leaf and freeindex block formats are in xfs_dir2_leaf.h. * Node blocks are the same as the other version, in xfs_da_btree.h. */ /* * Byte offset in data block and shortform entry. */ typedef __uint16_t xfs_dir2_data_off_t; #define NULLDATAOFF 0xffffU typedef uint xfs_dir2_data_aoff_t; /* argument form */ /* * Directory block number (logical dirblk in file) */ typedef __uint32_t xfs_dir2_db_t; /* * Byte offset in a directory. */ typedef xfs_off_t xfs_dir2_off_t; extern struct xfs_name xfs_name_dotdot; /* * Generic directory interface routines */ extern void xfs_dir_startup(void); extern void xfs_dir_mount(struct xfs_mount *mp); extern int xfs_dir_isempty(struct xfs_inode *dp); extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_inode *pdp); extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, xfs_fsblock_t *first, struct xfs_bmap_free *flist, xfs_extlen_t tot); extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t *inum, struct xfs_name *ci_name); extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, xfs_fsblock_t *first, struct xfs_bmap_free *flist, xfs_extlen_t tot); extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, xfs_fsblock_t *first, struct xfs_bmap_free *flist, xfs_extlen_t tot); extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, uint resblks); extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); /* * Utility routines for v2 directories. */ extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, xfs_dir2_db_t *dbp); extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *vp); extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *vp); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_dabuf *bp); extern int xfs_dir_cilookup_result(struct xfs_da_args *args, const unsigned char *name, int len); #endif /* __XFS_DIR2_H__ */ xfsprogs-3.1.9ubuntu2/include/radix-tree.h0000664000000000000000000000506411650373060015462 0ustar /* * Copyright (C) 2001 Momchil Velikov * Portions Copyright (C) 2001 Christoph Hellwig * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XFS_SUPPORT_RADIX_TREE_H__ #define __XFS_SUPPORT_RADIX_TREE_H__ #define RADIX_TREE_TAGS struct radix_tree_root { unsigned int height; struct radix_tree_node *rnode; }; #define RADIX_TREE_INIT(mask) { \ .height = 0, \ .rnode = NULL, \ } #define RADIX_TREE(name, mask) \ struct radix_tree_root name = RADIX_TREE_INIT(mask) #define INIT_RADIX_TREE(root, mask) \ do { \ (root)->height = 0; \ (root)->rnode = NULL; \ } while (0) #ifdef RADIX_TREE_TAGS #define RADIX_TREE_MAX_TAGS 2 #endif int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); void *radix_tree_lookup(struct radix_tree_root *, unsigned long); void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); void *radix_tree_lookup_first(struct radix_tree_root *, unsigned long *); void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); unsigned int radix_tree_gang_lookup_ex(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned long last_index, unsigned int max_items); void radix_tree_init(void); #ifdef RADIX_TREE_TAGS void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, unsigned int tag); void *radix_tree_tag_clear(struct radix_tree_root *root, unsigned long index, unsigned int tag); int radix_tree_tag_get(struct radix_tree_root *root, unsigned long index, unsigned int tag); unsigned int radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag); int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); #endif #endif /* __XFS_SUPPORT_RADIX_TREE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir_sf.h0000664000000000000000000000607011140033220015523 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR_SF_H__ #define __XFS_DIR_SF_H__ /* * Directory layout when stored internal to an inode. * * Small directories are packed as tightly as possible so as to * fit into the literal area of the inode. */ typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; /* * The parent directory has a dedicated field, and the self-pointer must * be calculated on the fly. * * Entries are packed toward the top as tight as possible. The header * and the elements much be memcpy'd out into a work area to get correct * alignment for the inode number fields. */ typedef struct xfs_dir_sf_hdr { /* constant-structure header block */ xfs_dir_ino_t parent; /* parent dir inode number */ __u8 count; /* count of active entries */ } xfs_dir_sf_hdr_t; typedef struct xfs_dir_sf_entry { xfs_dir_ino_t inumber; /* referenced inode number */ __u8 namelen; /* actual length of name (no NULL) */ __u8 name[1]; /* name */ } xfs_dir_sf_entry_t; typedef struct xfs_dir_shortform { xfs_dir_sf_hdr_t hdr; xfs_dir_sf_entry_t list[1]; /* variable sized array */ } xfs_dir_shortform_t; /* * We generate this then sort it, so that readdirs are returned in * hash-order. Else seekdir won't work. */ typedef struct xfs_dir_sf_sort { __u8 entno; /* .=0, ..=1, else entry# + 2 */ __u8 seqno; /* sequence # with same hash value */ __u8 namelen; /* length of name value (no null) */ __be32 hash; /* this entry's hash value */ xfs_intino_t ino; /* this entry's inode number */ __u8 *name; /* name value, pointer into buffer */ } xfs_dir_sf_sort_t; static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) { *to = XFS_GET_DIR_INO8(*from); } static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) { XFS_PUT_DIR_INO8(*from, *to); } static inline int xfs_dir_sf_entsize_byname(int len) { return sizeof(xfs_dir_sf_entry_t) - 1 + len; } static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) { return sizeof(xfs_dir_sf_entry_t) - 1 + sfep->namelen; } static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) { return (xfs_dir_sf_entry_t *)((char *)sfep + xfs_dir_sf_entsize_byentry(sfep)); } static inline int xfs_dir_sf_allfit(int count, int totallen) { return sizeof(xfs_dir_sf_hdr_t) + (sizeof(xfs_dir_sf_entry_t) - 1) * count + totallen; } #endif /* __XFS_DIR_SF_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_ialloc.h0000664000000000000000000001222111650373061015533 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_IALLOC_H__ #define __XFS_IALLOC_H__ struct xfs_buf; struct xfs_dinode; struct xfs_imap; struct xfs_mount; struct xfs_trans; /* * Allocation parameters for inode allocation. */ #define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks /* * Move inodes in clusters of this size. */ #define XFS_INODE_BIG_CLUSTER_SIZE 8192 #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size /* * Make an inode pointer out of the buffer/offset. */ static inline struct xfs_dinode * xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) { return (xfs_dinode_t *) (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog)); } /* * Find a free (set) bit in the inode bitmask. */ static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) { return xfs_lowbit64(*fp); } /* * Allocate an inode on disk. * Mode is used to tell whether the new inode will need space, and whether * it is a directory. * * To work within the constraint of one allocation per transaction, * xfs_dialloc() is designed to be called twice if it has to do an * allocation to make more free inodes. If an inode is * available without an allocation, agbp would be set to the current * agbp and alloc_done set to false. * If an allocation needed to be done, agbp would be set to the * inode header of the allocation group and alloc_done set to true. * The caller should then commit the current transaction and allocate a new * transaction. xfs_dialloc() should then be called again with * the agbp value returned from the previous call. * * Once we successfully pick an inode its number is returned and the * on-disk data structures are updated. The inode itself is not read * in, since doing so would break ordering constraints with xfs_reclaim. * * *agbp should be set to NULL on the first call, *alloc_done set to FALSE. */ int /* error */ xfs_dialloc( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t parent, /* parent inode (directory) */ mode_t mode, /* mode bits for new inode */ int okalloc, /* ok to allocate more space */ struct xfs_buf **agbp, /* buf for a.g. inode header */ boolean_t *alloc_done, /* an allocation was done to replenish the free inodes */ xfs_ino_t *inop); /* inode number allocated */ /* * Free disk inode. Carefully avoids touching the incore inode, all * manipulations incore are the caller's responsibility. * The on-disk inode is not changed by this operation, only the * btree (free inode mask) is changed. */ int /* error */ xfs_difree( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ struct xfs_bmap_free *flist, /* extents to free */ int *delete, /* set if inode cluster was deleted */ xfs_ino_t *first_ino); /* first inode in deleted cluster */ /* * Return the location of the inode in imap, for mapping it into a buffer. */ int xfs_imap( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t ino, /* inode to locate */ struct xfs_imap *imap, /* location map structure */ uint flags); /* flags for inode btree lookup */ /* * Compute and fill in value of m_in_maxlevels. */ void xfs_ialloc_compute_maxlevels( struct xfs_mount *mp); /* file system mount structure */ /* * Log specified fields for the ag hdr (inode section) */ void xfs_ialloc_log_agi( struct xfs_trans *tp, /* transaction pointer */ struct xfs_buf *bp, /* allocation group header buffer */ int fields); /* bitmask of fields to log */ /* * Read in the allocation group header (inode allocation section) */ int /* error */ xfs_ialloc_read_agi( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno, /* allocation group number */ struct xfs_buf **bpp); /* allocation group hdr buf */ /* * Read in the allocation group header to initialise the per-ag data * in the mount structure */ int xfs_ialloc_pagi_init( struct xfs_mount *mp, /* file system mount structure */ struct xfs_trans *tp, /* transaction pointer */ xfs_agnumber_t agno); /* allocation group number */ /* * Lookup a record by ino in the btree given by cur. */ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino, xfs_lookup_t dir, int *stat); /* * Get the data from the pointed-to record. */ extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_inobt_rec_incore_t *rec, int *stat); #endif /* __XFS_IALLOC_H__ */ xfsprogs-3.1.9ubuntu2/include/darwin.h0000664000000000000000000000730111307015331014667 0ustar /* * Copyright (c) 2004-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DARWIN_H__ #define __XFS_DARWIN_H__ #include #include #include #include #include #include #include #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN #include # ifndef SYS_fsctl # define SYS_fsctl 242 # endif static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { return syscall(SYS_fsctl, path, cmd, p, 0); } static __inline__ int platform_test_xfs_fd(int fd) { struct statfs buf; if (fstatfs(fd, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_test_xfs_path(const char *path) { struct statfs buf; if (statfs(path, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) { return fstatfs(fd, buf); } static __inline__ void platform_getoptreset(void) { extern int optreset; optreset = 0; } static __inline__ int platform_uuid_compare(uuid_t *uu1, uuid_t *uu2) { return uuid_compare(uu1, uu2, NULL); } static __inline__ void platform_uuid_unparse(uuid_t *uu, char *buffer) { uint32_t status; char *s; uuid_to_string(uu, &s, &status); if (status == uuid_s_ok) strcpy(buffer, s); else buffer[0] = '\0'; free(s); } static __inline__ int platform_uuid_parse(char *buffer, uuid_t *uu) { uint32_t status; uuid_from_string(buffer, uu, &status); return (status == uuid_s_ok); } static __inline__ int platform_uuid_is_null(uuid_t *uu) { return uuid_is_nil(uu, NULL); } static __inline__ void platform_uuid_generate(uuid_t *uu) { uuid_create(uu, NULL); } static __inline__ void platform_uuid_clear(uuid_t *uu) { uuid_create_nil(uu, NULL); } static __inline__ void platform_uuid_copy(uuid_t *dst, uuid_t *src) { memcpy(dst, src, sizeof(uuid_t)); } #define __int8_t int8_t #define __int16_t int16_t #define __int32_t int32_t #define __int32_t int32_t #define __int64_t int64_t #define __uint8_t u_int8_t #define __uint16_t u_int16_t #define __uint32_t u_int32_t #define __uint64_t u_int64_t #define loff_t off_t #define off64_t off_t typedef off_t xfs_off_t; typedef u_int64_t xfs_ino_t; typedef u_int32_t xfs_dev_t; typedef int64_t xfs_daddr_t; typedef char* xfs_caddr_t; typedef unsigned char uchar_t; #define stat64 stat #define fstat64 fstat #define lseek64 lseek #define pread64 pread #define pwrite64 pwrite #define ftruncate64 ftruncate #define fdatasync fsync #define memalign(a,sz) valloc(sz) #define O_LARGEFILE 0 #ifndef O_DIRECT #define O_DIRECT 0 #endif #ifndef O_SYNC #define O_SYNC 0 #endif #define B_FALSE 0 #define B_TRUE 1 #define ENOATTR 989 /* Attribute not found */ #define EFSCORRUPTED 990 /* Filesystem is corrupted */ #define constpp char * const * #define HAVE_FID 1 static __inline__ int platform_discard_blocks(int fd, uint64_t start, uint64_t len) { return 0; } #endif /* __XFS_DARWIN_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_dir2_sf.h0000664000000000000000000001236611650373061015632 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DIR2_SF_H__ #define __XFS_DIR2_SF_H__ /* * Directory layout when stored internal to an inode. * * Small directories are packed as tightly as possible so as to * fit into the literal area of the inode. */ struct uio; struct xfs_dabuf; struct xfs_da_args; struct xfs_dir2_block; struct xfs_inode; struct xfs_mount; struct xfs_trans; /* * Inode number stored as 8 8-bit values. */ typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; /* * Inode number stored as 4 8-bit values. * Works a lot of the time, when all the inode numbers in a directory * fit in 32 bits. */ typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; typedef union { xfs_dir2_ino8_t i8; xfs_dir2_ino4_t i4; } xfs_dir2_inou_t; #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) /* * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. * Only need 16 bits, this is the byte offset into the single block form. */ typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t; /* * The parent directory has a dedicated field, and the self-pointer must * be calculated on the fly. * * Entries are packed toward the top as tightly as possible. The header * and the elements must be memcpy'd out into a work area to get correct * alignment for the inode number fields. */ typedef struct xfs_dir2_sf_hdr { __uint8_t count; /* count of entries */ __uint8_t i8count; /* count of 8-byte inode #s */ xfs_dir2_inou_t parent; /* parent dir inode number */ } __arch_pack xfs_dir2_sf_hdr_t; typedef struct xfs_dir2_sf_entry { __uint8_t namelen; /* actual name length */ xfs_dir2_sf_off_t offset; /* saved offset */ __uint8_t name[1]; /* name, variable size */ xfs_dir2_inou_t inumber; /* inode number, var. offset */ } __arch_pack xfs_dir2_sf_entry_t; typedef struct xfs_dir2_sf { xfs_dir2_sf_hdr_t hdr; /* shortform header */ xfs_dir2_sf_entry_t list[1]; /* shortform entries */ } xfs_dir2_sf_t; static inline int xfs_dir2_sf_hdr_size(int i8count) { return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ ((i8count) == 0) * \ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) { return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; } static inline xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) { return ((sfp)->hdr.i8count == 0 ? \ (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); } static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, xfs_dir2_inou_t *to) { if ((sfp)->hdr.i8count == 0) XFS_PUT_DIR_INO4(*(from), (to)->i4); else XFS_PUT_DIR_INO8(*(from), (to)->i8); } static inline xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) { return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); } static inline void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) { INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); } static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) { return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ ((sfp)->hdr.i8count == 0) * \ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } static inline int xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) { return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ ((sfp)->hdr.i8count == 0) * \ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) { return ((xfs_dir2_sf_entry_t *) \ ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); } static inline xfs_dir2_sf_entry_t * xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) { return ((xfs_dir2_sf_entry_t *) \ ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); } /* * Functions. */ extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, struct xfs_dir2_block *block, xfs_dir2_sf_hdr_t *sfhp); extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, int size, xfs_dir2_sf_hdr_t *sfhp); extern int xfs_dir2_sf_addname(struct xfs_da_args *args); extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent, xfs_off_t *offset, filldir_t filldir); extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); extern int xfs_dir2_sf_removename(struct xfs_da_args *args); extern int xfs_dir2_sf_replace(struct xfs_da_args *args); #endif /* __XFS_DIR2_SF_H__ */ xfsprogs-3.1.9ubuntu2/include/handle.h0000664000000000000000000000413011140033220014623 0ustar /* * Copyright (c) 1995, 2001-2003, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __HANDLE_H__ #define __HANDLE_H__ #ifdef __cplusplus extern "C" { #endif struct fsdmidata; struct attrlist_cursor; struct parent; extern int path_to_handle (char *__path, void **__hanp, size_t *__hlen); extern int path_to_fshandle (char *__path, void **__fshanp, size_t *__fshlen); extern int handle_to_fshandle (void *__hanp, size_t __hlen, void **__fshanp, size_t *__fshlen); extern void free_handle (void *__hanp, size_t __hlen); extern int open_by_fshandle (void *__fshanp, size_t __fshlen, int __rw); extern int open_by_handle (void *__hanp, size_t __hlen, int __rw); extern int readlink_by_handle (void *__hanp, size_t __hlen, void *__buf, size_t __bs); extern int attr_multi_by_handle (void *__hanp, size_t __hlen, void *__buf, int __rtrvcnt, int __flags); extern int attr_list_by_handle (void *__hanp, size_t __hlen, void *__buf, size_t __bufsize, int __flags, struct attrlist_cursor *__cursor); extern int parents_by_handle(void *__hanp, size_t __hlen, struct parent *__buf, size_t __bufsize, unsigned int *__count); extern int parentpaths_by_handle(void *__hanp, size_t __hlen, struct parent *__buf, size_t __bufsize, unsigned int *__count); extern int fssetdm_by_handle (void *__hanp, size_t __hlen, struct fsdmidata *__fsdmi); #ifdef __cplusplus } #endif #endif /* __HANDLE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs.h0000664000000000000000000000267411140033220014203 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, * USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ #ifndef __XFS_H__ #define __XFS_H__ #include #include #endif /* __XFS_H__ */ xfsprogs-3.1.9ubuntu2/include/fstyp.h0000664000000000000000000000244711140033220014546 0ustar /* * Copyright (c) 2000-2001, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FSTYP_H__ #define __FSTYP_H__ #ifdef __cplusplus extern "C" { #endif /* * fstype allows the user to determine the filesystem identifier of * mounted or unmounted filesystems, using heuristics. * The filesystem type is required by mount(2) and sometimes by mount(8) * to mount filesystems of different types. */ extern char *fstype (const char * __device); /* * ptabtype allows one to determine the type of partition table in * use on a given volume, using heuristics. */ extern char *pttype (const char *__device); #ifdef __cplusplus } #endif #endif /* __FSTYP_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_extfree_item.h0000664000000000000000000001206411650373061016755 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_EXTFREE_ITEM_H__ #define __XFS_EXTFREE_ITEM_H__ struct xfs_mount; struct kmem_zone; typedef struct xfs_extent { xfs_dfsbno_t ext_start; xfs_extlen_t ext_len; } xfs_extent_t; /* * Since an xfs_extent_t has types (start:64, len: 32) * there are different alignments on 32 bit and 64 bit kernels. * So we provide the different variants for use by a * conversion routine. */ typedef struct xfs_extent_32 { __uint64_t ext_start; __uint32_t ext_len; } __attribute__((packed)) xfs_extent_32_t; typedef struct xfs_extent_64 { __uint64_t ext_start; __uint32_t ext_len; __uint32_t ext_pad; } xfs_extent_64_t; /* * This is the structure used to lay out an efi log item in the * log. The efi_extents field is a variable size array whose * size is given by efi_nextents. */ typedef struct xfs_efi_log_format { __uint16_t efi_type; /* efi log item type */ __uint16_t efi_size; /* size of this item */ __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_t efi_extents[1]; /* array of extents to free */ } xfs_efi_log_format_t; typedef struct xfs_efi_log_format_32 { __uint16_t efi_type; /* efi log item type */ __uint16_t efi_size; /* size of this item */ __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_32_t efi_extents[1]; /* array of extents to free */ } __attribute__((packed)) xfs_efi_log_format_32_t; typedef struct xfs_efi_log_format_64 { __uint16_t efi_type; /* efi log item type */ __uint16_t efi_size; /* size of this item */ __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_64_t efi_extents[1]; /* array of extents to free */ } xfs_efi_log_format_64_t; /* * This is the structure used to lay out an efd log item in the * log. The efd_extents array is a variable size array whose * size is given by efd_nextents; */ typedef struct xfs_efd_log_format { __uint16_t efd_type; /* efd log item type */ __uint16_t efd_size; /* size of this item */ __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_t efd_extents[1]; /* array of extents freed */ } xfs_efd_log_format_t; typedef struct xfs_efd_log_format_32 { __uint16_t efd_type; /* efd log item type */ __uint16_t efd_size; /* size of this item */ __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_32_t efd_extents[1]; /* array of extents freed */ } __attribute__((packed)) xfs_efd_log_format_32_t; typedef struct xfs_efd_log_format_64 { __uint16_t efd_type; /* efd log item type */ __uint16_t efd_size; /* size of this item */ __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_64_t efd_extents[1]; /* array of extents freed */ } xfs_efd_log_format_64_t; #ifdef __KERNEL__ /* * Max number of extents in fast allocation path. */ #define XFS_EFI_MAX_FAST_EXTENTS 16 /* * Define EFI flag bits. Manipulated by set/clear/test_bit operators. */ #define XFS_EFI_RECOVERED 1 #define XFS_EFI_COMMITTED 2 /* * This is the "extent free intention" log item. It is used * to log the fact that some extents need to be free. It is * used in conjunction with the "extent free done" log item * described below. */ typedef struct xfs_efi_log_item { xfs_log_item_t efi_item; atomic_t efi_next_extent; unsigned long efi_flags; /* misc flags */ xfs_efi_log_format_t efi_format; } xfs_efi_log_item_t; /* * This is the "extent free done" log item. It is used to log * the fact that some extents earlier mentioned in an efi item * have been freed. */ typedef struct xfs_efd_log_item { xfs_log_item_t efd_item; xfs_efi_log_item_t *efd_efip; uint efd_next_extent; xfs_efd_log_format_t efd_format; } xfs_efd_log_item_t; /* * Max number of extents in fast allocation path. */ #define XFS_EFD_MAX_FAST_EXTENTS 16 extern struct kmem_zone *xfs_efi_zone; extern struct kmem_zone *xfs_efd_zone; xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, uint); int xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt); void xfs_efi_item_free(xfs_efi_log_item_t *); #endif /* __KERNEL__ */ #endif /* __XFS_EXTFREE_ITEM_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_inode.h0000664000000000000000000004732511650373061015403 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_INODE_H__ #define __XFS_INODE_H__ struct posix_acl; struct xfs_dinode; struct xfs_inode; /* * Fork identifiers. */ #define XFS_DATA_FORK 0 #define XFS_ATTR_FORK 1 /* * The following xfs_ext_irec_t struct introduces a second (top) level * to the in-core extent allocation scheme. These structs are allocated * in a contiguous block, creating an indirection array where each entry * (irec) contains a pointer to a buffer of in-core extent records which * it manages. Each extent buffer is 4k in size, since 4k is the system * page size on Linux i386 and systems with larger page sizes don't seem * to gain much, if anything, by using their native page size as the * extent buffer size. Also, using 4k extent buffers everywhere provides * a consistent interface for CXFS across different platforms. * * There is currently no limit on the number of irec's (extent lists) * allowed, so heavily fragmented files may require an indirection array * which spans multiple system pages of memory. The number of extents * which would require this amount of contiguous memory is very large * and should not cause problems in the foreseeable future. However, * if the memory needed for the contiguous array ever becomes a problem, * it is possible that a third level of indirection may be required. */ typedef struct xfs_ext_irec { xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ xfs_extnum_t er_extoff; /* extent offset in file */ xfs_extnum_t er_extcount; /* number of extents in page/block */ } xfs_ext_irec_t; /* * File incore extent information, present for each of data & attr forks. */ #define XFS_IEXT_BUFSZ 4096 #define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) #define XFS_INLINE_EXTS 2 #define XFS_INLINE_DATA 32 typedef struct xfs_ifork { int if_bytes; /* bytes in if_u1 */ int if_real_bytes; /* bytes allocated in if_u1 */ struct xfs_btree_block *if_broot; /* file's incore btree root */ short if_broot_bytes; /* bytes allocated for root */ unsigned char if_flags; /* per-fork flags */ unsigned char if_ext_max; /* max # of extent records */ xfs_extnum_t if_lastex; /* last if_extents used */ union { xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ char *if_data; /* inline file data */ } if_u1; union { xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; /* very small file extents */ char if_inline_data[XFS_INLINE_DATA]; /* very small file data */ xfs_dev_t if_rdev; /* dev number if special */ uuid_t if_uuid; /* mount point value */ } if_u2; } xfs_ifork_t; /* * Inode location information. Stored in the inode and passed to * xfs_imap_to_bp() to get a buffer and dinode for a given inode. */ struct xfs_imap { xfs_daddr_t im_blkno; /* starting BB of inode chunk */ ushort im_len; /* length in BBs of inode chunk */ ushort im_boffset; /* inode offset in block in bytes */ }; /* * This is the xfs in-core inode structure. * Most of the on-disk inode is embedded in the i_d field. * * The extent pointers/inline file space, however, are managed * separately. The memory for this information is pointed to by * the if_u1 unions depending on the type of the data. * This is used to linearize the array of extents for fast in-core * access. This is used until the file's number of extents * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers * are accessed through the buffer cache. * * Other state kept in the in-core inode is used for identification, * locking, transactional updating, etc of the inode. * * Generally, we do not want to hold the i_rlock while holding the * i_ilock. Hierarchy is i_iolock followed by i_rlock. * * xfs_iptr_t contains all the inode fields upto and including the * i_mnext and i_mprev fields, it is used as a marker in the inode * chain off the mount structure by xfs_sync calls. */ typedef struct xfs_ictimestamp { __int32_t t_sec; /* timestamp seconds */ __int32_t t_nsec; /* timestamp nanoseconds */ } xfs_ictimestamp_t; /* * NOTE: This structure must be kept identical to struct xfs_dinode * in xfs_dinode.h except for the endianness annotations. */ typedef struct xfs_icdinode { __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ __int8_t di_format; /* format of di_c data */ __uint16_t di_onlink; /* old number of links to file */ __uint32_t di_uid; /* owner's user id */ __uint32_t di_gid; /* owner's group id */ __uint32_t di_nlink; /* number of links to file */ __uint16_t di_projid_lo; /* lower part of owner's project id */ __uint16_t di_projid_hi; /* higher part of owner's project id */ __uint8_t di_pad[6]; /* unused, zeroed space */ __uint16_t di_flushiter; /* incremented on flush */ xfs_ictimestamp_t di_atime; /* time last accessed */ xfs_ictimestamp_t di_mtime; /* time last modified */ xfs_ictimestamp_t di_ctime; /* time created/inode modified */ xfs_fsize_t di_size; /* number of bytes in file */ xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ xfs_extnum_t di_nextents; /* number of extents in data fork */ xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ __int8_t di_aformat; /* format of attr fork's data */ __uint32_t di_dmevmask; /* DMIG event mask */ __uint16_t di_dmstate; /* DMIG state info */ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ __uint32_t di_gen; /* generation number */ } xfs_icdinode_t; /* * Flags for xfs_ichgtime(). */ #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ #define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ /* * Per-fork incore inode flags. */ #define XFS_IFINLINE 0x01 /* Inline data is read in */ #define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ #define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ /* * Fork handling. */ #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) #define XFS_IFORK_PTR(ip,w) \ ((w) == XFS_DATA_FORK ? \ &(ip)->i_df : \ (ip)->i_afp) #define XFS_IFORK_DSIZE(ip) \ (XFS_IFORK_Q(ip) ? \ XFS_IFORK_BOFF(ip) : \ XFS_LITINO((ip)->i_mount)) #define XFS_IFORK_ASIZE(ip) \ (XFS_IFORK_Q(ip) ? \ XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ 0) #define XFS_IFORK_SIZE(ip,w) \ ((w) == XFS_DATA_FORK ? \ XFS_IFORK_DSIZE(ip) : \ XFS_IFORK_ASIZE(ip)) #define XFS_IFORK_FORMAT(ip,w) \ ((w) == XFS_DATA_FORK ? \ (ip)->i_d.di_format : \ (ip)->i_d.di_aformat) #define XFS_IFORK_FMT_SET(ip,w,n) \ ((w) == XFS_DATA_FORK ? \ ((ip)->i_d.di_format = (n)) : \ ((ip)->i_d.di_aformat = (n))) #define XFS_IFORK_NEXTENTS(ip,w) \ ((w) == XFS_DATA_FORK ? \ (ip)->i_d.di_nextents : \ (ip)->i_d.di_anextents) #define XFS_IFORK_NEXT_SET(ip,w,n) \ ((w) == XFS_DATA_FORK ? \ ((ip)->i_d.di_nextents = (n)) : \ ((ip)->i_d.di_anextents = (n))) /* * Project quota id helpers (previously projid was 16bit only * and using two 16bit values to hold new 32bit projid was choosen * to retain compatibility with "old" filesystems). */ static inline __uint32_t xfs_get_projid(struct xfs_icdinode i_d) { return (__uint32_t)i_d.di_projid_hi << 16 | i_d.di_projid_lo; } static inline void xfs_set_projid(struct xfs_icdinode *i_d, __uint32_t projid) { i_d->di_projid_hi = (__uint16_t) (projid >> 16); i_d->di_projid_lo = (__uint16_t) (projid & 0xffff); } #ifdef __KERNEL__ struct bhv_desc; struct xfs_buf; struct xfs_bmap_free; struct xfs_bmbt_irec; struct xfs_inode_log_item; struct xfs_mount; struct xfs_trans; struct xfs_dquot; typedef struct dm_attrs_s { __uint32_t da_dmevmask; /* DMIG event mask */ __uint16_t da_dmstate; /* DMIG state info */ __uint16_t da_pad; /* DMIG extra padding */ } dm_attrs_t; typedef struct xfs_inode { /* Inode linking and identification information. */ struct xfs_mount *i_mount; /* fs mount struct ptr */ struct xfs_dquot *i_udquot; /* user dquot */ struct xfs_dquot *i_gdquot; /* group dquot */ /* Inode location stuff */ xfs_ino_t i_ino; /* inode number (agno/agino)*/ struct xfs_imap i_imap; /* location for xfs_imap() */ /* Extent information. */ xfs_ifork_t *i_afp; /* attribute fork pointer */ xfs_ifork_t i_df; /* data fork */ /* Transaction and locking information. */ struct xfs_trans *i_transp; /* ptr to owning transaction*/ struct xfs_inode_log_item *i_itemp; /* logging information */ mrlock_t i_lock; /* inode lock */ mrlock_t i_iolock; /* inode IO lock */ struct completion i_flush; /* inode flush completion q */ atomic_t i_pincount; /* inode pin count */ wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ spinlock_t i_flags_lock; /* inode i_flags lock */ /* Miscellaneous state. */ unsigned short i_flags; /* see defined flags below */ unsigned char i_update_core; /* timestamps/size is dirty */ unsigned int i_delayed_blks; /* count of delay alloc blks */ xfs_icdinode_t i_d; /* most of ondisk inode */ xfs_fsize_t i_size; /* in-memory size */ xfs_fsize_t i_new_size; /* size when write completes */ atomic_t i_iocount; /* outstanding I/O count */ /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ } xfs_inode_t; #define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ (ip)->i_size : (ip)->i_d.di_size; /* Convert from vfs inode to xfs inode */ static inline struct xfs_inode *XFS_I(struct inode *inode) { return container_of(inode, struct xfs_inode, i_vnode); } /* convert from xfs inode to vfs inode */ static inline struct inode *VFS_I(struct xfs_inode *ip) { return &ip->i_vnode; } /* * i_flags helper functions */ static inline void __xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) { ip->i_flags |= flags; } static inline void xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) { spin_lock(&ip->i_flags_lock); __xfs_iflags_set(ip, flags); spin_unlock(&ip->i_flags_lock); } static inline void xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) { spin_lock(&ip->i_flags_lock); ip->i_flags &= ~flags; spin_unlock(&ip->i_flags_lock); } static inline int __xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) { return (ip->i_flags & flags); } static inline int xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) { int ret; spin_lock(&ip->i_flags_lock); ret = __xfs_iflags_test(ip, flags); spin_unlock(&ip->i_flags_lock); return ret; } static inline int xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) { int ret; spin_lock(&ip->i_flags_lock); ret = ip->i_flags & flags; if (ret) ip->i_flags &= ~flags; spin_unlock(&ip->i_flags_lock); return ret; } /* * Project quota id helpers (previously projid was 16bit only * and using two 16bit values to hold new 32bit projid was choosen * to retain compatibility with "old" filesystems). */ static inline prid_t xfs_get_projid(struct xfs_inode *ip) { return (prid_t)ip->i_d.di_projid_hi << 16 | ip->i_d.di_projid_lo; } static inline void xfs_set_projid(struct xfs_inode *ip, prid_t projid) { ip->i_d.di_projid_hi = (__uint16_t) (projid >> 16); ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff); } /* * Manage the i_flush queue embedded in the inode. This completion * queue synchronizes processes attempting to flush the in-core * inode back to disk. */ static inline void xfs_iflock(xfs_inode_t *ip) { wait_for_completion(&ip->i_flush); } static inline int xfs_iflock_nowait(xfs_inode_t *ip) { return try_wait_for_completion(&ip->i_flush); } static inline void xfs_ifunlock(xfs_inode_t *ip) { complete(&ip->i_flush); } /* * In-core inode flags. */ #define XFS_IRECLAIM 0x0001 /* started reclaiming this inode */ #define XFS_ISTALE 0x0002 /* inode has been staled */ #define XFS_IRECLAIMABLE 0x0004 /* inode can be reclaimed */ #define XFS_INEW 0x0008 /* inode has just been allocated */ #define XFS_IFILESTREAM 0x0010 /* inode is in a filestream directory */ #define XFS_ITRUNCATED 0x0020 /* truncated down so flush-on-close */ #define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ /* * Flags for inode locking. * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) * 1<<16 - 1<<32-1 -- lockdep annotation (integers) */ #define XFS_IOLOCK_EXCL (1<<0) #define XFS_IOLOCK_SHARED (1<<1) #define XFS_ILOCK_EXCL (1<<2) #define XFS_ILOCK_SHARED (1<<3) #define XFS_IUNLOCK_NONOTIFY (1<<4) #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) #define XFS_LOCK_FLAGS \ { XFS_IOLOCK_EXCL, "IOLOCK_EXCL" }, \ { XFS_IOLOCK_SHARED, "IOLOCK_SHARED" }, \ { XFS_ILOCK_EXCL, "ILOCK_EXCL" }, \ { XFS_ILOCK_SHARED, "ILOCK_SHARED" }, \ { XFS_IUNLOCK_NONOTIFY, "IUNLOCK_NONOTIFY" } /* * Flags for lockdep annotations. * * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes * (ie directory operations that require locking a directory inode and * an entry inode). The first inode gets locked with this flag so it * gets a lockdep subclass of 1 and the second lock will have a lockdep * subclass of 0. * * XFS_LOCK_INUMORDER - for locking several inodes at the some time * with xfs_lock_inodes(). This flag is used as the starting subclass * and each subsequent lock acquired will increment the subclass by one. * So the first lock acquired will have a lockdep subclass of 2, the * second lock will have a lockdep subclass of 3, and so on. It is * the responsibility of the class builder to shift this to the correct * portion of the lock_mode lockdep mask. */ #define XFS_LOCK_PARENT 1 #define XFS_LOCK_INUMORDER 2 #define XFS_IOLOCK_SHIFT 16 #define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) #define XFS_ILOCK_SHIFT 24 #define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) #define XFS_IOLOCK_DEP_MASK 0x00ff0000 #define XFS_ILOCK_DEP_MASK 0xff000000 #define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK) #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) extern struct lock_class_key xfs_iolock_reclaimable; /* * Flags for xfs_itruncate_start(). */ #define XFS_ITRUNC_DEFINITE 0x1 #define XFS_ITRUNC_MAYBE 0x2 #define XFS_ITRUNC_FLAGS \ { XFS_ITRUNC_DEFINITE, "DEFINITE" }, \ { XFS_ITRUNC_MAYBE, "MAYBE" } /* * For multiple groups support: if S_ISGID bit is set in the parent * directory, group of new file is set to that of the parent, and * new subdirectory gets S_ISGID bit from parent. */ #define XFS_INHERIT_GID(pip) \ (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ ((pip)->i_d.di_mode & S_ISGID)) /* * xfs_iget.c prototypes. */ int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, uint, xfs_inode_t **); void xfs_ilock(xfs_inode_t *, uint); int xfs_ilock_nowait(xfs_inode_t *, uint); void xfs_iunlock(xfs_inode_t *, uint); void xfs_ilock_demote(xfs_inode_t *, uint); int xfs_isilocked(xfs_inode_t *, uint); uint xfs_ilock_map_shared(xfs_inode_t *); void xfs_iunlock_map_shared(xfs_inode_t *, uint); void xfs_inode_free(struct xfs_inode *ip); /* * xfs_inode.c prototypes. */ int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, xfs_nlink_t, xfs_dev_t, prid_t, int, struct xfs_buf **, boolean_t *, xfs_inode_t **); uint xfs_ip2xflags(struct xfs_inode *); uint xfs_dic2xflags(struct xfs_dinode *); int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_bmap_free *); int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, xfs_fsize_t, int, int); int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); void xfs_iext_realloc(xfs_inode_t *, int, int); void xfs_iunpin_wait(xfs_inode_t *); int xfs_iflush(xfs_inode_t *, uint); void xfs_lock_inodes(xfs_inode_t **, int, uint); void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); void xfs_synchronize_times(xfs_inode_t *); void xfs_mark_inode_dirty(xfs_inode_t *); void xfs_mark_inode_dirty_sync(xfs_inode_t *); #define IHOLD(ip) \ do { \ ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ ihold(VFS_I(ip)); \ trace_xfs_ihold(ip, _THIS_IP_); \ } while (0) #define IRELE(ip) \ do { \ trace_xfs_irele(ip, _THIS_IP_); \ iput(VFS_I(ip)); \ } while (0) #endif /* __KERNEL__ */ /* * Flags for xfs_iget() */ #define XFS_IGET_CREATE 0x1 #define XFS_IGET_UNTRUSTED 0x2 int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, struct xfs_dinode **, struct xfs_buf **, int *, uint); int xfs_itobp(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, struct xfs_dinode **, struct xfs_buf **, uint); int xfs_iread(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, uint); void xfs_dinode_to_disk(struct xfs_dinode *, struct xfs_icdinode *); void xfs_dinode_from_disk(struct xfs_icdinode *, struct xfs_dinode *); void xfs_idestroy_fork(struct xfs_inode *, int); void xfs_idata_realloc(struct xfs_inode *, int, int); void xfs_iroot_realloc(struct xfs_inode *, int, int); int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); int xfs_iextents_copy(struct xfs_inode *, xfs_bmbt_rec_t *, int); xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t, xfs_bmbt_irec_t *, int); void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int); void xfs_iext_remove(struct xfs_inode *, xfs_extnum_t, int, int); void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_realloc_direct(xfs_ifork_t *, int); void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); void xfs_iext_inline_to_direct(xfs_ifork_t *, int); void xfs_iext_destroy(xfs_ifork_t *); xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); void xfs_iext_irec_init(xfs_ifork_t *); xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int); void xfs_iext_irec_remove(xfs_ifork_t *, int); void xfs_iext_irec_compact(xfs_ifork_t *); void xfs_iext_irec_compact_pages(xfs_ifork_t *); void xfs_iext_irec_compact_full(xfs_ifork_t *); void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int); #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) #ifdef DEBUG void xfs_isize_check(struct xfs_mount *, struct xfs_inode *, xfs_fsize_t); #else /* DEBUG */ #define xfs_isize_check(mp, ip, isize) #endif /* DEBUG */ #if defined(DEBUG) void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); #else #define xfs_inobp_check(mp, bp) #endif /* DEBUG */ extern struct kmem_zone *xfs_ifork_zone; extern struct kmem_zone *xfs_inode_zone; extern struct kmem_zone *xfs_ili_zone; #endif /* __XFS_INODE_H__ */ xfsprogs-3.1.9ubuntu2/include/input.h0000664000000000000000000000353511140033220014537 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __INPUT_H__ #define __INPUT_H__ #include #include #include #include extern char **breakline(char *input, int *count); extern void doneline(char *input, char **vec); extern char *fetchline(void); extern long long cvtnum(size_t blocksize, size_t sectorsize, char *s); extern void cvtstr(double value, char *str, size_t sz); extern unsigned long cvttime(char *s); extern struct timeval tadd(struct timeval t1, struct timeval t2); extern struct timeval tsub(struct timeval t1, struct timeval t2); extern double tdiv(double value, struct timeval tv); enum { DEFAULT_TIME = 0x0, TERSE_FIXED_TIME = 0x1, VERBOSE_FIXED_TIME = 0x2 }; extern void timestr(struct timeval *tv, char *str, size_t sz, int flags); extern uid_t uid_from_string(char *user); extern gid_t gid_from_string(char *group); extern prid_t prid_from_string(char *project); #define HAVE_FTW_H 1 /* TODO: configure me */ #ifdef HAVE_FTW_H #include #else struct FTW; struct stat; extern int nftw( char *dir, int (*fn)(const char *, const struct stat *, int, struct FTW *), int depth, int flags); #endif #endif /* __INPUT_H__ */ xfsprogs-3.1.9ubuntu2/include/gnukfreebsd.h0000664000000000000000000000560211371657241015721 0ustar /* * Copyright (c) 2004-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_KFREEBSD_H__ #define __XFS_KFREEBSD_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define constpp char * const * #define EFSCORRUPTED 990 /* Filesystem is corrupted */ typedef off_t xfs_off_t; typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; typedef char* xfs_caddr_t; typedef off_t loff_t; #ifndef _UCHAR_T_DEFINED typedef unsigned char uchar_t; #define _UCHAR_T_DEFINED 1 #endif typedef enum { B_FALSE,B_TRUE } boolean_t; #define HAVE_FID 1 static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { return ioctl(fd, cmd, p); } static __inline__ int platform_test_xfs_fd(int fd) { struct statfs buf; if (fstatfs(fd, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_test_xfs_path(const char *path) { struct statfs buf; if (statfs(path, &buf) < 0) return 0; return strncmp(buf.f_fstypename, "xfs", 4) == 0; } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) { return fstatfs(fd, buf); } static __inline__ void platform_getoptreset(void) { extern int optind; optind = 0; } static __inline__ int platform_uuid_compare(uuid_t *uu1, uuid_t *uu2) { return uuid_compare(*uu1, *uu2); } static __inline__ void platform_uuid_unparse(uuid_t *uu, char *buffer) { uuid_unparse(*uu, buffer); } static __inline__ int platform_uuid_parse(char *buffer, uuid_t *uu) { return uuid_parse(buffer, *uu); } static __inline__ int platform_uuid_is_null(uuid_t *uu) { return uuid_is_null(*uu); } static __inline__ void platform_uuid_generate(uuid_t *uu) { uuid_generate(*uu); } static __inline__ void platform_uuid_clear(uuid_t *uu) { uuid_clear(*uu); } static __inline__ void platform_uuid_copy(uuid_t *dst, uuid_t *src) { uuid_copy(*dst, *src); } static __inline__ int platform_discard_blocks(int fd, uint64_t start, uint64_t len) { return 0; } #endif /* __XFS_KFREEBSD_H__ */ xfsprogs-3.1.9ubuntu2/include/platform_defs.h.in0000664000000000000000000001060712062210562016642 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @configure_input@ */ #ifndef __XFS_PLATFORM_DEFS_H__ #define __XFS_PLATFORM_DEFS_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef HAVE___U32 #ifdef HAVE___U32 #include #else typedef unsigned char __u8; typedef signed char __s8; typedef unsigned short __u16; typedef signed short __s16; typedef unsigned int __u32; typedef signed int __s32; typedef unsigned long long int __u64; typedef signed long long int __s64; #endif #ifdef __CHECKER__ #define __bitwise __attribute__((bitwise)) #define __force __attribute__((force)) #else #define __bitwise #define __force #endif typedef __u16 __bitwise __be16; typedef __u32 __bitwise __be32; typedef __u64 __bitwise __be64; typedef struct filldir filldir_t; #if defined(__linux__) #include #elif defined(__FreeBSD__) #include #elif defined(__FreeBSD_kernel__) #include #elif defined(__APPLE__) #include #elif defined(__sgi__) || defined(__sgi) #include #else # error unknown platform... have fun porting! #endif /* long and pointer must be either 32 bit or 64 bit */ #undef SIZEOF_LONG #undef SIZEOF_CHAR_P #define BITS_PER_LONG (SIZEOF_LONG * CHAR_BIT) /* Check if __psint_t is set to something meaningful */ #undef HAVE___PSINT_T #ifndef HAVE___PSINT_T # if (SIZEOF_CHAR_P * CHAR_BIT) == 32 typedef int __psint_t; # elif (SIZEOF_CHAR_P * CHAR_BIT) == 64 # if BITS_PER_LONG == 64 typedef long __psint_t; # else /* This is a very strange architecture, which has 64 bit pointers but */ /* not 64 bit longs. So, just punt here and assume long long is OK. */ typedef long long __psint_t; # endif # else # error Unknown pointer size # endif #endif /* Check if __psunsigned_t is set to something meaningful */ #undef HAVE___PSUNSIGNED_T #ifndef HAVE___PSUNSIGNED_T # if (SIZEOF_CHAR_P * CHAR_BIT) == 32 typedef unsigned int __psunsigned_t; # elif (SIZEOF_CHAR_P * CHAR_BIT) == 64 # if BITS_PER_LONG == 64 typedef long __psunsigned_t; # else /* This is a very strange architecture, which has 64 bit pointers but */ /* not 64 bit longs. So, just punt here and assume long long is OK. */ typedef unsigned long long __psunsigned_t; # endif # else # error Unknown pointer size # endif #endif /* Define if you want gettext (I18N) support */ #undef ENABLE_GETTEXT #ifdef ENABLE_GETTEXT # include # define _(x) gettext(x) # define N_(x) x #else # define _(x) (x) # define N_(x) x # define textdomain(d) do { } while (0) # define bindtextdomain(d,dir) do { } while (0) #endif #include #ifdef DEBUG # define ASSERT(EX) assert(EX) #else # define ASSERT(EX) ((void) 0) #endif /* * sparse kernel source annotations */ #ifndef __user #define __user #endif #define IRIX_DEV_BITSMAJOR 14 #define IRIX_DEV_BITSMINOR 18 #define IRIX_DEV_MAXMAJ 0x1ff #define IRIX_DEV_MAXMIN 0x3ffff #define IRIX_DEV_MAJOR(dev) ((int)(((unsigned)(dev) >> IRIX_DEV_BITSMINOR) \ & IRIX_DEV_MAXMAJ)) #define IRIX_DEV_MINOR(dev) ((int)((dev) & IRIX_DEV_MAXMIN)) #define IRIX_MKDEV(major,minor) ((xfs_dev_t)(((major) << IRIX_DEV_BITSMINOR) \ | (minor&IRIX_DEV_MAXMIN))) #define IRIX_DEV_TO_KDEVT(dev) makedev(IRIX_DEV_MAJOR(dev),IRIX_DEV_MINOR(dev)) /* ARM old ABI has some weird alignment/padding */ #if defined(__arm__) && !defined(__ARM_EABI__) #define __arch_pack __attribute__((packed)) #else #define __arch_pack #endif #endif /* __XFS_PLATFORM_DEFS_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_inode_item.h0000664000000000000000000001343211650373061016411 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_INODE_ITEM_H__ #define __XFS_INODE_ITEM_H__ /* * This is the structure used to lay out an inode log item in the * log. The size of the inline data/extents/b-tree root to be logged * (if any) is indicated in the ilf_dsize field. Changes to this structure * must be added on to the end. */ typedef struct xfs_inode_log_format { __uint16_t ilf_type; /* inode log item type */ __uint16_t ilf_size; /* size of this item */ __uint32_t ilf_fields; /* flags for fields logged */ __uint16_t ilf_asize; /* size of attr d/ext/root */ __uint16_t ilf_dsize; /* size of data/ext/root */ __uint64_t ilf_ino; /* inode number */ union { __uint32_t ilfu_rdev; /* rdev value for dev inode*/ uuid_t ilfu_uuid; /* mount point value */ } ilf_u; __int64_t ilf_blkno; /* blkno of inode buffer */ __int32_t ilf_len; /* len of inode buffer */ __int32_t ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_t; typedef struct xfs_inode_log_format_32 { __uint16_t ilf_type; /* inode log item type */ __uint16_t ilf_size; /* size of this item */ __uint32_t ilf_fields; /* flags for fields logged */ __uint16_t ilf_asize; /* size of attr d/ext/root */ __uint16_t ilf_dsize; /* size of data/ext/root */ __uint64_t ilf_ino; /* inode number */ union { __uint32_t ilfu_rdev; /* rdev value for dev inode*/ uuid_t ilfu_uuid; /* mount point value */ } ilf_u; __int64_t ilf_blkno; /* blkno of inode buffer */ __int32_t ilf_len; /* len of inode buffer */ __int32_t ilf_boffset; /* off of inode in buffer */ } __attribute__((packed)) xfs_inode_log_format_32_t; typedef struct xfs_inode_log_format_64 { __uint16_t ilf_type; /* inode log item type */ __uint16_t ilf_size; /* size of this item */ __uint32_t ilf_fields; /* flags for fields logged */ __uint16_t ilf_asize; /* size of attr d/ext/root */ __uint16_t ilf_dsize; /* size of data/ext/root */ __uint32_t ilf_pad; /* pad for 64 bit boundary */ __uint64_t ilf_ino; /* inode number */ union { __uint32_t ilfu_rdev; /* rdev value for dev inode*/ uuid_t ilfu_uuid; /* mount point value */ } ilf_u; __int64_t ilf_blkno; /* blkno of inode buffer */ __int32_t ilf_len; /* len of inode buffer */ __int32_t ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_64_t; /* * Flags for xfs_trans_log_inode flags field. */ #define XFS_ILOG_CORE 0x001 /* log standard inode fields */ #define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */ #define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */ #define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */ #define XFS_ILOG_DEV 0x010 /* log the dev field */ #define XFS_ILOG_UUID 0x020 /* log the uuid field */ #define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */ #define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ #define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ #define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ XFS_ILOG_UUID | XFS_ILOG_ADATA | \ XFS_ILOG_AEXT | XFS_ILOG_ABROOT) #define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ XFS_ILOG_DBROOT) #define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ XFS_ILOG_ABROOT) #define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \ XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ XFS_ILOG_DEV | XFS_ILOG_UUID | \ XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ XFS_ILOG_ABROOT) static inline int xfs_ilog_fbroot(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); } static inline int xfs_ilog_fext(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); } static inline int xfs_ilog_fdata(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); } #ifdef __KERNEL__ struct xfs_buf; struct xfs_bmbt_rec; struct xfs_inode; struct xfs_mount; typedef struct xfs_inode_log_item { xfs_log_item_t ili_item; /* common portion */ struct xfs_inode *ili_inode; /* inode ptr */ xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ unsigned short ili_lock_flags; /* lock flags */ unsigned short ili_logged; /* flushed logged data */ unsigned int ili_last_fields; /* fields when flushed */ struct xfs_bmbt_rec *ili_extents_buf; /* array of logged data exts */ struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged attr exts */ #ifdef XFS_TRANS_DEBUG int ili_root_size; char *ili_orig_root; #endif xfs_inode_log_format_t ili_format; /* logged structure */ } xfs_inode_log_item_t; static inline int xfs_inode_clean(xfs_inode_t *ip) { return (!ip->i_itemp || !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) && !ip->i_update_core; } extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *); extern void xfs_inode_item_destroy(struct xfs_inode *); extern void xfs_iflush_done(struct xfs_buf *, struct xfs_log_item *); extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *); extern void xfs_iflush_abort(struct xfs_inode *); extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, xfs_inode_log_format_t *); #endif /* __KERNEL__ */ #endif /* __XFS_INODE_ITEM_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_fs.h0000664000000000000000000004640511650373061014713 0ustar /* * Copyright (c) 1995-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_FS_H__ #define __XFS_FS_H__ /* * SGI's XFS filesystem's major stuff (constants, structures) */ /* * Direct I/O attribute record used with XFS_IOC_DIOINFO * d_miniosz is the min xfer size, xfer size multiple and file seek offset * alignment. */ #ifndef HAVE_DIOATTR struct dioattr { __u32 d_mem; /* data buffer memory alignment */ __u32 d_miniosz; /* min xfer size */ __u32 d_maxiosz; /* max xfer size */ }; #endif /* * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR. */ #ifndef HAVE_FSXATTR struct fsxattr { __u32 fsx_xflags; /* xflags field value (get/set) */ __u32 fsx_extsize; /* extsize field value (get/set)*/ __u32 fsx_nextents; /* nextents field value (get) */ __u32 fsx_projid; /* project identifier (get/set) */ unsigned char fsx_pad[12]; }; #endif /* * Flags for the bs_xflags/fsx_xflags field * There should be a one-to-one correspondence between these flags and the * XFS_DIFLAG_s. */ #define XFS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */ #define XFS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */ #define XFS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */ #define XFS_XFLAG_APPEND 0x00000010 /* all writes append */ #define XFS_XFLAG_SYNC 0x00000020 /* all writes synchronous */ #define XFS_XFLAG_NOATIME 0x00000040 /* do not update access time */ #define XFS_XFLAG_NODUMP 0x00000080 /* do not include in backups */ #define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */ #define XFS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */ #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* * Structure for XFS_IOC_GETBMAP. * On input, fill in bmv_offset and bmv_length of the first structure * to indicate the area of interest in the file, and bmv_entries with * the number of array elements given back. The first structure is * updated on return to give the offset and length for the next call. */ #ifndef HAVE_GETBMAP struct getbmap { __s64 bmv_offset; /* file offset of segment in blocks */ __s64 bmv_block; /* starting block (64-bit daddr_t) */ __s64 bmv_length; /* length of segment, blocks */ __s32 bmv_count; /* # of entries in array incl. 1st */ __s32 bmv_entries; /* # of entries filled in (output) */ }; #endif /* * Structure for XFS_IOC_GETBMAPX. Fields bmv_offset through bmv_entries * are used exactly as in the getbmap structure. The getbmapx structure * has additional bmv_iflags and bmv_oflags fields. The bmv_iflags field * is only used for the first structure. It contains input flags * specifying XFS_IOC_GETBMAPX actions. The bmv_oflags field is filled * in by the XFS_IOC_GETBMAPX command for each returned structure after * the first. */ #ifndef HAVE_GETBMAPX struct getbmapx { __s64 bmv_offset; /* file offset of segment in blocks */ __s64 bmv_block; /* starting block (64-bit daddr_t) */ __s64 bmv_length; /* length of segment, blocks */ __s32 bmv_count; /* # of entries in array incl. 1st */ __s32 bmv_entries; /* # of entries filled in (output). */ __s32 bmv_iflags; /* input flags (1st structure) */ __s32 bmv_oflags; /* output flags (after 1st structure)*/ __s32 bmv_unused1; /* future use */ __s32 bmv_unused2; /* future use */ }; #endif /* bmv_iflags values - set by XFS_IOC_GETBMAPX caller. */ #define BMV_IF_ATTRFORK 0x1 /* return attr fork rather than data */ #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ #define BMV_IF_NO_HOLES 0x10 /* Do not return holes */ #define BMV_IF_VALID \ (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC| \ BMV_IF_DELALLOC|BMV_IF_NO_HOLES) /* bmv_oflags values - returned for each non-header segment */ #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ #define BMV_OF_DELALLOC 0x2 /* segment = delayed allocation */ #define BMV_OF_LAST 0x4 /* segment is the last in the file */ /* * Structure for XFS_IOC_FSSETDM. * For use by backup and restore programs to set the XFS on-disk inode * fields di_dmevmask and di_dmstate. These must be set to exactly and * only values previously obtained via xfs_bulkstat! (Specifically the * xfs_bstat_t fields bs_dmevmask and bs_dmstate.) */ #ifndef HAVE_FSDMIDATA struct fsdmidata { __u32 fsd_dmevmask; /* corresponds to di_dmevmask */ __u16 fsd_padding; __u16 fsd_dmstate; /* corresponds to di_dmstate */ }; #endif /* * File segment locking set data type for 64 bit access. * Also used for all the RESV/FREE interfaces. */ typedef struct xfs_flock64 { __s16 l_type; __s16 l_whence; __s64 l_start; __s64 l_len; /* len == 0 means until end of file */ __s32 l_sysid; __u32 l_pid; __s32 l_pad[4]; /* reserve area */ } xfs_flock64_t; /* * Output for XFS_IOC_FSGEOMETRY_V1 */ typedef struct xfs_fsop_geom_v1 { __u32 blocksize; /* filesystem (data) block size */ __u32 rtextsize; /* realtime extent size */ __u32 agblocks; /* fsblocks in an AG */ __u32 agcount; /* number of allocation groups */ __u32 logblocks; /* fsblocks in the log */ __u32 sectsize; /* (data) sector size, bytes */ __u32 inodesize; /* inode size in bytes */ __u32 imaxpct; /* max allowed inode space(%) */ __u64 datablocks; /* fsblocks in data subvolume */ __u64 rtblocks; /* fsblocks in realtime subvol */ __u64 rtextents; /* rt extents in realtime subvol*/ __u64 logstart; /* starting fsblock of the log */ unsigned char uuid[16]; /* unique id of the filesystem */ __u32 sunit; /* stripe unit, fsblocks */ __u32 swidth; /* stripe width, fsblocks */ __s32 version; /* structure version */ __u32 flags; /* superblock version flags */ __u32 logsectsize; /* log sector size, bytes */ __u32 rtsectsize; /* realtime sector size, bytes */ __u32 dirblocksize; /* directory block size, bytes */ } xfs_fsop_geom_v1_t; /* * Output for XFS_IOC_FSGEOMETRY */ typedef struct xfs_fsop_geom { __u32 blocksize; /* filesystem (data) block size */ __u32 rtextsize; /* realtime extent size */ __u32 agblocks; /* fsblocks in an AG */ __u32 agcount; /* number of allocation groups */ __u32 logblocks; /* fsblocks in the log */ __u32 sectsize; /* (data) sector size, bytes */ __u32 inodesize; /* inode size in bytes */ __u32 imaxpct; /* max allowed inode space(%) */ __u64 datablocks; /* fsblocks in data subvolume */ __u64 rtblocks; /* fsblocks in realtime subvol */ __u64 rtextents; /* rt extents in realtime subvol*/ __u64 logstart; /* starting fsblock of the log */ unsigned char uuid[16]; /* unique id of the filesystem */ __u32 sunit; /* stripe unit, fsblocks */ __u32 swidth; /* stripe width, fsblocks */ __s32 version; /* structure version */ __u32 flags; /* superblock version flags */ __u32 logsectsize; /* log sector size, bytes */ __u32 rtsectsize; /* realtime sector size, bytes */ __u32 dirblocksize; /* directory block size, bytes */ __u32 logsunit; /* log stripe unit, bytes */ } xfs_fsop_geom_t; /* Output for XFS_FS_COUNTS */ typedef struct xfs_fsop_counts { __u64 freedata; /* free data section blocks */ __u64 freertx; /* free rt extents */ __u64 freeino; /* free inodes */ __u64 allocino; /* total allocated inodes */ } xfs_fsop_counts_t; /* Input/Output for XFS_GET_RESBLKS and XFS_SET_RESBLKS */ typedef struct xfs_fsop_resblks { __u64 resblks; __u64 resblks_avail; } xfs_fsop_resblks_t; #define XFS_FSOP_GEOM_VERSION 0 #define XFS_FSOP_GEOM_FLAGS_ATTR 0x0001 /* attributes in use */ #define XFS_FSOP_GEOM_FLAGS_NLINK 0x0002 /* 32-bit nlink values */ #define XFS_FSOP_GEOM_FLAGS_QUOTA 0x0004 /* quotas enabled */ #define XFS_FSOP_GEOM_FLAGS_IALIGN 0x0008 /* inode alignment */ #define XFS_FSOP_GEOM_FLAGS_DALIGN 0x0010 /* large data alignment */ #define XFS_FSOP_GEOM_FLAGS_SHARED 0x0020 /* read-only shared */ #define XFS_FSOP_GEOM_FLAGS_EXTFLG 0x0040 /* special extent flag */ #define XFS_FSOP_GEOM_FLAGS_DIRV2 0x0080 /* directory version 2 */ #define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ #define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ #define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */ #define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ /* * Minimum and maximum sizes need for growth checks */ #define XFS_MIN_AG_BLOCKS 64 #define XFS_MIN_LOG_BLOCKS 512ULL #define XFS_MAX_LOG_BLOCKS (1024 * 1024ULL) #define XFS_MIN_LOG_BYTES (10 * 1024 * 1024ULL) /* keep the maximum size under 2^31 by a small amount */ #define XFS_MAX_LOG_BYTES \ ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES) /* * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT */ typedef struct xfs_growfs_data { __u64 newblocks; /* new data subvol size, fsblocks */ __u32 imaxpct; /* new inode space percentage limit */ } xfs_growfs_data_t; typedef struct xfs_growfs_log { __u32 newblocks; /* new log size, fsblocks */ __u32 isint; /* 1 if new log is internal */ } xfs_growfs_log_t; typedef struct xfs_growfs_rt { __u64 newblocks; /* new realtime size, fsblocks */ __u32 extsize; /* new realtime extent size, fsblocks */ } xfs_growfs_rt_t; /* * Structures returned from ioctl XFS_IOC_FSBULKSTAT & XFS_IOC_FSBULKSTAT_SINGLE */ typedef struct xfs_bstime { time_t tv_sec; /* seconds */ __s32 tv_nsec; /* and nanoseconds */ } xfs_bstime_t; typedef struct xfs_bstat { __u64 bs_ino; /* inode number */ __u16 bs_mode; /* type and mode */ __u16 bs_nlink; /* number of links */ __u32 bs_uid; /* user id */ __u32 bs_gid; /* group id */ __u32 bs_rdev; /* device value */ __s32 bs_blksize; /* block size */ __s64 bs_size; /* file size */ xfs_bstime_t bs_atime; /* access time */ xfs_bstime_t bs_mtime; /* modify time */ xfs_bstime_t bs_ctime; /* inode change time */ int64_t bs_blocks; /* number of blocks */ __u32 bs_xflags; /* extended flags */ __s32 bs_extsize; /* extent size */ __s32 bs_extents; /* number of extents */ __u32 bs_gen; /* generation count */ __u16 bs_projid_lo; /* lower part of project id */ #define bs_projid bs_projid_lo /* (previously just bs_projid) */ __u16 bs_forkoff; /* inode fork offset in bytes */ __u16 bs_projid_hi; /* higher part of project id */ unsigned char bs_pad[10]; /* pad space, unused */ __u32 bs_dmevmask; /* DMIG event mask */ __u16 bs_dmstate; /* DMIG state info */ __u16 bs_aextents; /* attribute number of extents */ } xfs_bstat_t; /* * The user-level BulkStat Request interface structure. */ typedef struct xfs_fsop_bulkreq { __u64 __user *lastip; /* last inode # pointer */ __s32 icount; /* count of entries in buffer */ void __user *ubuffer;/* user buffer for inode desc. */ __s32 __user *ocount; /* output count pointer */ } xfs_fsop_bulkreq_t; /* * Structures returned from xfs_inumbers routine (XFS_IOC_FSINUMBERS). */ typedef struct xfs_inogrp { __u64 xi_startino; /* starting inode number */ __s32 xi_alloccount; /* # bits set in allocmask */ __u64 xi_allocmask; /* mask of allocated inodes */ } xfs_inogrp_t; /* * Error injection. */ typedef struct xfs_error_injection { __s32 fd; __s32 errtag; } xfs_error_injection_t; /* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq { __u32 fd; /* fd for FD_TO_HANDLE */ void __user *path; /* user pathname */ __u32 oflags; /* open flags */ void __user *ihandle;/* user supplied handle */ __u32 ihandlen; /* user supplied length */ void __user *ohandle;/* user buffer for handle */ __u32 __user *ohandlen;/* user buffer length */ } xfs_fsop_handlereq_t; /* * Compound structures for passing args through Handle Request interfaces * xfs_fssetdm_by_handle, xfs_attrlist_by_handle, xfs_attrmulti_by_handle * - ioctls: XFS_IOC_FSSETDM_BY_HANDLE, XFS_IOC_ATTRLIST_BY_HANDLE, and * XFS_IOC_ATTRMULTI_BY_HANDLE */ typedef struct xfs_fsop_setdm_handlereq { struct xfs_fsop_handlereq hreq; /* handle information */ struct fsdmidata __user *data; /* DMAPI data */ } xfs_fsop_setdm_handlereq_t; typedef struct xfs_attrlist_cursor { __u32 opaque[4]; } xfs_attrlist_cursor_t; typedef struct xfs_fsop_attrlist_handlereq { struct xfs_fsop_handlereq hreq; /* handle interface structure */ struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */ __u32 flags; /* which namespace to use */ __u32 buflen; /* length of buffer supplied */ void __user *buffer; /* returned names */ } xfs_fsop_attrlist_handlereq_t; typedef struct xfs_attr_multiop { __u32 am_opcode; #define ATTR_OP_GET 1 /* return the indicated attr's value */ #define ATTR_OP_SET 2 /* set/create the indicated attr/value pair */ #define ATTR_OP_REMOVE 3 /* remove the indicated attr */ __s32 am_error; void __user *am_attrname; void __user *am_attrvalue; __u32 am_length; __u32 am_flags; } xfs_attr_multiop_t; typedef struct xfs_fsop_attrmulti_handlereq { struct xfs_fsop_handlereq hreq; /* handle interface structure */ __u32 opcount;/* count of following multiop */ struct xfs_attr_multiop __user *ops; /* attr_multi data */ } xfs_fsop_attrmulti_handlereq_t; /* * per machine unique filesystem identifier types. */ typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */ typedef struct xfs_fid { __u16 fid_len; /* length of remainder */ __u16 fid_pad; __u32 fid_gen; /* generation number */ __u64 fid_ino; /* 64 bits inode number */ } xfs_fid_t; typedef struct xfs_handle { union { __s64 align; /* force alignment of ha_fid */ xfs_fsid_t _ha_fsid; /* unique file system identifier */ } ha_u; xfs_fid_t ha_fid; /* file system specific file ID */ } xfs_handle_t; #define ha_fsid ha_u._ha_fsid #define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.fid_pad \ - (char *) &(handle)) \ + (handle).ha_fid.fid_len) /* * Flags for going down operation */ #define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ #define XFS_FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ /* * ioctl commands that are used by Linux filesystems */ #define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS #define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS #define XFS_IOC_GETVERSION FS_IOC_GETVERSION /* * ioctl commands that replace IRIX fcntl()'s * For 'documentation' purposed more than anything else, * the "cmd #" field reflects the IRIX fcntl number. */ #define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64) #define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64) #define XFS_IOC_DIOINFO _IOR ('X', 30, struct dioattr) #define XFS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr) #define XFS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr) #define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64) #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64) #define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap) #define XFS_IOC_FSSETDM _IOW ('X', 39, struct fsdmidata) #define XFS_IOC_RESVSP _IOW ('X', 40, struct xfs_flock64) #define XFS_IOC_UNRESVSP _IOW ('X', 41, struct xfs_flock64) #define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64) #define XFS_IOC_UNRESVSP64 _IOW ('X', 43, struct xfs_flock64) #define XFS_IOC_GETBMAPA _IOWR('X', 44, struct getbmap) #define XFS_IOC_FSGETXATTRA _IOR ('X', 45, struct fsxattr) /* XFS_IOC_SETBIOSIZE ---- deprecated 46 */ /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) /* * ioctl commands that replace IRIX syssgi()'s */ #define XFS_IOC_FSGEOMETRY_V1 _IOR ('X', 100, struct xfs_fsop_geom_v1) #define XFS_IOC_FSBULKSTAT _IOWR('X', 101, struct xfs_fsop_bulkreq) #define XFS_IOC_FSBULKSTAT_SINGLE _IOWR('X', 102, struct xfs_fsop_bulkreq) #define XFS_IOC_FSINUMBERS _IOWR('X', 103, struct xfs_fsop_bulkreq) #define XFS_IOC_PATH_TO_FSHANDLE _IOWR('X', 104, struct xfs_fsop_handlereq) #define XFS_IOC_PATH_TO_HANDLE _IOWR('X', 105, struct xfs_fsop_handlereq) #define XFS_IOC_FD_TO_HANDLE _IOWR('X', 106, struct xfs_fsop_handlereq) #define XFS_IOC_OPEN_BY_HANDLE _IOWR('X', 107, struct xfs_fsop_handlereq) #define XFS_IOC_READLINK_BY_HANDLE _IOWR('X', 108, struct xfs_fsop_handlereq) #define XFS_IOC_SWAPEXT _IOWR('X', 109, struct xfs_swapext) #define XFS_IOC_FSGROWFSDATA _IOW ('X', 110, struct xfs_growfs_data) #define XFS_IOC_FSGROWFSLOG _IOW ('X', 111, struct xfs_growfs_log) #define XFS_IOC_FSGROWFSRT _IOW ('X', 112, struct xfs_growfs_rt) #define XFS_IOC_FSCOUNTS _IOR ('X', 113, struct xfs_fsop_counts) #define XFS_IOC_SET_RESBLKS _IOWR('X', 114, struct xfs_fsop_resblks) #define XFS_IOC_GET_RESBLKS _IOR ('X', 115, struct xfs_fsop_resblks) #define XFS_IOC_ERROR_INJECTION _IOW ('X', 116, struct xfs_error_injection) #define XFS_IOC_ERROR_CLEARALL _IOW ('X', 117, struct xfs_error_injection) /* XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118 */ /* XFS_IOC_FREEZE -- FIFREEZE 119 */ /* XFS_IOC_THAW -- FITHAW 120 */ #define XFS_IOC_FREEZE _IOWR('X', 119, int) #define XFS_IOC_THAW _IOWR('X', 120, int) #define XFS_IOC_FSSETDM_BY_HANDLE _IOW ('X', 121, struct xfs_fsop_setdm_handlereq) #define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq) #define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq) #define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom) #define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t) /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ #ifndef HAVE_BBMACROS /* * Block I/O parameterization. A basic block (BB) is the lowest size of * filesystem allocation, and must equal 512. Length units given to bio * routines are in BB's. */ #define BBSHIFT 9 #define BBSIZE (1<> BBSHIFT) #define BTOBBT(bytes) ((__u64)(bytes) >> BBSHIFT) #define BBTOB(bbs) ((bbs) << BBSHIFT) #endif /* * Project quota id helpers (previously projid was 16bit only * and using two 16bit values to hold new 32bit projid was choosen * to retain compatibility with "old" filesystems). */ static inline __uint32_t bstat_get_projid(struct xfs_bstat *bs) { return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo; } #endif /* __XFS_FS_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_log_recover.h0000664000000000000000000000372611650373061016610 0ustar /* * Copyright (c) 2000,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_LOG_RECOVER_H__ #define __XFS_LOG_RECOVER_H__ /* * Macros, structures, prototypes for internal log manager use. */ #define XLOG_RHASH_BITS 4 #define XLOG_RHASH_SIZE 16 #define XLOG_RHASH_SHIFT 2 #define XLOG_RHASH(tid) \ ((((__uint32_t)tid)>>XLOG_RHASH_SHIFT) & (XLOG_RHASH_SIZE-1)) #define XLOG_MAX_REGIONS_IN_ITEM (XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK / 2 + 1) /* * item headers are in ri_buf[0]. Additional buffers follow. */ typedef struct xlog_recover_item { struct list_head ri_list; int ri_type; int ri_cnt; /* count of regions found */ int ri_total; /* total regions */ xfs_log_iovec_t *ri_buf; /* ptr to regions buffer */ } xlog_recover_item_t; struct xlog_tid; typedef struct xlog_recover { struct hlist_node r_list; xlog_tid_t r_log_tid; /* log's transaction id */ xfs_trans_header_t r_theader; /* trans header for partial */ int r_state; /* not needed */ xfs_lsn_t r_lsn; /* xact lsn */ struct list_head r_itemq; /* q for items */ } xlog_recover_t; #define ITEM_TYPE(i) (*(ushort *)(i)->ri_buf[0].i_addr) /* * This is the number of entries in the l_buf_cancel_table used during * recovery. */ #define XLOG_BC_TABLE_SIZE 64 #define XLOG_RECOVER_PASS1 1 #define XLOG_RECOVER_PASS2 2 #endif /* __XFS_LOG_RECOVER_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_metadump.h0000664000000000000000000000200211140033220016060 0ustar /* * Copyright (c) 2007 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _XFS_METADUMP_H_ #define _XFS_METADUMP_H_ #define XFS_MD_MAGIC 0x5846534d /* 'XFSM' */ typedef struct xfs_metablock { __be32 mb_magic; __be16 mb_count; __uint8_t mb_blocklog; __uint8_t mb_reserved; /* followed by an array of xfs_daddr_t */ } xfs_metablock_t; #endif /* _XFS_METADUMP_H_ */ xfsprogs-3.1.9ubuntu2/include/xfs_quota.h0000664000000000000000000003531311650373061015430 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_QUOTA_H__ #define __XFS_QUOTA_H__ struct xfs_trans; /* * The ondisk form of a dquot structure. */ #define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */ #define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */ /* * uid_t and gid_t are hard-coded to 32 bits in the inode. * Hence, an 'id' in a dquot is 32 bits.. */ typedef __uint32_t xfs_dqid_t; /* * Even though users may not have quota limits occupying all 64-bits, * they may need 64-bit accounting. Hence, 64-bit quota-counters, * and quota-limits. This is a waste in the common case, but hey ... */ typedef __uint64_t xfs_qcnt_t; typedef __uint16_t xfs_qwarncnt_t; /* * This is the main portion of the on-disk representation of quota * information for a user. This is the q_core of the xfs_dquot_t that * is kept in kernel memory. We pad this with some more expansion room * to construct the on disk structure. */ typedef struct xfs_disk_dquot { __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ __u8 d_version; /* dquot version */ __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */ __be32 d_id; /* user,project,group id */ __be64 d_blk_hardlimit;/* absolute limit on disk blks */ __be64 d_blk_softlimit;/* preferred limit on disk blks */ __be64 d_ino_hardlimit;/* maximum # allocated inodes */ __be64 d_ino_softlimit;/* preferred inode limit */ __be64 d_bcount; /* disk blocks owned by the user */ __be64 d_icount; /* inodes owned by the user */ __be32 d_itimer; /* zero if within inode limits if not, this is when we refuse service */ __be32 d_btimer; /* similar to above; for disk blocks */ __be16 d_iwarns; /* warnings issued wrt num inodes */ __be16 d_bwarns; /* warnings issued wrt disk blocks */ __be32 d_pad0; /* 64 bit align */ __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */ __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */ __be64 d_rtbcount; /* realtime blocks owned */ __be32 d_rtbtimer; /* similar to above; for RT disk blocks */ __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */ __be16 d_pad; } xfs_disk_dquot_t; /* * This is what goes on disk. This is separated from the xfs_disk_dquot because * carrying the unnecessary padding would be a waste of memory. */ typedef struct xfs_dqblk { xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */ char dd_fill[32]; /* filling for posterity */ } xfs_dqblk_t; /* * flags for q_flags field in the dquot. */ #define XFS_DQ_USER 0x0001 /* a user quota */ #define XFS_DQ_PROJ 0x0002 /* project quota */ #define XFS_DQ_GROUP 0x0004 /* a group quota */ #define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ #define XFS_DQ_WANT 0x0010 /* for lookup/reclaim race */ #define XFS_DQ_INACTIVE 0x0020 /* dq off mplist & hashlist */ #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) #define XFS_DQ_FLAGS \ { XFS_DQ_USER, "USER" }, \ { XFS_DQ_PROJ, "PROJ" }, \ { XFS_DQ_GROUP, "GROUP" }, \ { XFS_DQ_DIRTY, "DIRTY" }, \ { XFS_DQ_WANT, "WANT" }, \ { XFS_DQ_INACTIVE, "INACTIVE" } /* * In the worst case, when both user and group quotas are on, * we can have a max of three dquots changing in a single transaction. */ #define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3) /* * These are the structures used to lay out dquots and quotaoff * records on the log. Quite similar to those of inodes. */ /* * log format struct for dquots. * The first two fields must be the type and size fitting into * 32 bits : log_recovery code assumes that. */ typedef struct xfs_dq_logformat { __uint16_t qlf_type; /* dquot log item type */ __uint16_t qlf_size; /* size of this item */ xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */ __int64_t qlf_blkno; /* blkno of dquot buffer */ __int32_t qlf_len; /* len of dquot buffer */ __uint32_t qlf_boffset; /* off of dquot in buffer */ } xfs_dq_logformat_t; /* * log format struct for QUOTAOFF records. * The first two fields must be the type and size fitting into * 32 bits : log_recovery code assumes that. * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer * to the first and ensures that the first logitem is taken out of the AIL * only when the last one is securely committed. */ typedef struct xfs_qoff_logformat { unsigned short qf_type; /* quotaoff log item type */ unsigned short qf_size; /* size of this item */ unsigned int qf_flags; /* USR and/or GRP */ char qf_pad[12]; /* padding for future */ } xfs_qoff_logformat_t; /* * Disk quotas status in m_qflags, and also sb_qflags. 16 bits. */ #define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ #define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ #define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ #define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */ #define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */ #define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */ #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ /* * Quota Accounting/Enforcement flags */ #define XFS_ALL_QUOTA_ACCT \ (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) #define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) #define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) #define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD) /* * Incore only flags for quotaoff - these bits get cleared when quota(s) * are in the process of getting turned off. These flags are in m_qflags but * never in sb_qflags. */ #define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */ #define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */ #define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */ /* * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees * quota will be not be switched off as long as that inode lock is held. */ #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ XFS_GQUOTA_ACTIVE | \ XFS_PQUOTA_ACTIVE)) #define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ XFS_PQUOTA_ACTIVE)) #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) #define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) /* * Flags to tell various functions what to do. Not all of these are meaningful * to a single function. None of these XFS_QMOPT_* flags are meant to have * persistent values (ie. their values can and will change between versions) */ #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ #define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ #define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ #define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ #define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be * modified. */ #define XFS_QMOPT_RES_REGBLKS 0x0010000 #define XFS_QMOPT_RES_RTBLKS 0x0020000 #define XFS_QMOPT_BCOUNT 0x0040000 #define XFS_QMOPT_ICOUNT 0x0080000 #define XFS_QMOPT_RTBCOUNT 0x0100000 #define XFS_QMOPT_DELBCOUNT 0x0200000 #define XFS_QMOPT_DELRTBCOUNT 0x0400000 #define XFS_QMOPT_RES_INOS 0x0800000 /* * flags for dqalloc. */ #define XFS_QMOPT_INHERIT 0x1000000 /* * flags to xfs_trans_mod_dquot. */ #define XFS_TRANS_DQ_RES_BLKS XFS_QMOPT_RES_REGBLKS #define XFS_TRANS_DQ_RES_RTBLKS XFS_QMOPT_RES_RTBLKS #define XFS_TRANS_DQ_RES_INOS XFS_QMOPT_RES_INOS #define XFS_TRANS_DQ_BCOUNT XFS_QMOPT_BCOUNT #define XFS_TRANS_DQ_DELBCOUNT XFS_QMOPT_DELBCOUNT #define XFS_TRANS_DQ_ICOUNT XFS_QMOPT_ICOUNT #define XFS_TRANS_DQ_RTBCOUNT XFS_QMOPT_RTBCOUNT #define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT #define XFS_QMOPT_QUOTALL \ (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) #ifdef __KERNEL__ /* * This check is done typically without holding the inode lock; * that may seem racy, but it is harmless in the context that it is used. * The inode cannot go inactive as long a reference is kept, and * therefore if dquot(s) were attached, they'll stay consistent. * If, for example, the ownership of the inode changes while * we didn't have the inode locked, the appropriate dquot(s) will be * attached atomically. */ #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ (ip)->i_udquot == NULL) || \ (XFS_IS_OQUOTA_ON(mp) && \ (ip)->i_gdquot == NULL)) #define XFS_QM_NEED_QUOTACHECK(mp) \ ((XFS_IS_UQUOTA_ON(mp) && \ (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \ (XFS_IS_GQUOTA_ON(mp) && \ ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \ (XFS_IS_PQUOTA_ON(mp) && \ ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT)))) #define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) #define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ XFS_GQUOTA_ACCT) /* * The structure kept inside the xfs_trans_t keep track of dquot changes * within a transaction and apply them later. */ typedef struct xfs_dqtrx { struct xfs_dquot *qt_dquot; /* the dquot this refers to */ ulong qt_blk_res; /* blks reserved on a dquot */ ulong qt_blk_res_used; /* blks used from the reservation */ ulong qt_ino_res; /* inode reserved on a dquot */ ulong qt_ino_res_used; /* inodes used from the reservation */ long qt_bcount_delta; /* dquot blk count changes */ long qt_delbcnt_delta; /* delayed dquot blk count changes */ long qt_icount_delta; /* dquot inode count changes */ ulong qt_rtblk_res; /* # blks reserved on a dquot */ ulong qt_rtblk_res_used;/* # blks used from reservation */ long qt_rtbcount_delta;/* dquot realtime blk changes */ long qt_delrtb_delta; /* delayed RT blk count changes */ } xfs_dqtrx_t; extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); extern int xfs_mount_reset_sbqflags(struct xfs_mount *); #endif /* __KERNEL__ */ #ifdef CONFIG_XFS_QUOTA extern void xfs_trans_dup_dqinfo(struct xfs_trans *, struct xfs_trans *); extern void xfs_trans_free_dqinfo(struct xfs_trans *); extern void xfs_trans_mod_dquot_byino(struct xfs_trans *, struct xfs_inode *, uint, long); extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *); extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *); extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *, struct xfs_inode *, long, long, uint); extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *, struct xfs_mount *, struct xfs_dquot *, struct xfs_dquot *, long, long, uint); extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint, struct xfs_dquot **, struct xfs_dquot **); extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *, struct xfs_dquot *, struct xfs_dquot *); extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **); extern struct xfs_dquot *xfs_qm_vop_chown(struct xfs_trans *, struct xfs_inode *, struct xfs_dquot **, struct xfs_dquot *); extern int xfs_qm_vop_chown_reserve(struct xfs_trans *, struct xfs_inode *, struct xfs_dquot *, struct xfs_dquot *, uint); extern int xfs_qm_dqattach(struct xfs_inode *, uint); extern int xfs_qm_dqattach_locked(struct xfs_inode *, uint); extern void xfs_qm_dqdetach(struct xfs_inode *); extern void xfs_qm_dqrele(struct xfs_dquot *); extern void xfs_qm_statvfs(struct xfs_inode *, struct kstatfs *); extern int xfs_qm_sync(struct xfs_mount *, int); extern int xfs_qm_newmount(struct xfs_mount *, uint *, uint *); extern void xfs_qm_mount_quotas(struct xfs_mount *); extern void xfs_qm_unmount(struct xfs_mount *); extern void xfs_qm_unmount_quotas(struct xfs_mount *); #else #define xfs_qm_vop_dqalloc(ip, uid, gid, prid, flags, udqp, gdqp) ({ \ *(udqp) = NULL; \ *(gdqp) = NULL; \ 0; \ }) #define xfs_trans_dup_dqinfo(tp, tp2) #define xfs_trans_free_dqinfo(tp) #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) #define xfs_trans_apply_dquot_deltas(tp) #define xfs_trans_unreserve_and_mod_dquots(tp) #define xfs_trans_reserve_quota_nblks(tp, ip, blks, inos, flg) (0) #define xfs_trans_reserve_quota_bydquots(tp, mp, uqp, gqp, blks, inos, flg) (0) #define xfs_qm_vop_create_dqattach(tp, ip, u, g) #define xfs_qm_vop_rename_dqattach(it) (0) #define xfs_qm_vop_chown(tp, ip, old, new) (NULL) #define xfs_qm_vop_chown_reserve(tp, ip, u, g, fl) (0) #define xfs_qm_dqattach(ip, fl) (0) #define xfs_qm_dqattach_locked(ip, fl) (0) #define xfs_qm_dqdetach(ip) #define xfs_qm_dqrele(d) #define xfs_qm_statvfs(ip, s) #define xfs_qm_sync(mp, flags) (0) #define xfs_qm_newmount(mp, a, b) (0) #define xfs_qm_mount_quotas(mp) #define xfs_qm_unmount(mp) #define xfs_qm_unmount_quotas(mp) #endif /* CONFIG_XFS_QUOTA */ #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), -(ninos), flags) #define xfs_trans_reserve_quota(tp, mp, ud, gd, nb, ni, f) \ xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, nb, ni, \ f | XFS_QMOPT_RES_REGBLKS) #endif /* __XFS_QUOTA_H__ */ xfsprogs-3.1.9ubuntu2/include/jdm.h0000664000000000000000000000460211140033220014146 0ustar /* * Copyright (c) 2000-2002, 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __JDM_H__ #define __JDM_H__ typedef int intgen_t; typedef void jdm_fshandle_t; /* filesystem handle */ typedef void jdm_filehandle_t; /* filehandle */ struct xfs_bstat; struct attrlist_cursor; struct parent; extern jdm_fshandle_t * jdm_getfshandle( char *mntpnt); extern void jdm_new_filehandle( jdm_filehandle_t **handlep, /* new filehandle */ size_t *hlen, /* new filehandle size */ jdm_fshandle_t *fshandlep, /* filesystem filehandle */ struct xfs_bstat *sp); /* bulkstat info */ extern void jdm_delete_filehandle( jdm_filehandle_t *handlep,/* filehandle to delete */ size_t hlen); /* filehandle size */ extern intgen_t jdm_open( jdm_fshandle_t *fshandlep, struct xfs_bstat *sp, intgen_t oflags); extern intgen_t jdm_readlink( jdm_fshandle_t *fshandlep, struct xfs_bstat *sp, char *bufp, size_t bufsz); extern intgen_t jdm_attr_multi( jdm_fshandle_t *fshp, xfs_bstat_t *statp, char *bufp, int rtrvcnt, int flags); extern intgen_t jdm_attr_list( jdm_fshandle_t *fshp, xfs_bstat_t *statp, char *bufp, size_t bufsz, int flags, struct attrlist_cursor *cursor); extern int jdm_parents( jdm_fshandle_t *fshp, xfs_bstat_t *statp, struct parent *bufp, size_t bufsz, unsigned int *count); extern int jdm_parentpaths( jdm_fshandle_t *fshp, xfs_bstat_t *statp, struct parent *bufp, size_t bufsz, unsigned int *count); /* macro for determining the size of a structure member */ #define sizeofmember( t, m ) sizeof( ( ( t * )0 )->m ) /* macro for calculating the offset of a structure member */ #define offsetofmember( t, m ) ( ( size_t )( char * )&( ( ( t * )0 )->m ) ) #endif /* __JDM_H__ */ xfsprogs-3.1.9ubuntu2/include/irix.h0000664000000000000000000003070411307015331014361 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_IRIX_H__ #define __XFS_IRIX_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __int8_t char #define __int16_t short #define __uint8_t unsigned char #define __uint16_t unsigned short #define loff_t off64_t typedef off64_t xfs_off_t; typedef __int64_t xfs_ino_t; typedef __int32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; typedef char* xfs_caddr_t; #define xfs_flock64 flock64 #define xfs_flock64_t struct flock64 typedef struct xfs_error_injection { __int32_t fd; __int32_t errtag; } xfs_error_injection_t; /* --- xfs_fsop_*req - request data structures --- */ typedef struct xfs_fsop_bulkreq { ino64_t *lastip; __int32_t icount; xfs_bstat_t *ubuffer; __int32_t *ocount; } xfs_fsop_bulkreq_t; typedef struct xfs_fsop_handlereq { __u32 fd; /* fd for FD_TO_HANDLE */ void *path; /* user pathname */ __u32 oflags; /* open flags */ void *ihandle; /* user supplied handle */ __u32 ihandlen; /* user supplied length */ void *ohandle; /* user buffer for handle */ __u32 *ohandlen; /* user buffer length */ } xfs_fsop_handlereq_t; typedef struct xfs_fsop_setdm_handlereq { struct xfs_fsop_handlereq hreq; /* handle information */ struct fsdmidata *data; /* DMAPI data */ } xfs_fsop_setdm_handlereq_t; typedef struct xfs_attrlist_cursor { __u32 opaque[4]; } xfs_attrlist_cursor_t; typedef struct xfs_fsop_attrlist_handlereq { struct xfs_fsop_handlereq hreq; /* handle interface structure */ struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */ __u32 flags; /* which namespace to use */ __u32 buflen; /* length of buffer supplied */ void *buffer; /* returned names */ } xfs_fsop_attrlist_handlereq_t; typedef struct xfs_fsop_getparents_handlereq { struct xfs_fsop_handlereq hreq; /* handle interface structure */ struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */ __u32 buflen; /* length of buffer supplied */ void *buffer; /* returned data */ __u32 *ocount; /* return number of links */ __u32 *omore; /* return whether more to come */ } xfs_fsop_getparents_handlereq_t; typedef struct xfs_attr_multiop { __u32 am_opcode; __s32 am_error; void *am_attrname; void *am_attrvalue; __u32 am_length; __u32 am_flags; } xfs_attr_multiop_t; typedef struct xfs_fsop_attrmulti_handlereq { struct xfs_fsop_handlereq hreq; /* handle interface structure */ __u32 opcount;/* count of following multiop */ struct xfs_attr_multiop *ops; /* attr_multi data */ } xfs_fsop_attrmulti_handlereq_t; /* start doing packed stuctures here */ #define HAVE_FORMAT32 1 #pragma pack 1 typedef struct xfs_inode_log_format_32 { __u16 ilf_type; /* inode log item type */ __u16 ilf_size; /* size of this item */ __u32 ilf_fields; /* flags for fields logged */ __u16 ilf_asize; /* size of attr d/ext/root */ __u16 ilf_dsize; /* size of data/ext/root */ __u64 ilf_ino; /* inode number */ union { __u32 ilfu_rdev; /* rdev value for dev inode*/ uuid_t ilfu_uuid; /* mount point value */ } ilf_u; __s64 ilf_blkno; /* blkno of inode buffer */ __s32 ilf_len; /* len of inode buffer */ __s32 ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_32_t; typedef struct xfs_extent_32 { __u64 ext_start; __u32 ext_len; } xfs_extent_32_t; typedef struct xfs_efi_log_format_32 { __u16 efi_type; /* efi log item type */ __u16 efi_size; /* size of this item */ __u32 efi_nextents; /* # extents to free */ __u64 efi_id; /* efi identifier */ xfs_extent_32_t efi_extents[1]; /* array of extents to free */ } xfs_efi_log_format_32_t; typedef struct xfs_efd_log_format_32 { __u16 efd_type; /* efd log item type */ __u16 efd_size; /* size of this item */ __u32 efd_nextents; /* # of extents freed */ __u64 efd_efi_id; /* id of corresponding efi */ xfs_extent_32_t efd_extents[1]; /* array of extents freed */ } xfs_efd_log_format_32_t; #pragma pack 0 /* end of packed stuctures */ #include #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN /* Map some gcc macros for the MipsPRO compiler */ #ifndef __GNUC__ #define __builtin_constant_p(x) (0) #define __FUNCTION__ "XFS" #define __sgi__ __sgi #define __inline__ __inline #define inline __inline #endif #define constpp char * const * /*ARGSUSED*/ static __inline__ int xfsctl(const char *path, int fd, int cmd, void *arg) { if (cmd >= 0 && cmd < XFS_FSOPS_COUNT) { /* * We have a problem in that xfsctl takes 1 arg but * some sgi xfs ops take an input arg and/or an output arg * So have to special case the ops to decide if xfsctl arg * is an input or an output argument. */ if (cmd == XFS_FS_GOINGDOWN) return syssgi(SGI_XFS_FSOPERATIONS, fd, cmd, arg, 0); return syssgi(SGI_XFS_FSOPERATIONS, fd, cmd, 0, arg); } switch (cmd) { case SGI_FS_INUMBERS: case SGI_FS_BULKSTAT: return syssgi(cmd, fd, ((xfs_fsop_bulkreq_t*)arg)->lastip, ((xfs_fsop_bulkreq_t*)arg)->icount, ((xfs_fsop_bulkreq_t*)arg)->ubuffer, ((xfs_fsop_bulkreq_t*)arg)->ocount); case SGI_FS_BULKSTAT_SINGLE: return syssgi(SGI_FS_BULKSTAT_SINGLE, fd, ((xfs_fsop_bulkreq_t*)arg)->lastip, ((xfs_fsop_bulkreq_t*)arg)->ubuffer); case SGI_XFS_INJECT_ERROR: return syssgi(SGI_XFS_INJECT_ERROR, ((xfs_error_injection_t*)arg)->errtag, fd); case SGI_XFS_CLEARALL_ERROR: return syssgi(SGI_XFS_CLEARALL_ERROR, fd); case SGI_PATH_TO_HANDLE: case SGI_PATH_TO_FSHANDLE: return syssgi(cmd, ((xfs_fsop_handlereq_t*)arg)->path, ((xfs_fsop_handlereq_t*)arg)->ohandle, ((xfs_fsop_handlereq_t*)arg)->ohandlen); case SGI_FD_TO_HANDLE: return syssgi(cmd, ((xfs_fsop_handlereq_t*)arg)->fd, ((xfs_fsop_handlereq_t*)arg)->ohandle, ((xfs_fsop_handlereq_t*)arg)->ohandlen); case SGI_OPEN_BY_HANDLE: return syssgi(cmd, ((xfs_fsop_handlereq_t*)arg)->ihandle, ((xfs_fsop_handlereq_t*)arg)->ihandlen, ((xfs_fsop_handlereq_t*)arg)->oflags); case SGI_READLINK_BY_HANDLE: return syssgi(cmd, ((xfs_fsop_handlereq_t*)arg)->ihandle, ((xfs_fsop_handlereq_t*)arg)->ihandlen, ((xfs_fsop_handlereq_t*)arg)->ohandle, ((xfs_fsop_handlereq_t*)arg)->ohandlen); case SGI_ATTR_LIST_BY_HANDLE: return syssgi(cmd, ((xfs_fsop_attrlist_handlereq_t*)arg)->hreq.ihandle, ((xfs_fsop_attrlist_handlereq_t*)arg)->hreq.ihandlen, ((xfs_fsop_attrlist_handlereq_t*)arg)->buffer, ((xfs_fsop_attrlist_handlereq_t*)arg)->buflen, ((xfs_fsop_attrlist_handlereq_t*)arg)->flags, &(((xfs_fsop_attrlist_handlereq_t*)arg)->pos)); case SGI_XFS_GETPARENTS: case SGI_XFS_GETPARENTPATHS: return syssgi(cmd, ((xfs_fsop_getparents_handlereq_t*)arg)->hreq.ihandle, ((xfs_fsop_getparents_handlereq_t*)arg)->hreq.ihandlen, ((xfs_fsop_getparents_handlereq_t*)arg)->buffer, ((xfs_fsop_getparents_handlereq_t*)arg)->buflen, &(((xfs_fsop_getparents_handlereq_t*)arg)->pos), ((xfs_fsop_getparents_handlereq_t*)arg)->ocount, ((xfs_fsop_getparents_handlereq_t*)arg)->omore); case SGI_ATTR_MULTI_BY_HANDLE: return syssgi(cmd, ((xfs_fsop_attrmulti_handlereq_t*)arg)->hreq.ihandle, ((xfs_fsop_attrmulti_handlereq_t*)arg)->hreq.ihandlen, ((xfs_fsop_attrmulti_handlereq_t*)arg)->ops, ((xfs_fsop_attrmulti_handlereq_t*)arg)->opcount, ((xfs_fsop_attrmulti_handlereq_t*)arg)->hreq.oflags); case SGI_FSSETDM_BY_HANDLE: return syssgi(cmd, ((xfs_fsop_setdm_handlereq_t*)arg)->hreq.ihandle, ((xfs_fsop_setdm_handlereq_t*)arg)->hreq.ihandlen, ((xfs_fsop_setdm_handlereq_t*)arg)->data); } return fcntl(fd, cmd, arg); } static __inline__ int platform_test_xfs_fd(int fd) { struct statvfs sbuf; if (fstatvfs(fd, &sbuf) < 0) return 0; return strncmp(sbuf.f_basetype, "xfs", 4) == 0; } static __inline__ int platform_test_xfs_path(const char *path) { struct statvfs sbuf; if (statvfs(path, &sbuf) < 0) return 0; return strncmp(sbuf.f_basetype, "xfs", 4) == 0; } static __inline__ int platform_fstatfs(int fd, struct statfs *buf) { return fstatfs(fd, buf, sizeof(struct statfs), 0); } static __inline__ void platform_getoptreset(void) { getoptreset(); } static __inline__ int platform_uuid_compare(uuid_t *uu1, uuid_t *uu2) { uint_t status; return uuid_compare(uu1, uu2, &status); } static __inline__ void platform_uuid_unparse(uuid_t *uu, char *buffer) { uint_t status; char *s; uuid_to_string(uu, &s, &status); if (status == uuid_s_ok) strcpy(buffer, s); else buffer[0] = '\0'; free(s); } static __inline__ int platform_uuid_parse(char *buffer, uuid_t *uu) { uint_t status; uuid_from_string(buffer, uu, &status); return (status == uuid_s_ok); } static __inline__ int platform_uuid_is_null(uuid_t *uu) { uint status; return uuid_is_nil(uu, &status); } static __inline__ void platform_uuid_generate(uuid_t *uu) { uint_t status; uuid_create(uu, &status); } static __inline__ void platform_uuid_clear(uuid_t *uu) { uint_t status; uuid_create_nil(uu, &status); } static __inline__ void platform_uuid_copy(uuid_t *dst, uuid_t *src) { memcpy(dst, src, sizeof(uuid_t)); } static __inline__ int platform_discard_blocks(int fd, uint64_t start, uint64_t len) { return 0; } static __inline__ char * strsep(char **s, const char *ct) { char *sbegin = *s, *end; if (!sbegin) return NULL; end = strpbrk(sbegin, ct); if (end) *end++ = '\0'; *s = end; return sbegin; } #define HAVE_DIOATTR 1 #define HAVE_FSXATTR 1 #define HAVE_GETBMAP 1 #define HAVE_GETBMAPX 1 #define HAVE_FSDMIDATA 1 #define HAVE_FID 1 #define HAVE_IOCMACROS 1 #define HAVE_BBMACROS 1 #define __XFS_FS_H__ 1 #define XFS_IOC_DIOINFO F_DIOINFO #define XFS_IOC_FSGETXATTR F_FSGETXATTR #define XFS_IOC_FSSETXATTR F_FSSETXATTR #define XFS_IOC_ALLOCSP64 F_ALLOCSP64 #define XFS_IOC_FREESP64 F_FREESP64 #define XFS_IOC_GETBMAP F_GETBMAP #define XFS_IOC_FSSETDM F_FSSETDM #define XFS_IOC_RESVSP F_RESVSP #define XFS_IOC_RESVSP64 F_RESVSP64 #define XFS_IOC_UNRESVSP F_UNRESVSP #define XFS_IOC_UNRESVSP64 F_UNRESVSP64 #define XFS_IOC_GETBMAPA F_GETBMAPA #define XFS_IOC_FSGETXATTRA F_FSGETXATTRA #define XFS_IOC_GETBMAPX F_GETBMAPX #define XFS_IOC_FSGEOMETRY_V1 XFS_FS_GEOMETRY #define XFS_IOC_FSBULKSTAT SGI_FS_BULKSTAT #define XFS_IOC_FSBULKSTAT_SINGLE SGI_FS_BULKSTAT_SINGLE #define XFS_IOC_FSINUMBERS SGI_FS_INUMBERS #define XFS_IOC_PATH_TO_FSHANDLE SGI_PATH_TO_FSHANDLE #define XFS_IOC_PATH_TO_HANDLE SGI_PATH_TO_HANDLE #define XFS_IOC_FD_TO_HANDLE SGI_FD_TO_HANDLE #define XFS_IOC_OPEN_BY_HANDLE SGI_OPEN_BY_HANDLE #define XFS_IOC_READLINK_BY_HANDLE SGI_READLINK_BY_HANDLE #define XFS_IOC_SWAPEXT /* TODO */ #define XFS_IOC_FSGROWFSDATA XFS_GROWFS_DATA #define XFS_IOC_FSGROWFSLOG XFS_GROWFS_LOG #define XFS_IOC_FSGROWFSRT XFS_GROWFS_RT #define XFS_IOC_FSCOUNTS XFS_FS_COUNTS #define XFS_IOC_SET_RESBLKS XFS_SET_RESBLKS #define XFS_IOC_GET_RESBLKS XFS_GET_RESBLKS #define XFS_IOC_ERROR_INJECTION SGI_XFS_INJECT_ERROR #define XFS_IOC_ERROR_CLEARALL SGI_XFS_CLEARALL_ERROR #define XFS_IOC_FREEZE XFS_FS_FREEZE #define XFS_IOC_THAW XFS_FS_THAW #define XFS_IOC_FSSETDM_BY_HANDLE SGI_FSSETDM_BY_HANDLE #define XFS_IOC_ATTRLIST_BY_HANDLE SGI_ATTR_LIST_BY_HANDLE #define XFS_IOC_ATTRMULTI_BY_HANDLE SGI_ATTR_MULTI_BY_HANDLE #define XFS_IOC_FSGEOMETRY XFS_FS_GEOMETRY #define XFS_IOC_GOINGDOWN XFS_FS_GOINGDOWN #define XFS_IOC_GETPARENTS SGI_XFS_GETPARENTS #define XFS_IOC_GETPARENTPATHS SGI_XFS_GETPARENTPATHS #define _AIOCB64_T_DEFINED 1 #define XFS_XFLAG_NODEFRAG 0x00002000 #endif /* __XFS_IRIX_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_bmap.h0000664000000000000000000003217611650373060015221 0ustar /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BMAP_H__ #define __XFS_BMAP_H__ struct getbmap; struct xfs_bmbt_irec; struct xfs_ifork; struct xfs_inode; struct xfs_mount; struct xfs_trans; extern kmem_zone_t *xfs_bmap_free_item_zone; /* * List of extents to be free "later". * The list is kept sorted on xbf_startblock. */ typedef struct xfs_bmap_free_item { xfs_fsblock_t xbfi_startblock;/* starting fs block number */ xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ } xfs_bmap_free_item_t; /* * Header for free extent list. * * xbf_low is used by the allocator to activate the lowspace algorithm - * when free space is running low the extent allocator may choose to * allocate an extent from an AG without leaving sufficient space for * a btree split when inserting the new extent. In this case the allocator * will enable the lowspace algorithm which is supposed to allow further * allocations (such as btree splits and newroots) to allocate from * sequential AGs. In order to avoid locking AGs out of order the lowspace * algorithm will start searching for free space from AG 0. If the correct * transaction reservations have been made then this algorithm will eventually * find all the space it needs. */ typedef struct xfs_bmap_free { xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ int xbf_count; /* count of items on list */ int xbf_low; /* alloc in low mode */ } xfs_bmap_free_t; #define XFS_BMAP_MAX_NMAP 4 /* * Flags for xfs_bmapi */ #define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */ #define XFS_BMAPI_DELAY 0x002 /* delayed write operation */ #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ #define XFS_BMAPI_RSVBLOCKS 0x020 /* OK to alloc. reserved data blocks */ #define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ #define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ /* combine contig. space */ #define XFS_BMAPI_CONTIG 0x100 /* must allocate only one extent */ /* * unwritten extent conversion - this needs write cache flushing and no additional * allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x200 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_WRITE, "WRITE" }, \ { XFS_BMAPI_DELAY, "DELAY" }, \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ { XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \ { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONVERT, "CONVERT" } static inline int xfs_bmapi_aflag(int w) { return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0); } /* * Special values for xfs_bmbt_irec_t br_startblock field. */ #define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL) #define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL) static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) { ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK); } /* * Argument structure for xfs_bmap_alloc. */ typedef struct xfs_bmalloca { xfs_fsblock_t firstblock; /* i/o first block allocated */ xfs_fsblock_t rval; /* starting block of new extent */ xfs_fileoff_t off; /* offset in file filling in */ struct xfs_trans *tp; /* transaction pointer */ struct xfs_inode *ip; /* incore inode pointer */ struct xfs_bmbt_irec *prevp; /* extent before the new one */ struct xfs_bmbt_irec *gotp; /* extent after, or delayed */ xfs_extlen_t alen; /* i/o length asked/allocated */ xfs_extlen_t total; /* total blocks needed for xaction */ xfs_extlen_t minlen; /* minimum allocation size (blocks) */ xfs_extlen_t minleft; /* amount must be left after alloc */ char eof; /* set if allocating past last extent */ char wasdel; /* replacing a delayed allocation */ char userdata;/* set if is user data */ char low; /* low on space, using seq'l ags */ char aeof; /* allocated space at eof */ char conv; /* overwriting unwritten extents */ } xfs_bmalloca_t; /* * Flags for xfs_bmap_add_extent*. */ #define BMAP_LEFT_CONTIG (1 << 0) #define BMAP_RIGHT_CONTIG (1 << 1) #define BMAP_LEFT_FILLING (1 << 2) #define BMAP_RIGHT_FILLING (1 << 3) #define BMAP_LEFT_DELAY (1 << 4) #define BMAP_RIGHT_DELAY (1 << 5) #define BMAP_LEFT_VALID (1 << 6) #define BMAP_RIGHT_VALID (1 << 7) #define BMAP_ATTRFORK (1 << 8) #define XFS_BMAP_EXT_FLAGS \ { BMAP_LEFT_CONTIG, "LC" }, \ { BMAP_RIGHT_CONTIG, "RC" }, \ { BMAP_LEFT_FILLING, "LF" }, \ { BMAP_RIGHT_FILLING, "RF" }, \ { BMAP_ATTRFORK, "ATTR" } /* * Add bmap trace insert entries for all the contents of the extent list. * * Quite excessive tracing. Only do this for debug builds. */ #if defined(__KERNEL) && defined(DEBUG) void xfs_bmap_trace_exlist( struct xfs_inode *ip, /* incore inode pointer */ xfs_extnum_t cnt, /* count of entries in list */ int whichfork, unsigned long caller_ip); /* data or attr fork */ #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ xfs_bmap_trace_exlist(ip,c,w, _THIS_IP_) #else #define XFS_BMAP_TRACE_EXLIST(ip,c,w) #endif /* * Convert inode from non-attributed to attributed. * Must not be in a transaction, ip must not be locked. */ int /* error code */ xfs_bmap_add_attrfork( struct xfs_inode *ip, /* incore inode pointer */ int size, /* space needed for new attribute */ int rsvd); /* flag for reserved block allocation */ /* * Add the extent to the list of extents to be free at transaction end. * The list is maintained sorted (by block number). */ void xfs_bmap_add_free( xfs_fsblock_t bno, /* fs block number of extent */ xfs_filblks_t len, /* length of extent */ xfs_bmap_free_t *flist, /* list of extents */ struct xfs_mount *mp); /* mount point structure */ /* * Routine to clean up the free list data structure when * an error occurs during a transaction. */ void xfs_bmap_cancel( xfs_bmap_free_t *flist); /* free list to clean up */ /* * Compute and fill in the value of the maximum depth of a bmap btree * in this filesystem. Done once, during mount. */ void xfs_bmap_compute_maxlevels( struct xfs_mount *mp, /* file system mount structure */ int whichfork); /* data or attr fork */ /* * Returns the file-relative block number of the first unused block in the file. * This is the lowest-address hole if the file has holes, else the first block * past the end of file. */ int /* error */ xfs_bmap_first_unused( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_extlen_t len, /* size of hole to find */ xfs_fileoff_t *unused, /* unused block num */ int whichfork); /* data or attr fork */ /* * Returns the file-relative block number of the last block + 1 before * last_block (input value) in the file. * This is not based on i_size, it is based on the extent list. * Returns 0 for local files, as they do not have an extent list. */ int /* error */ xfs_bmap_last_before( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t *last_block, /* last block */ int whichfork); /* data or attr fork */ /* * Returns the file-relative block number of the first block past eof in * the file. This is not based on i_size, it is based on the extent list. * Returns 0 for local files, as they do not have an extent list. */ int /* error */ xfs_bmap_last_offset( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t *unused, /* last block num */ int whichfork); /* data or attr fork */ /* * Returns whether the selected fork of the inode has exactly one * block or not. For the data fork we check this matches di_size, * implying the file's range is 0..bsize-1. */ int xfs_bmap_one_block( struct xfs_inode *ip, /* incore inode */ int whichfork); /* data or attr fork */ /* * Read in the extents to iu_extents. * All inode fields are set up by caller, we just traverse the btree * and copy the records in. */ int /* error */ xfs_bmap_read_extents( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ int whichfork); /* data or attr fork */ /* * Map file blocks to filesystem blocks. * File range is given by the bno/len pair. * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) * into a hole or past eof. * Only allocates blocks from a single allocation group, * to avoid locking problems. * The returned value in "firstblock" from the first call in a transaction * must be remembered and presented to subsequent calls in "firstblock". * An upper bound for the number of blocks to be allocated is supplied to * the first call in "total"; if no allocation group has that many free * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). */ int /* error */ xfs_bmapi( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t bno, /* starting file offs. mapped */ xfs_filblks_t len, /* length to map in file */ int flags, /* XFS_BMAPI_... */ xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_extlen_t total, /* total blocks needed */ struct xfs_bmbt_irec *mval, /* output: map values */ int *nmap, /* i/o: mval size/count */ xfs_bmap_free_t *flist); /* i/o: list extents to free */ /* * Map file blocks to filesystem blocks, simple version. * One block only, read-only. * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. * For the other flag values, the effect is as if XFS_BMAPI_METADATA * was set and all the others were clear. */ int /* error */ xfs_bmapi_single( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ int whichfork, /* data or attr fork */ xfs_fsblock_t *fsb, /* output: mapped block */ xfs_fileoff_t bno); /* starting file offs. mapped */ /* * Unmap (remove) blocks from a file. * If nexts is nonzero then the number of extents to remove is limited to * that value. If not all extents in the block range can be removed then * *done is set. */ int /* error */ xfs_bunmapi( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t bno, /* starting offset to unmap */ xfs_filblks_t len, /* length to unmap in file */ int flags, /* XFS_BMAPI_... */ xfs_extnum_t nexts, /* number of extents max */ xfs_fsblock_t *firstblock, /* first allocated block controls a.g. for allocs */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *done); /* set if not done yet */ /* * Check an extent list, which has just been read, for * any bit in the extent flag field. */ int xfs_check_nostate_extents( struct xfs_ifork *ifp, xfs_extnum_t idx, xfs_extnum_t num); uint xfs_default_attroffset( struct xfs_inode *ip); #ifdef __KERNEL__ /* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. * * Return 1 if the given transaction was committed and a new one allocated, * and 0 otherwise. */ int /* error */ xfs_bmap_finish( struct xfs_trans **tp, /* transaction pointer addr */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *committed); /* xact committed or not */ /* bmap to userspace formatter - copy to user & advance pointer */ typedef int (*xfs_bmap_format_t)(void **, struct getbmapx *, int *); /* * Get inode's extents as described in bmv, and format for output. */ int /* error code */ xfs_getbmap( xfs_inode_t *ip, struct getbmapx *bmv, /* user bmap structure */ xfs_bmap_format_t formatter, /* format to user */ void *arg); /* formatter arg */ /* * Check if the endoff is outside the last extent. If so the caller will grow * the allocation to a stripe unit boundary */ int xfs_bmap_eof( struct xfs_inode *ip, xfs_fileoff_t endoff, int whichfork, int *eof); /* * Count fsblocks of the given fork. */ int xfs_bmap_count_blocks( xfs_trans_t *tp, struct xfs_inode *ip, int whichfork, int *count); int xfs_bmap_punch_delalloc_range( struct xfs_inode *ip, xfs_fileoff_t start_fsb, xfs_fileoff_t length); #endif /* __KERNEL__ */ #endif /* __XFS_BMAP_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_da_btree.h0000664000000000000000000002452711650373060016050 0ustar /* * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_DA_BTREE_H__ #define __XFS_DA_BTREE_H__ struct xfs_buf; struct xfs_bmap_free; struct xfs_inode; struct xfs_mount; struct xfs_trans; struct zone; /*======================================================================== * Directory Structure when greater than XFS_LBSIZE(mp) bytes. *========================================================================*/ /* * This structure is common to both leaf nodes and non-leaf nodes in the Btree. * * Is is used to manage a doubly linked list of all blocks at the same * level in the Btree, and to identify which type of block this is. */ #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ typedef struct xfs_da_blkinfo { __be32 forw; /* previous block in list */ __be32 back; /* following block in list */ __be16 magic; /* validity check on block */ __be16 pad; /* unused */ } xfs_da_blkinfo_t; /* * This is the structure of the root and intermediate nodes in the Btree. * The leaf nodes are defined above. * * Entries are not packed. * * Since we have duplicate keys, use a binary search but always follow * all match in the block, not just the first match found. */ #define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */ typedef struct xfs_da_intnode { struct xfs_da_node_hdr { /* constant-structure header block */ xfs_da_blkinfo_t info; /* block type, links, etc. */ __be16 count; /* count of active entries */ __be16 level; /* level above leaves (leaf == 0) */ } hdr; struct xfs_da_node_entry { __be32 hashval; /* hash value for this descendant */ __be32 before; /* Btree block before this key */ } btree[1]; /* variable sized array of keys */ } xfs_da_intnode_t; typedef struct xfs_da_node_hdr xfs_da_node_hdr_t; typedef struct xfs_da_node_entry xfs_da_node_entry_t; #define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize /*======================================================================== * Btree searching and modification structure definitions. *========================================================================*/ /* * Search comparison results */ enum xfs_dacmp { XFS_CMP_DIFFERENT, /* names are completely different */ XFS_CMP_EXACT, /* names are exactly the same */ XFS_CMP_CASE /* names are same but differ in case */ }; /* * Structure to ease passing around component names. */ typedef struct xfs_da_args { const __uint8_t *name; /* string (maybe not NULL terminated) */ int namelen; /* length of string (maybe no NULL) */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ int flags; /* argument flags (eg: ATTR_NOCREATE) */ xfs_dahash_t hashval; /* hash value of name */ xfs_ino_t inumber; /* input/output inode number */ struct xfs_inode *dp; /* directory inode to manipulate */ xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */ struct xfs_bmap_free *flist; /* ptr to freelist for bmap_finish */ struct xfs_trans *trans; /* current trans (changes over time) */ xfs_extlen_t total; /* total blocks needed, for 1st bmap */ int whichfork; /* data or attribute fork */ xfs_dablk_t blkno; /* blkno of attr leaf of interest */ int index; /* index of attr of interest in blk */ xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ int rmtblkcnt; /* remote attr value block count */ xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ int index2; /* index of 2nd attr in blk */ xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ int rmtblkcnt2; /* remote attr value block count */ int op_flags; /* operation flags */ enum xfs_dacmp cmpresult; /* name compare result for lookups */ } xfs_da_args_t; /* * Operation flags: */ #define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */ #define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */ #define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */ #define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ #define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ #define XFS_DA_OP_FLAGS \ { XFS_DA_OP_JUSTCHECK, "JUSTCHECK" }, \ { XFS_DA_OP_RENAME, "RENAME" }, \ { XFS_DA_OP_ADDNAME, "ADDNAME" }, \ { XFS_DA_OP_OKNOENT, "OKNOENT" }, \ { XFS_DA_OP_CILOOKUP, "CILOOKUP" } /* * Structure to describe buffer(s) for a block. * This is needed in the directory version 2 format case, when * multiple non-contiguous fsblocks might be needed to cover one * logical directory block. * If the buffer count is 1 then the data pointer points to the * same place as the b_addr field for the buffer, else to kmem_alloced memory. */ typedef struct xfs_dabuf { int nbuf; /* number of buffer pointers present */ short dirty; /* data needs to be copied back */ short bbcount; /* how large is data in bbs */ void *data; /* pointer for buffers' data */ #ifdef XFS_DABUF_DEBUG inst_t *ra; /* return address of caller to make */ struct xfs_dabuf *next; /* next in global chain */ struct xfs_dabuf *prev; /* previous in global chain */ struct xfs_buftarg *target; /* device for buffer */ xfs_daddr_t blkno; /* daddr first in bps[0] */ #endif struct xfs_buf *bps[1]; /* actually nbuf of these */ } xfs_dabuf_t; #define XFS_DA_BUF_SIZE(n) \ (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) #ifdef XFS_DABUF_DEBUG extern xfs_dabuf_t *xfs_dabuf_global_list; #endif /* * Storage for holding state during Btree searches and split/join ops. * * Only need space for 5 intermediate nodes. With a minimum of 62-way * fanout to the Btree, we can support over 900 million directory blocks, * which is slightly more than enough. */ typedef struct xfs_da_state_blk { xfs_dabuf_t *bp; /* buffer containing block */ xfs_dablk_t blkno; /* filesystem blkno of buffer */ xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ int index; /* relevant index into block */ xfs_dahash_t hashval; /* last hash value in block */ int magic; /* blk's magic number, ie: blk type */ } xfs_da_state_blk_t; typedef struct xfs_da_state_path { int active; /* number of active levels */ xfs_da_state_blk_t blk[XFS_DA_NODE_MAXDEPTH]; } xfs_da_state_path_t; typedef struct xfs_da_state { xfs_da_args_t *args; /* filename arguments */ struct xfs_mount *mp; /* filesystem mount point */ unsigned int blocksize; /* logical block size */ unsigned int node_ents; /* how many entries in danode */ xfs_da_state_path_t path; /* search/split paths */ xfs_da_state_path_t altpath; /* alternate path for join */ unsigned char inleaf; /* insert into 1->lf, 0->splf */ unsigned char extravalid; /* T/F: extrablk is in use */ unsigned char extraafter; /* T/F: extrablk is after new */ xfs_da_state_blk_t extrablk; /* for double-splits on leaves */ /* for dirv2 extrablk is data */ } xfs_da_state_t; /* * Utility macros to aid in logging changed structure fields. */ #define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE)) #define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \ (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) /* * Name ops for directory and/or attr name operations */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; /*======================================================================== * Function prototypes. *========================================================================*/ /* * Routines used for growing the Btree. */ int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, xfs_dabuf_t **bpp, int whichfork); int xfs_da_split(xfs_da_state_t *state); /* * Routines used for shrinking the Btree. */ int xfs_da_join(xfs_da_state_t *state); void xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path_to_to_fix); /* * Routines used for finding things in the Btree. */ int xfs_da_node_lookup_int(xfs_da_state_t *state, int *result); int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, int forward, int release, int *result); /* * Utility routines. */ int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, xfs_da_state_blk_t *new_blk); /* * Utility routines. */ int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dabuf_t **bp, int whichfork); int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dabuf_t **bpp, int whichfork); xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, int whichfork); int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, xfs_dabuf_t *dead_buf); uint xfs_da_hashname(const __uint8_t *name_string, int name_length); enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, const unsigned char *name, int len); xfs_da_state_t *xfs_da_state_alloc(void); void xfs_da_state_free(xfs_da_state_t *state); void xfs_da_buf_done(xfs_dabuf_t *dabuf); void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, uint last); void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf); void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); extern struct kmem_zone *xfs_da_state_zone; extern struct kmem_zone *xfs_dabuf_zone; extern const struct xfs_nameops xfs_default_nameops; #endif /* __XFS_DA_BTREE_H__ */ xfsprogs-3.1.9ubuntu2/include/xfs_bmap_btree.h0000664000000000000000000001621611650373060016377 0ustar /* * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __XFS_BMAP_BTREE_H__ #define __XFS_BMAP_BTREE_H__ #define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ struct xfs_btree_cur; struct xfs_btree_block; struct xfs_mount; struct xfs_inode; struct xfs_trans; /* * Bmap root header, on-disk form only. */ typedef struct xfs_bmdr_block { __be16 bb_level; /* 0 is a leaf */ __be16 bb_numrecs; /* current # of data records */ } xfs_bmdr_block_t; /* * Bmap btree record and extent descriptor. * l0:63 is an extent flag (value 1 indicates non-normal). * l0:9-62 are startoff. * l0:0-8 and l1:21-63 are startblock. * l1:0-20 are blockcount. */ #define BMBT_EXNTFLAG_BITLEN 1 #define BMBT_STARTOFF_BITLEN 54 #define BMBT_STARTBLOCK_BITLEN 52 #define BMBT_BLOCKCOUNT_BITLEN 21 typedef struct xfs_bmbt_rec { __be64 l0, l1; } xfs_bmbt_rec_t; typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ typedef xfs_bmbt_rec_t xfs_bmdr_rec_t; typedef struct xfs_bmbt_rec_host { __uint64_t l0, l1; } xfs_bmbt_rec_host_t; /* * Values and macros for delayed-allocation startblock fields. */ #define STARTBLOCKVALBITS 17 #define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) #define DSTARTBLOCKMASKBITS (15 + 20) #define STARTBLOCKMASK \ (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) #define DSTARTBLOCKMASK \ (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) static inline int isnullstartblock(xfs_fsblock_t x) { return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; } static inline int isnulldstartblock(xfs_dfsbno_t x) { return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; } static inline xfs_fsblock_t nullstartblock(int k) { ASSERT(k < (1 << STARTBLOCKVALBITS)); return STARTBLOCKMASK | (k); } static inline xfs_filblks_t startblockval(xfs_fsblock_t x) { return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); } /* * Possible extent formats. */ typedef enum { XFS_EXTFMT_NOSTATE = 0, XFS_EXTFMT_HASSTATE } xfs_exntfmt_t; /* * Possible extent states. */ typedef enum { XFS_EXT_NORM, XFS_EXT_UNWRITTEN, XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID } xfs_exntst_t; /* * Extent state and extent format macros. */ #define XFS_EXTFMT_INODE(x) \ (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \ XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) /* * Incore version of above. */ typedef struct xfs_bmbt_irec { xfs_fileoff_t br_startoff; /* starting file offset */ xfs_fsblock_t br_startblock; /* starting block number */ xfs_filblks_t br_blockcount; /* number of blocks */ xfs_exntst_t br_state; /* extent state */ } xfs_bmbt_irec_t; /* * Key structure for non-leaf levels of the tree. */ typedef struct xfs_bmbt_key { __be64 br_startoff; /* starting file offset */ } xfs_bmbt_key_t, xfs_bmdr_key_t; /* btree pointer type */ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* * Btree block header size depends on a superblock flag. * * (not quite yet, but soon) */ #define XFS_BMBT_BLOCK_LEN(mp) XFS_BTREE_LBLOCK_LEN #define XFS_BMBT_REC_ADDR(mp, block, index) \ ((xfs_bmbt_rec_t *) \ ((char *)(block) + \ XFS_BMBT_BLOCK_LEN(mp) + \ ((index) - 1) * sizeof(xfs_bmbt_rec_t))) #define XFS_BMBT_KEY_ADDR(mp, block, index) \ ((xfs_bmbt_key_t *) \ ((char *)(block) + \ XFS_BMBT_BLOCK_LEN(mp) + \ ((index) - 1) * sizeof(xfs_bmbt_key_t))) #define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \ ((xfs_bmbt_ptr_t *) \ ((char *)(block) + \ XFS_BMBT_BLOCK_LEN(mp) + \ (maxrecs) * sizeof(xfs_bmbt_key_t) + \ ((index) - 1) * sizeof(xfs_bmbt_ptr_t))) #define XFS_BMDR_REC_ADDR(block, index) \ ((xfs_bmdr_rec_t *) \ ((char *)(block) + \ sizeof(struct xfs_bmdr_block) + \ ((index) - 1) * sizeof(xfs_bmdr_rec_t))) #define XFS_BMDR_KEY_ADDR(block, index) \ ((xfs_bmdr_key_t *) \ ((char *)(block) + \ sizeof(struct xfs_bmdr_block) + \ ((index) - 1) * sizeof(xfs_bmdr_key_t))) #define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \ ((xfs_bmdr_ptr_t *) \ ((char *)(block) + \ sizeof(struct xfs_bmdr_block) + \ (maxrecs) * sizeof(xfs_bmdr_key_t) + \ ((index) - 1) * sizeof(xfs_bmdr_ptr_t))) /* * These are to be used when we know the size of the block and * we don't have a cursor. */ #define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \ XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)) #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \ (int)(XFS_BTREE_LBLOCK_LEN + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) #define XFS_BMAP_BROOT_SPACE(bb) \ (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) #define XFS_BMDR_SPACE_CALC(nrecs) \ (int)(sizeof(xfs_bmdr_block_t) + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) /* * Maximum number of bmap btree levels. */ #define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)]) /* * Prototypes for xfs_bmap.c to call. */ extern void xfs_bmdr_to_bmbt(struct xfs_mount *, xfs_bmdr_block_t *, int, struct xfs_btree_block *, int); extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v); extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v); extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v); extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v); extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int, xfs_bmdr_block_t *, int); extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level); extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf); extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, int); #endif /* __XFS_BMAP_BTREE_H__ */ xfsprogs-3.1.9ubuntu2/io/0000775000000000000000000000000012062211564012222 5ustar xfsprogs-3.1.9ubuntu2/io/open.c0000664000000000000000000004605712062210562013340 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t open_cmd; static cmdinfo_t stat_cmd; static cmdinfo_t close_cmd; static cmdinfo_t setfl_cmd; static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; static cmdinfo_t extsize_cmd; static prid_t prid; static long extsize; off64_t filesize(void) { struct stat64 st; if (fstat64(file->fd, &st) < 0) { perror("fstat64"); return -1; } return st.st_size; } static char * filetype(mode_t mode) { switch (mode & S_IFMT) { case S_IFSOCK: return _("socket"); case S_IFDIR: return _("directory"); case S_IFCHR: return _("char device"); case S_IFBLK: return _("block device"); case S_IFREG: return _("regular file"); case S_IFLNK: return _("symbolic link"); case S_IFIFO: return _("fifo"); } return NULL; } static int stat_f( int argc, char **argv) { struct dioattr dio; struct fsxattr fsx, fsxa; struct stat64 st; int verbose = (argc == 2 && !strcmp(argv[1], "-v")); printf(_("fd.path = \"%s\"\n"), file->name); printf(_("fd.flags = %s,%s,%s%s%s%s\n"), file->flags & IO_OSYNC ? _("sync") : _("non-sync"), file->flags & IO_DIRECT ? _("direct") : _("non-direct"), file->flags & IO_READONLY ? _("read-only") : _("read-write"), file->flags & IO_REALTIME ? _(",real-time") : "", file->flags & IO_APPEND ? _(",append-only") : "", file->flags & IO_NONBLOCK ? _(",non-block") : ""); if (fstat64(file->fd, &st) < 0) { perror("fstat64"); } else { printf(_("stat.ino = %lld\n"), (long long)st.st_ino); printf(_("stat.type = %s\n"), filetype(st.st_mode)); printf(_("stat.size = %lld\n"), (long long)st.st_size); printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks); if (verbose) { printf(_("stat.atime = %s"), ctime(&st.st_atime)); printf(_("stat.mtime = %s"), ctime(&st.st_mtime)); printf(_("stat.ctime = %s"), ctime(&st.st_ctime)); } } if (file->flags & IO_FOREIGN) return 0; if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0 || (xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTRA, &fsxa)) < 0) { perror("XFS_IOC_FSGETXATTR"); } else { printf(_("fsxattr.xflags = 0x%x "), fsx.fsx_xflags); printxattr(fsx.fsx_xflags, verbose, 0, file->name, 1, 1); printf(_("fsxattr.projid = %u\n"), fsx.fsx_projid); printf(_("fsxattr.extsize = %u\n"), fsx.fsx_extsize); printf(_("fsxattr.nextents = %u\n"), fsx.fsx_nextents); printf(_("fsxattr.naextents = %u\n"), fsxa.fsx_nextents); } if ((xfsctl(file->name, file->fd, XFS_IOC_DIOINFO, &dio)) < 0) { perror("XFS_IOC_DIOINFO"); } else { printf(_("dioattr.mem = 0x%x\n"), dio.d_mem); printf(_("dioattr.miniosz = %u\n"), dio.d_miniosz); printf(_("dioattr.maxiosz = %u\n"), dio.d_maxiosz); } return 0; } int openfile( char *path, xfs_fsop_geom_t *geom, int flags, mode_t mode) { int fd; int oflags; oflags = flags & IO_READONLY ? O_RDONLY : O_RDWR; if (flags & IO_APPEND) oflags |= O_APPEND; if (flags & IO_CREAT) oflags |= O_CREAT; if (flags & IO_DIRECT) oflags |= O_DIRECT; if (flags & IO_OSYNC) oflags |= O_SYNC; if (flags & IO_TRUNC) oflags |= O_TRUNC; if (flags & IO_NONBLOCK) oflags |= O_NONBLOCK; fd = open(path, oflags, mode); if (fd < 0) { if ((errno == EISDIR) && (oflags & O_RDWR)) { /* make it as if we asked for O_RDONLY & try again */ oflags &= ~O_RDWR; oflags |= O_RDONLY; flags |= IO_READONLY; fd = open(path, oflags, mode); if (fd < 0) { perror(path); return -1; } } else { perror(path); return -1; } } if (!geom || !platform_test_xfs_fd(fd)) return fd; if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) { perror("XFS_IOC_FSGEOMETRY"); close(fd); return -1; } if (!(flags & IO_READONLY) && (flags & IO_REALTIME)) { struct fsxattr attr; if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) { perror("XFS_IOC_FSGETXATTR"); close(fd); return -1; } if (!(attr.fsx_xflags & XFS_XFLAG_REALTIME)) { attr.fsx_xflags |= XFS_XFLAG_REALTIME; if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) { perror("XFS_IOC_FSSETXATTR"); close(fd); return -1; } } } return fd; } int addfile( char *name, int fd, xfs_fsop_geom_t *geometry, int flags) { char *filename; filename = strdup(name); if (!filename) { perror("strdup"); close(fd); return -1; } /* Extend the table of currently open files */ filetable = (fileio_t *)realloc(filetable, /* growing */ ++filecount * sizeof(fileio_t)); if (!filetable) { perror("realloc"); filecount = 0; free(filename); close(fd); return -1; } /* Finally, make this the new active open file */ file = &filetable[filecount - 1]; file->fd = fd; file->flags = flags; file->name = filename; file->geom = *geometry; return 0; } static void open_help(void) { printf(_( "\n" " opens a new file in the requested mode\n" "\n" " Example:\n" " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n" "\n" " Opens a file for subsequent use by all of the other xfs_io commands.\n" " With no arguments, open uses the stat command to show the current file.\n" " -a -- open with the O_APPEND flag (append-only mode)\n" " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" " -f -- open with O_CREAT (create the file if it doesn't exist)\n" " -m -- permissions to use in case a new file is created (default 0600)\n" " -n -- open with O_NONBLOCK\n" " -r -- open with O_RDONLY, the default is O_RDWR\n" " -s -- open with O_SYNC\n" " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" " -R -- mark the file as a realtime XFS file immediately after opening it\n" " Note1: usually read/write direct IO requests must be blocksize aligned;\n" " some kernels, however, allow sectorsize alignment for direct IO.\n" " Note2: the bmap for non-regular files can be obtained provided the file\n" " was opened correctly (in particular, must be opened read-only).\n" "\n")); } static int open_f( int argc, char **argv) { int c, fd, flags = 0; char *sp; mode_t mode = 0600; xfs_fsop_geom_t geometry = { 0 }; if (argc == 1) { if (file) return stat_f(argc, argv); fprintf(stderr, _("no files are open, try 'help open'\n")); return 0; } while ((c = getopt(argc, argv, "FRacdfm:nrstx")) != EOF) { switch (c) { case 'F': /* Ignored / deprecated now, handled automatically */ break; case 'a': flags |= IO_APPEND; break; case 'c': case 'f': flags |= IO_CREAT; break; case 'd': flags |= IO_DIRECT; break; case 'm': mode = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric mode -- %s\n"), optarg); return 0; } break; case 'n': flags |= IO_NONBLOCK; break; case 'r': flags |= IO_READONLY; break; case 's': flags |= IO_OSYNC; break; case 't': flags |= IO_TRUNC; break; case 'R': case 'x': /* backwards compatibility */ flags |= IO_REALTIME; break; default: return command_usage(&open_cmd); } } if (optind != argc - 1) return command_usage(&open_cmd); fd = openfile(argv[optind], &geometry, flags, mode); if (fd < 0) return 0; if (!platform_test_xfs_fd(fd)) flags |= IO_FOREIGN; addfile(argv[optind], fd, &geometry, flags); return 0; } static int close_f( int argc, char **argv) { size_t length; unsigned int offset; if (close(file->fd) < 0) { perror("close"); return 0; } free(file->name); /* Shuffle the file table entries down over the removed entry */ offset = file - &filetable[0]; length = filecount * sizeof(fileio_t); length -= (offset + 1) * sizeof(fileio_t); if (length) memmove(file, file + 1, length); /* Resize the memory allocated for the table, possibly freeing */ if (--filecount) { filetable = (fileio_t *)realloc(filetable, /* shrinking */ filecount * sizeof(fileio_t)); if (offset == filecount) offset--; file = filetable + offset; } else { free(filetable); file = filetable = NULL; } filelist_f(); return 0; } static void lsproj_help(void) { printf(_( "\n" " displays the project identifier associated with the current path\n" "\n" " Options:\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, but only list projects on directories\n" "\n")); } static int lsproj_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { prid_t projid; int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else { if (getprojid(path, fd, &projid) == 0) printf("[%u] %s\n", (unsigned int)projid, path); close(fd); } return 0; } static int lsproj_f( int argc, char **argv) { prid_t projid; int c; recurse_all = recurse_dir = 0; while ((c = getopt(argc, argv, "DR")) != EOF) { switch (c) { case 'D': recurse_all = 0; recurse_dir = 1; break; case 'R': recurse_all = 1; recurse_dir = 0; break; default: return command_usage(&lsproj_cmd); } } if (argc != optind) return command_usage(&lsproj_cmd); if (recurse_all || recurse_dir) nftw(file->name, lsproj_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); else if (getprojid(file->name, file->fd, &projid) < 0) perror("getprojid"); else printf(_("projid = %u\n"), (unsigned int)projid); return 0; } static void chproj_help(void) { printf(_( "\n" " modifies the project identifier associated with the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying projects on directories\n" "\n")); } static int chproj_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else { if (setprojid(path, fd, prid) < 0) perror("setprojid"); close(fd); } return 0; } static int chproj_f( int argc, char **argv) { int c; recurse_all = recurse_dir = 0; while ((c = getopt(argc, argv, "DR")) != EOF) { switch (c) { case 'D': recurse_all = 0; recurse_dir = 1; break; case 'R': recurse_all = 1; recurse_dir = 0; break; default: return command_usage(&chproj_cmd); } } if (argc != optind + 1) return command_usage(&chproj_cmd); prid = prid_from_string(argv[optind]); if (prid == -1) { printf(_("invalid project ID -- %s\n"), argv[optind]); return 0; } if (recurse_all || recurse_dir) nftw(file->name, chproj_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); else if (setprojid(file->name, file->fd, prid) < 0) perror("setprojid"); return 0; } static void extsize_help(void) { printf(_( "\n" " report or modify preferred extent size (in bytes) for the current path\n" "\n" " -R -- recursively descend (useful when current path is a directory)\n" " -D -- recursively descend, only modifying extsize on directories\n" "\n")); } static int get_extsize(const char *path, int fd) { struct fsxattr fsx; if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { printf("%s: XFS_IOC_FSGETXATTR %s: %s\n", progname, path, strerror(errno)); return 0; } printf("[%u] %s\n", fsx.fsx_extsize, path); return 0; } static int set_extsize(const char *path, int fd, long extsz) { struct fsxattr fsx; struct stat64 stat; if (fstat64(fd, &stat) < 0) { perror("fstat64"); return 0; } if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { printf("%s: XFS_IOC_FSGETXATTR %s: %s\n", progname, path, strerror(errno)); return 0; } if (S_ISREG(stat.st_mode)) { fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE; } else if (S_ISDIR(stat.st_mode)) { fsx.fsx_xflags |= XFS_XFLAG_EXTSZINHERIT; } else { printf(_("invalid target file type - file %s\n"), path); return 0; } fsx.fsx_extsize = extsz; if ((xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx)) < 0) { printf("%s: XFS_IOC_FSSETXATTR %s: %s\n", progname, path, strerror(errno)); return 0; } return 0; } static int get_extsize_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else { get_extsize(path, fd); close(fd); } return 0; } static int set_extsize_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else { set_extsize(path, fd, extsize); close(fd); } return 0; } static int extsize_f( int argc, char **argv) { size_t blocksize, sectsize; int c; recurse_all = recurse_dir = 0; init_cvtnum(&blocksize, §size); while ((c = getopt(argc, argv, "DR")) != EOF) { switch (c) { case 'D': recurse_all = 0; recurse_dir = 1; break; case 'R': recurse_all = 1; recurse_dir = 0; break; default: return command_usage(&extsize_cmd); } } if (optind < argc) { extsize = (long)cvtnum(blocksize, sectsize, argv[optind]); if (extsize < 0) { printf(_("non-numeric extsize argument -- %s\n"), argv[optind]); return 0; } } else { extsize = -1; } if (recurse_all || recurse_dir) nftw(file->name, (extsize >= 0) ? set_extsize_callback : get_extsize_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); else if (extsize >= 0) set_extsize(file->name, file->fd, extsize); else get_extsize(file->name, file->fd); return 0; } static int setfl_f( int argc, char **argv) { int c, flags; flags = fcntl(file->fd, F_GETFL, 0); if (flags < 0) { perror("fcntl(F_GETFL)"); return 0; } while ((c = getopt(argc, argv, "ad")) != EOF) { switch (c) { case 'a': if (flags & O_APPEND) flags |= O_APPEND; else flags &= ~O_APPEND; break; case 'd': if (flags & O_DIRECT) flags |= O_DIRECT; else flags &= ~O_DIRECT; break; default: printf(_("invalid setfl argument -- '%c'\n"), c); return 0; } } if (fcntl(file->fd, F_SETFL, flags) < 0) perror("fcntl(F_SETFL)"); return 0; } static int statfs_f( int argc, char **argv) { struct xfs_fsop_counts fscounts; struct xfs_fsop_geom fsgeo; struct statfs st; printf(_("fd.path = \"%s\"\n"), file->name); if (platform_fstatfs(file->fd, &st) < 0) { perror("fstatfs"); } else { printf(_("statfs.f_bsize = %lld\n"), (long long) st.f_bsize); printf(_("statfs.f_blocks = %lld\n"), (long long) st.f_blocks); #if defined(__sgi__) printf(_("statfs.f_frsize = %lld\n"), (long long) st.f_frsize); #else printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail); #endif printf(_("statfs.f_files = %lld\n"), (long long) st.f_files); printf(_("statfs.f_ffree = %lld\n"), (long long) st.f_ffree); } if (file->flags & IO_FOREIGN) return 0; if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) { perror("XFS_IOC_FSGEOMETRY_V1"); } else { printf(_("geom.bsize = %u\n"), fsgeo.blocksize); printf(_("geom.agcount = %u\n"), fsgeo.agcount); printf(_("geom.agblocks = %u\n"), fsgeo.agblocks); printf(_("geom.datablocks = %llu\n"), (unsigned long long) fsgeo.datablocks); printf(_("geom.rtblocks = %llu\n"), (unsigned long long) fsgeo.rtblocks); printf(_("geom.rtextents = %llu\n"), (unsigned long long) fsgeo.rtextents); printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize); printf(_("geom.sunit = %u\n"), fsgeo.sunit); printf(_("geom.swidth = %u\n"), fsgeo.swidth); } if ((xfsctl(file->name, file->fd, XFS_IOC_FSCOUNTS, &fscounts)) < 0) { perror("XFS_IOC_FSCOUNTS"); } else { printf(_("counts.freedata = %llu\n"), (unsigned long long) fscounts.freedata); printf(_("counts.freertx = %llu\n"), (unsigned long long) fscounts.freertx); printf(_("counts.freeino = %llu\n"), (unsigned long long) fscounts.freeino); printf(_("counts.allocino = %llu\n"), (unsigned long long) fscounts.allocino); } return 0; } void open_init(void) { open_cmd.name = "open"; open_cmd.altname = "o"; open_cmd.cfunc = open_f; open_cmd.argmin = 0; open_cmd.argmax = -1; open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK; open_cmd.args = _("[-acdrstx] [path]"); open_cmd.oneline = _("open the file specified by path"); open_cmd.help = open_help; stat_cmd.name = "stat"; stat_cmd.cfunc = stat_f; stat_cmd.argmin = 0; stat_cmd.argmax = 1; stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; stat_cmd.args = _("[-v]"); stat_cmd.oneline = _("statistics on the currently open file"); close_cmd.name = "close"; close_cmd.altname = "c"; close_cmd.cfunc = close_f; close_cmd.argmin = 0; close_cmd.argmax = 0; close_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; close_cmd.oneline = _("close the current open file"); setfl_cmd.name = "setfl"; setfl_cmd.cfunc = setfl_f; setfl_cmd.args = _("[-adx]"); setfl_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; setfl_cmd.oneline = _("set/clear append/direct flags on the open file"); statfs_cmd.name = "statfs"; statfs_cmd.cfunc = statfs_f; statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; statfs_cmd.oneline = _("statistics on the filesystem of the currently open file"); chproj_cmd.name = "chproj"; chproj_cmd.cfunc = chproj_f; chproj_cmd.args = _("[-D | -R] projid"); chproj_cmd.argmin = 1; chproj_cmd.argmax = -1; chproj_cmd.flags = CMD_NOMAP_OK; chproj_cmd.oneline = _("change project identifier on the currently open file"); chproj_cmd.help = chproj_help; lsproj_cmd.name = "lsproj"; lsproj_cmd.cfunc = lsproj_f; lsproj_cmd.args = _("[-D | -R]"); lsproj_cmd.argmin = 0; lsproj_cmd.argmax = -1; lsproj_cmd.flags = CMD_NOMAP_OK; lsproj_cmd.oneline = _("list project identifier set on the currently open file"); lsproj_cmd.help = lsproj_help; extsize_cmd.name = "extsize"; extsize_cmd.cfunc = extsize_f; extsize_cmd.args = _("[-D | -R] [extsize]"); extsize_cmd.argmin = 0; extsize_cmd.argmax = -1; extsize_cmd.flags = CMD_NOMAP_OK; extsize_cmd.oneline = _("get/set preferred extent size (in bytes) for the open file"); extsize_cmd.help = extsize_help; add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); add_command(&setfl_cmd); add_command(&statfs_cmd); add_command(&chproj_cmd); add_command(&lsproj_cmd); add_command(&extsize_cmd); } xfsprogs-3.1.9ubuntu2/io/xfs_mkfile.sh0000775000000000000000000000175711140033220014705 0ustar #!/bin/sh -f # # Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. # OPTS="" NOBYTES=false PREALLOC=false VERBOSE=false VERSION=false XFS_IO=`dirname $0`"/xfs_io -p xfs_mkfile" USAGE="Usage: xfs_mkfile [-npvV] size file..." while getopts "npvV" c do case $c in n) NOBYTES=true;; p) PREALLOC=true;; v) VERBOSE=true;; V) VERSION=true;; \?) echo $USAGE 1>&2 exit 2 ;; esac done $VERSION && $XFS_IO -V shift `expr $OPTIND - 1` [ "$1" != "" ] || exit 0 SIZE="$1" ERRORS=0 shift while [ "$1" != "" ] do if $VERBOSE ; then $PREALLOC && echo "$1 $SIZE bytes pre-allocated" $PREALLOC || echo "$1 $SIZE bytes" fi if $NOBYTES ; then $XFS_IO -ft -c "truncate $SIZE" -- "$1" elif $PREALLOC ; then $XFS_IO -ftd -c "resvsp 0 $SIZE" \ -c "pwrite -q -S0 -b256k 0 $SIZE" \ -c "truncate $SIZE" -- "$1" else $XFS_IO -ftd -c "pwrite -q -S0 -b256k 0 $SIZE" \ -c "truncate $SIZE" -- "$1" fi [ $? -eq 0 ] || ERRORS=`expr $ERRORS + 1` shift done exit $ERRORS xfsprogs-3.1.9ubuntu2/io/Makefile0000664000000000000000000000361412062210562013663 0ustar # # Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_io LSRCFILES = xfs_bmap.sh xfs_freeze.sh xfs_mkfile.sh HFILES = init.h io.h CFILES = init.c \ attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c mmap.c \ open.c parent.c pread.c prealloc.c pwrite.c shutdown.c truncate.c LLDLIBS = $(LIBXCMD) $(LIBHANDLE) LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE) LLDFLAGS = -static ifeq ($(HAVE_FADVISE),yes) CFILES += fadvise.c LCFLAGS += -DHAVE_FADVISE else LSRCFILES += fadvise.c endif ifeq ($(HAVE_MADVISE),yes) CFILES += madvise.c LCFLAGS += -DHAVE_MADVISE else LSRCFILES += madvise.c endif ifeq ($(HAVE_MINCORE),yes) CFILES += mincore.c LCFLAGS += -DHAVE_MINCORE else LSRCFILES += mincore.c endif ifeq ($(HAVE_SENDFILE),yes) CFILES += sendfile.c LCFLAGS += -DHAVE_SENDFILE else LSRCFILES += sendfile.c endif ifeq ($(HAVE_FIEMAP),yes) CFILES += fiemap.c LCFLAGS += -DHAVE_FIEMAP else LSRCFILES += fiemap.c endif ifeq ($(PKG_PLATFORM),irix) LSRCFILES += inject.c resblks.c else CFILES += inject.c resblks.c LCFLAGS += -DHAVE_INJECT -DHAVE_RESBLKS endif ifeq ($(HAVE_SYNC_FILE_RANGE),yes) CFILES += sync_file_range.c LCFLAGS += -DHAVE_SYNC_FILE_RANGE endif ifeq ($(ENABLE_READLINE),yes) LLDLIBS += $(LIBREADLINE) $(LIBTERMCAP) endif ifeq ($(ENABLE_EDITLINE),yes) LLDLIBS += $(LIBEDITLINE) $(LIBTERMCAP) endif ifeq ($(HAVE_FALLOCATE),yes) LCFLAGS += -DHAVE_FALLOCATE endif # Also implies PWRITEV ifeq ($(HAVE_PREADV),yes) LCFLAGS += -DHAVE_PREADV -DHAVE_PWRITEV endif default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 xfs_bmap.sh $(PKG_SBIN_DIR)/xfs_bmap $(LTINSTALL) -m 755 xfs_freeze.sh $(PKG_SBIN_DIR)/xfs_freeze $(LTINSTALL) -m 755 xfs_mkfile.sh $(PKG_SBIN_DIR)/xfs_mkfile install-dev: -include .dep xfsprogs-3.1.9ubuntu2/io/shutdown.c0000664000000000000000000000313011604735741014247 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t shutdown_cmd; static int shutdown_f( int argc, char **argv) { int c, flag = XFS_FSOP_GOING_FLAGS_NOLOGFLUSH; while ((c = getopt(argc, argv, "fv")) != -1) { switch (c) { case 'f': flag = XFS_FSOP_GOING_FLAGS_LOGFLUSH; break; default: return command_usage(&shutdown_cmd); } } if ((xfsctl(file->name, file->fd, XFS_IOC_GOINGDOWN, &flag)) < 0) { perror("XFS_IOC_GOINGDOWN"); return 0; } return 0; } void shutdown_init(void) { shutdown_cmd.name = "shutdown"; shutdown_cmd.cfunc = shutdown_f; shutdown_cmd.argmin = 0; shutdown_cmd.argmax = 1; shutdown_cmd.flags = CMD_NOMAP_OK; shutdown_cmd.args = _("[-f]"); shutdown_cmd.oneline = _("shuts down the filesystem where the current file resides"); if (expert) add_command(&shutdown_cmd); } xfsprogs-3.1.9ubuntu2/io/truncate.c0000664000000000000000000000310711604735741014225 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t truncate_cmd; static int truncate_f( int argc, char **argv) { off64_t offset; size_t blocksize, sectsize; init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[1]); if (offset < 0) { printf(_("non-numeric truncate argument -- %s\n"), argv[1]); return 0; } if (ftruncate64(file->fd, offset) < 0) { perror("ftruncate"); return 0; } return 0; } void truncate_init(void) { truncate_cmd.name = "truncate"; truncate_cmd.altname = "t"; truncate_cmd.cfunc = truncate_f; truncate_cmd.argmin = 1; truncate_cmd.argmax = 1; truncate_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; truncate_cmd.args = _("off"); truncate_cmd.oneline = _("truncates the current file at the given offset"); add_command(&truncate_cmd); } xfsprogs-3.1.9ubuntu2/io/madvise.c0000664000000000000000000000705411604735741014035 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t madvise_cmd; static void madvise_help(void) { printf(_( "\n" " advise the page cache about access patterns expected for a mapping\n" "\n" " Modifies page cache behavior when operating on the current mapping.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_MADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n" " -r -- expect random page references (POSIX_MADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n" " Notes:\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED forces the maximum readahead.\n" "\n")); } int madvise_f( int argc, char **argv) { off64_t offset, llength; size_t length; void *start; int advise = MADV_NORMAL, c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "drsw")) != EOF) { switch (c) { case 'd': /* Don't need these pages */ advise = MADV_DONTNEED; break; case 'r': /* Expect random page references */ advise = MADV_RANDOM; break; case 's': /* Expect sequential page references */ advise = MADV_SEQUENTIAL; break; case 'w': /* Will need these pages */ advise = MADV_WILLNEED; break; default: return command_usage(&madvise_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; llength = cvtnum(blocksize, sectsize, argv[optind]); if (llength < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } else if (llength > (size_t)llength) { printf(_("length argument too large -- %lld\n"), (long long)llength); return 0; } else length = (size_t)llength; } else { return command_usage(&madvise_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; if (madvise(start, length, advise) < 0) { perror("madvise"); return 0; } return 0; } void madvise_init(void) { madvise_cmd.name = "madvise"; madvise_cmd.altname = "ma"; madvise_cmd.cfunc = madvise_f; madvise_cmd.argmin = 0; madvise_cmd.argmax = -1; madvise_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; madvise_cmd.args = _("[-drsw] [off len]"); madvise_cmd.oneline = _("give advice about use of memory"); madvise_cmd.help = madvise_help; add_command(&madvise_cmd); } xfsprogs-3.1.9ubuntu2/io/mincore.c0000664000000000000000000000625011604735741014036 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t mincore_cmd; int mincore_f( int argc, char **argv) { off64_t offset, llength; size_t length; size_t blocksize, sectsize; void *start; void *current, *previous; unsigned char *vec; int i; if (argc == 1) { offset = mapping->offset; length = mapping->length; } else if (argc == 3) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[1]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[1]); return 0; } llength = cvtnum(blocksize, sectsize, argv[2]); if (llength < 0) { printf(_("non-numeric length argument -- %s\n"), argv[2]); return 0; } else if (llength > (size_t)llength) { printf(_("length argument too large -- %lld\n"), (long long)llength); return 0; } else length = (size_t)llength; } else { return command_usage(&mincore_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; vec = calloc(length/pagesize, sizeof(unsigned char)); if (!vec) { perror("calloc"); return 0; } if (mincore(start, length, vec) < 0) { perror("mincore"); free(vec); return 0; } previous = NULL; current = start; for (i = 0; i < length/pagesize; i++, current += pagesize) { if (vec[i]) { if (!previous) { /* print start address */ printf("0x%lx - ", (unsigned long)current); previous = start + (i * pagesize); } } else if (previous) { /* print end and page count */ printf(_("0x%lx %lu pages (%llu : %lu)\n"), (unsigned long)current, (unsigned long)(current - previous) / pagesize, (unsigned long long)offset + (unsigned long long)(previous - start), (unsigned long)(current - previous)); previous = NULL; } } if (previous) printf(_("0x%lx %lu pages (%llu : %lu)\n"), (unsigned long)current, (unsigned long)(current - previous) / pagesize, (unsigned long long)offset + (unsigned long long)(previous - start), (unsigned long)(current - previous)); free(vec); return 0; } void mincore_init(void) { mincore_cmd.name = "mincore"; mincore_cmd.altname = "mi"; mincore_cmd.cfunc = mincore_f; mincore_cmd.argmin = 0; mincore_cmd.argmax = 2; mincore_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; mincore_cmd.args = _("[off len]"); mincore_cmd.oneline = _("find mapping pages that are memory resident"); add_command(&mincore_cmd); } xfsprogs-3.1.9ubuntu2/io/pread.c0000664000000000000000000002570412062210562013466 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t pread_cmd; static void pread_help(void) { printf(_( "\n" " reads a range of bytes in a specified block size from the given offset\n" "\n" " Example:\n" " 'pread -v 512 20' - dumps 20 bytes read from 512 bytes into the file\n" "\n" " Reads a segment of the currently open file, optionally dumping it to the\n" " standard output stream (with -v option) for subsequent inspection.\n" " The reads are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different pattern is requested.\n" " -B -- read backwards through the range from offset (backwards N bytes)\n" " -F -- read forwards through the range of bytes from offset (default)\n" " -v -- be verbose, dump out buffers (used when reading forwards)\n" " -R -- read at random offsets in the range of bytes\n" " -Z N -- zeed the random number generator (used when reading randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" #ifdef HAVE_PREADV " -V N -- use vectored IO with N iovecs of blocksize each (preadv)\n" #endif "\n" " When in \"random\" mode, the number of read operations will equal the\n" " number required to do a complete forward/backward scan of the range.\n" " Note that the offset within the range is chosen at random each time\n" " (an offset may be read more than once when operating in this mode).\n" "\n")); } void *buffer; size_t highwater; size_t buffersize; int vectors; struct iovec *iov; static int alloc_iovec( size_t bsize, int uflag, unsigned int seed) { int i; iov = calloc(vectors, sizeof(struct iovec)); if (!iov) return -1; buffersize = 0; for (i = 0; i < vectors; i++) { iov[i].iov_base = memalign(pagesize, bsize); if (!iov[i].iov_base) { perror("memalign"); goto unwind; } iov[i].iov_len = bsize; if (!uflag) memset(iov[i].iov_base, seed, bsize); } buffersize = bsize * vectors; return 0; unwind: for( ; i >= 0; i--) free(iov[i].iov_base); free(iov); iov = NULL; return -1; } int alloc_buffer( size_t bsize, int uflag, unsigned int seed) { if (vectors) return alloc_iovec(bsize, uflag, seed); if (bsize > highwater) { if (buffer) free(buffer); buffer = memalign(pagesize, bsize); if (!buffer) { perror("memalign"); highwater = buffersize = 0; return -1; } highwater = bsize; } buffersize = bsize; if (!uflag) memset(buffer, seed, buffersize); return 0; } void __dump_buffer( void *buf, off64_t offset, ssize_t len) { int i, j; char *p; for (i = 0, p = (char *)buf; i < len; i += 16) { char *s = p; printf("%08llx: ", (unsigned long long)offset + i); for (j = 0; j < 16 && i + j < len; j++, p++) printf("%02x ", *p); printf(" "); for (j = 0; j < 16 && i + j < len; j++, s++) { if (isalnum((int)*s)) printf("%c", *s); else printf("."); } printf("\n"); } } void dump_buffer( off64_t offset, ssize_t len) { int i, l; if (!vectors) { __dump_buffer(buffer, offset, len); return; } for (i = 0; len > 0 && i < vectors; i++) { l = min(len, iov[i].iov_len); __dump_buffer(iov[i].iov_base, offset, l); len -= l; offset += l; } } #ifdef HAVE_PREADV static int do_preadv( int fd, off64_t offset, ssize_t count, ssize_t buffer_size) { int vecs = 0; ssize_t oldlen = 0; ssize_t bytes = 0; /* trim the iovec if necessary */ if (count < buffersize) { size_t len = 0; while (len + iov[vecs].iov_len < count) { len += iov[vecs].iov_len; vecs++; } oldlen = iov[vecs].iov_len; iov[vecs].iov_len = count - len; vecs++; } else { vecs = vectors; } bytes = preadv(fd, iov, vectors, offset); /* restore trimmed iov */ if (oldlen) iov[vecs - 1].iov_len = oldlen; return bytes; } #else #define do_preadv(fd, offset, count, buffer_size) (0) #endif static int do_pread( int fd, off64_t offset, ssize_t count, ssize_t buffer_size) { if (!vectors) return pread64(fd, buffer, min(count, buffer_size), offset); return do_preadv(fd, offset, count, buffer_size); } static int read_random( int fd, off64_t offset, long long count, long long *total, unsigned int seed, int eof) { off64_t end, off, range; ssize_t bytes; int ops = 0; srandom(seed); end = lseek64(fd, 0, SEEK_END); offset = (eof || offset > end) ? end : offset; if ((bytes = (offset % buffersize))) offset -= bytes; offset = max(0, offset); if ((bytes = (count % buffersize))) count += bytes; count = max(buffersize, count); range = count - buffersize; *total = 0; while (count > 0) { off = ((random() % range) / buffersize) * buffersize; bytes = do_pread(fd, off, buffersize, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pread64"); return -1; } ops++; *total += bytes; if (bytes < buffersize) break; count -= bytes; } return ops; } static int read_backward( int fd, off64_t *offset, long long *count, long long *total, int eof) { off64_t end, off = *offset; ssize_t bytes = 0, bytes_requested; long long cnt = *count; int ops = 0; end = lseek64(fd, 0, SEEK_END); off = eof ? end : min(end, lseek64(fd, off, SEEK_SET)); if ((end = off - cnt) < 0) { cnt += end; /* subtraction, end is negative */ end = 0; } *total = 0; *count = cnt; *offset = off; /* Do initial unaligned read if needed */ if ((bytes_requested = (off % buffersize))) { off -= bytes_requested; bytes = do_pread(fd, off, bytes_requested, buffersize); if (bytes == 0) return ops; if (bytes < 0) { perror("pread64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) return ops; cnt -= bytes; } /* Iterate backward through the rest of the range */ while (cnt > end) { bytes_requested = min(cnt, buffersize); off -= bytes_requested; bytes = do_pread(fd, off, cnt, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pread64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) break; cnt -= bytes; } return ops; } static int read_forward( int fd, off64_t offset, long long count, long long *total, int verbose, int onlyone, int eof) { ssize_t bytes; int ops = 0; *total = 0; while (count > 0 || eof) { bytes = do_pread(fd, offset, count, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pread64"); return -1; } ops++; if (verbose) dump_buffer(offset, bytes); *total += bytes; if (onlyone || bytes < min(count, buffersize)) break; offset += bytes; count -= bytes; } return ops; } int read_buffer( int fd, off64_t offset, long long count, long long *total, int verbose, int onlyone) { return read_forward(fd, offset, count, total, verbose, onlyone, 0); } static int pread_f( int argc, char **argv) { size_t bsize; off64_t offset; unsigned int zeed = 0; long long count, total, tmp; size_t fsblocksize, fssectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *sp; int Cflag, qflag, uflag, vflag; int eof = 0, direction = IO_FORWARD; int c; Cflag = qflag = uflag = vflag = 0; init_cvtnum(&fsblocksize, &fssectsize); bsize = fsblocksize; while ((c = getopt(argc, argv, "b:BCFRquvV:Z:")) != EOF) { switch (c) { case 'b': tmp = cvtnum(fsblocksize, fssectsize, optarg); if (tmp < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } bsize = tmp; break; case 'C': Cflag = 1; break; case 'F': direction = IO_FORWARD; break; case 'B': direction = IO_BACKWARD; break; case 'R': direction = IO_RANDOM; break; case 'q': qflag = 1; break; case 'u': uflag = 1; break; case 'v': vflag = 1; break; #ifdef HAVE_PREADV case 'V': vectors = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric vector count == %s\n"), optarg); return 0; } break; #endif case 'Z': zeed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&pread_cmd); } } if (optind != argc - 2) return command_usage(&pread_cmd); offset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (offset < 0 && (direction & (IO_RANDOM|IO_BACKWARD))) { eof = -1; /* read from EOF */ } else if (offset < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 0 && (direction & (IO_RANDOM|IO_FORWARD))) { eof = -1; /* read to EOF */ } else if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } if (alloc_buffer(bsize, uflag, 0xabababab) < 0) return 0; gettimeofday(&t1, NULL); switch (direction) { case IO_RANDOM: if (!zeed) /* srandom seed */ zeed = time(NULL); c = read_random(file->fd, offset, count, &total, zeed, eof); break; case IO_FORWARD: c = read_forward(file->fd, offset, count, &total, vflag, 0, eof); if (eof) count = total; break; case IO_BACKWARD: c = read_backward(file->fd, &offset, &count, &total, eof); break; default: ASSERT(0); } if (c < 0) return 0; if (qflag) return 0; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("read %lld/%lld bytes at offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } return 0; } void pread_init(void) { pread_cmd.name = "pread"; pread_cmd.altname = "r"; pread_cmd.cfunc = pread_f; pread_cmd.argmin = 2; pread_cmd.argmax = -1; pread_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; pread_cmd.args = _("[-b bs] [-v] [-i N] [-FBR [-Z N]] off len"); pread_cmd.oneline = _("reads a number of bytes at a specified offset"); pread_cmd.help = pread_help; add_command(&pread_cmd); } xfsprogs-3.1.9ubuntu2/io/pwrite.c0000664000000000000000000002320612062210562013700 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t pwrite_cmd; static void pwrite_help(void) { printf(_( "\n" " writes a range of bytes (in block size increments) from the given offset\n" "\n" " Example:\n" " 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Writes into a segment of the currently open file, using either a buffer\n" " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n" " The writes are performed in sequential blocks starting at offset, with the\n" " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n" " unless a different write pattern is requested.\n" " -S -- use an alternate seed number for filling the write buffer\n" " -i -- input file, source of data to write (used when writing forward)\n" " -d -- open the input file for direct IO\n" " -s -- skip a number of bytes at the start of the input file\n" " -w -- call fdatasync(2) at the end (included in timing results)\n" " -W -- call fsync(2) at the end (included in timing results)\n" " -B -- write backwards through the range from offset (backwards N bytes)\n" " -F -- write forwards through the range of bytes from offset (default)\n" " -R -- write at random offsets in the specified range of bytes\n" " -Z N -- zeed the random number generator (used when writing randomly)\n" " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n" #ifdef HAVE_PWRITEV " -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n" #endif "\n")); } #ifdef HAVE_PWRITEV static int do_pwritev( int fd, off64_t offset, ssize_t count, ssize_t buffer_size) { int vecs = 0; ssize_t oldlen = 0; ssize_t bytes = 0; /* trim the iovec if necessary */ if (count < buffersize) { size_t len = 0; while (len + iov[vecs].iov_len < count) { len += iov[vecs].iov_len; vecs++; } oldlen = iov[vecs].iov_len; iov[vecs].iov_len = count - len; vecs++; } else { vecs = vectors; } bytes = pwritev(fd, iov, vectors, offset); /* restore trimmed iov */ if (oldlen) iov[vecs - 1].iov_len = oldlen; return bytes; } #else #define do_pwritev(fd, offset, count, buffer_size) (0) #endif static int do_pwrite( int fd, off64_t offset, ssize_t count, ssize_t buffer_size) { if (!vectors) return pwrite64(fd, buffer, min(count, buffer_size), offset); return do_pwritev(fd, offset, count, buffer_size); } static int write_random( off64_t offset, long long count, unsigned int seed, long long *total) { off64_t off, range; ssize_t bytes; int ops = 0; srandom(seed); if ((bytes = (offset % buffersize))) offset -= bytes; offset = max(0, offset); if ((bytes = (count % buffersize))) count += bytes; count = max(buffersize, count); range = count - buffersize; *total = 0; while (count > 0) { off = ((random() % range) / buffersize) * buffersize; bytes = do_pwrite(file->fd, off, buffersize, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < buffersize) break; count -= bytes; } return ops; } static int write_backward( off64_t offset, long long *count, long long *total) { off64_t end, off = offset; ssize_t bytes = 0, bytes_requested; long long cnt = *count; int ops = 0; if ((end = off - cnt) < 0) { cnt += end; /* subtraction, end is negative */ end = 0; } *total = 0; *count = cnt; /* Do initial unaligned write if needed */ if ((bytes_requested = (off % buffersize))) { bytes_requested = min(cnt, bytes_requested); off -= bytes_requested; bytes = do_pwrite(file->fd, off, bytes_requested, buffersize); if (bytes == 0) return ops; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) return ops; cnt -= bytes; } /* Iterate backward through the rest of the range */ while (cnt > end) { bytes_requested = min(cnt, buffersize); off -= bytes_requested; bytes = do_pwrite(file->fd, off, cnt, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) break; cnt -= bytes; } return ops; } static int write_buffer( off64_t offset, long long count, size_t bs, int fd, off64_t skip, long long *total) { ssize_t bytes; long long bar = min(bs, count); int ops = 0; *total = 0; while (count >= 0) { if (fd > 0) { /* input file given, read buffer first */ if (read_buffer(fd, skip + *total, bs, &bar, 0, 1) < 0) break; } bytes = do_pwrite(file->fd, offset, count, bar); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < min(count, bar)) break; offset += bytes; count -= bytes; if (count == 0) break; } return ops; } static int pwrite_f( int argc, char **argv) { size_t bsize; off64_t offset, skip = 0; long long count, total, tmp; unsigned int zeed = 0, seed = 0xcdcdcdcd; size_t fsblocksize, fssectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *sp, *infile = NULL; int Cflag, qflag, uflag, dflag, wflag, Wflag; int direction = IO_FORWARD; int c, fd = -1; Cflag = qflag = uflag = dflag = wflag = Wflag = 0; init_cvtnum(&fsblocksize, &fssectsize); bsize = fsblocksize; while ((c = getopt(argc, argv, "b:Cdf:i:qs:S:uV:wWZ:")) != EOF) { switch (c) { case 'b': tmp = cvtnum(fsblocksize, fssectsize, optarg); if (tmp < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } bsize = tmp; break; case 'C': Cflag = 1; break; case 'F': direction = IO_FORWARD; break; case 'B': direction = IO_BACKWARD; break; case 'R': direction = IO_RANDOM; break; case 'd': dflag = 1; break; case 'f': case 'i': infile = optarg; break; case 's': skip = cvtnum(fsblocksize, fssectsize, optarg); if (skip < 0) { printf(_("non-numeric skip -- %s\n"), optarg); return 0; } break; case 'S': seed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; case 'q': qflag = 1; break; case 'u': uflag = 1; break; case 'V': vectors = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric vector count == %s\n"), optarg); return 0; } break; case 'w': wflag = 1; break; case 'W': Wflag = 1; break; case 'Z': zeed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&pwrite_cmd); } } if (((skip || dflag) && !infile) || (optind != argc - 2)) return command_usage(&pwrite_cmd); if (infile && direction != IO_FORWARD) return command_usage(&pwrite_cmd); offset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } if (alloc_buffer(bsize, uflag, seed) < 0) return 0; c = IO_READONLY | (dflag ? IO_DIRECT : 0); if (infile && ((fd = openfile(infile, NULL, c, 0)) < 0)) return 0; gettimeofday(&t1, NULL); switch (direction) { case IO_RANDOM: if (!zeed) /* srandom seed */ zeed = time(NULL); c = write_random(offset, count, zeed, &total); break; case IO_FORWARD: c = write_buffer(offset, count, bsize, fd, skip, &total); break; case IO_BACKWARD: c = write_backward(offset, &count, &total); break; default: total = 0; ASSERT(0); } if (c < 0) goto done; if (Wflag) fsync(file->fd); if (wflag) fdatasync(file->fd); if (qflag) goto done; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("wrote %lld/%lld bytes at offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } done: if (infile) close(fd); return 0; } void pwrite_init(void) { pwrite_cmd.name = "pwrite"; pwrite_cmd.altname = "w"; pwrite_cmd.cfunc = pwrite_f; pwrite_cmd.argmin = 2; pwrite_cmd.argmax = -1; pwrite_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; pwrite_cmd.args = _("[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off len"); pwrite_cmd.oneline = _("writes a number of bytes at a specified offset"); pwrite_cmd.help = pwrite_help; add_command(&pwrite_cmd); } xfsprogs-3.1.9ubuntu2/io/resblks.c0000664000000000000000000000365211604735741014052 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t resblks_cmd; static int resblks_f(int argc, char **argv); static int resblks_f( int argc, char **argv) { xfs_fsop_resblks_t res; long long blks; if (argc == 2) { blks = cvtnum(file->geom.blocksize, file->geom.sectsize, argv[1]); if (blks < 0) { printf(_("non-numeric argument -- %s\n"), argv[1]); return 0; } res.resblks = blks; if (xfsctl(file->name, file->fd, XFS_IOC_SET_RESBLKS, &res) < 0) { perror("XFS_IOC_SET_RESBLKS"); return 0; } } else if (xfsctl(file->name, file->fd, XFS_IOC_GET_RESBLKS, &res) < 0) { perror("XFS_IOC_GET_RESBLKS"); return 0; } printf(_("reserved blocks = %llu\n"), (unsigned long long) res.resblks); printf(_("available reserved blocks = %llu\n"), (unsigned long long) res.resblks_avail); return 0; } void resblks_init(void) { resblks_cmd.name = "resblks"; resblks_cmd.cfunc = resblks_f; resblks_cmd.argmin = 0; resblks_cmd.argmax = 1; resblks_cmd.flags = CMD_NOMAP_OK; resblks_cmd.args = _("[blocks]"); resblks_cmd.oneline = _("get and/or set count of reserved filesystem blocks"); if (expert) add_command(&resblks_cmd); } xfsprogs-3.1.9ubuntu2/io/mmap.c0000664000000000000000000003573111604735741013342 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t mmap_cmd; static cmdinfo_t mread_cmd; static cmdinfo_t msync_cmd; static cmdinfo_t munmap_cmd; static cmdinfo_t mwrite_cmd; mmap_region_t *maptable; int mapcount; mmap_region_t *mapping; static void print_mapping( mmap_region_t *map, int index, int braces) { unsigned char buffer[8] = { 0 }; int i; static struct { int prot; int mode; } *p, pflags[] = { { PROT_READ, 'r' }, { PROT_WRITE, 'w' }, { PROT_EXEC, 'x' }, { PROT_NONE, 0 } }; for (i = 0, p = pflags; p->prot != PROT_NONE; i++, p++) buffer[i] = (map->prot & p->prot) ? p->mode : '-'; printf("%c%03d%c 0x%lx - 0x%lx %s %14s (%lld : %ld)\n", braces? '[' : ' ', index, braces? ']' : ' ', (unsigned long)map->addr, (unsigned long)((char *)map->addr + map->length), buffer, map->name ? map->name : "???", (long long)map->offset, (long)map->length); } void * check_mapping_range( mmap_region_t *map, off64_t offset, size_t length, int pagealign) { off64_t relative; if (offset < mapping->offset) { printf(_("offset (%lld) is before start of mapping (%lld)\n"), (long long)offset, (long long)mapping->offset); return NULL; } relative = offset - mapping->offset; if (relative > mapping->length) { printf(_("offset (%lld) is beyond end of mapping (%lld)\n"), (long long)relative, (long long)mapping->offset); return NULL; } if ((relative + length) > (mapping->offset + mapping->length)) { printf(_("range (%lld:%lld) is beyond mapping (%lld:%ld)\n"), (long long)offset, (long long)relative, (long long)mapping->offset, (long)mapping->length); return NULL; } if (pagealign && (long)((char *)mapping->addr + relative) % pagesize) { printf(_("offset address (%p) is not page aligned\n"), (char *)mapping->addr + relative); return NULL; } return (char *)mapping->addr + relative; } int maplist_f(void) { int i; for (i = 0; i < mapcount; i++) print_mapping(&maptable[i], i, &maptable[i] == mapping); return 0; } static int mapset_f( int argc, char **argv) { int i; ASSERT(argc == 2); i = atoi(argv[1]); if (i < 0 || i >= mapcount) { printf("value %d is out of range (0-%d)\n", i, mapcount); } else { mapping = &maptable[i]; maplist_f(); } return 0; } static void mmap_help(void) { printf(_( "\n" " maps a range within the current file into memory\n" "\n" " Example:\n" " 'mmap -rw 0 1m' - maps one megabyte from the start of the current file\n" "\n" " Memory maps a range of a file for subsequent use by other xfs_io commands.\n" " With no arguments, mmap shows the current mappings. The current mapping\n" " can be set by using the single argument form (mapping number or address).\n" " If two arguments are specified (a range), a new mapping is created and the\n" " following options are available:\n" " -r -- map with PROT_READ protection\n" " -w -- map with PROT_WRITE protection\n" " -x -- map with PROT_EXEC protection\n" " If no protection mode is specified, all are used by default.\n" "\n")); } static int mmap_f( int argc, char **argv) { off64_t offset; ssize_t length; void *address; char *filename; size_t blocksize, sectsize; int c, prot = 0; if (argc == 1) { if (mapping) return maplist_f(); fprintf(stderr, file ? _("no mapped regions, try 'help mmap'\n") : _("no files are open, try 'help open'\n")); return 0; } else if (argc == 2) { if (mapping) return mapset_f(argc, argv); fprintf(stderr, file ? _("no mapped regions, try 'help mmap'\n") : _("no files are open, try 'help open'\n")); return 0; } else if (!file) { fprintf(stderr, _("no files are open, try 'help open'\n")); return 0; } while ((c = getopt(argc, argv, "rwx")) != EOF) { switch (c) { case 'r': prot |= PROT_READ; break; case 'w': prot |= PROT_WRITE; break; case 'x': prot |= PROT_EXEC; break; default: return command_usage(&mmap_cmd); } } if (!prot) prot = PROT_READ | PROT_WRITE | PROT_EXEC; if (optind != argc - 2) return command_usage(&mmap_cmd); init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } filename = strdup(file->name); if (!filename) { perror("strdup"); return 0; } address = mmap(NULL, length, prot, MAP_SHARED, file->fd, offset); if (address == MAP_FAILED) { perror("mmap"); free(filename); return 0; } /* Extend the control array of mmap'd regions */ maptable = (mmap_region_t *)realloc(maptable, /* growing */ ++mapcount * sizeof(mmap_region_t)); if (!maptable) { perror("realloc"); mapcount = 0; munmap(address, length); free(filename); return 0; } /* Finally, make this the new active mapping */ mapping = &maptable[mapcount - 1]; mapping->addr = address; mapping->length = length; mapping->offset = offset; mapping->name = filename; mapping->prot = prot; return 0; } static void msync_help(void) { printf(_( "\n" " flushes a range of bytes in the current memory mapping\n" "\n" " Writes all modified copies of pages over the specified range (or entire\n" " mapping if no range specified) to their backing storage locations. Also,\n" " optionally invalidates so that subsequent references to the pages will be\n" " obtained from their backing storage locations (instead of cached copies).\n" " -a -- perform asynchronous writes (MS_ASYNC)\n" " -i -- invalidate mapped pages (MS_INVALIDATE)\n" " -s -- perform synchronous writes (MS_SYNC)\n" "\n")); } int msync_f( int argc, char **argv) { off64_t offset; ssize_t length; void *start; int c, flags = 0; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "ais")) != EOF) { switch (c) { case 'a': flags |= MS_ASYNC; break; case 'i': flags |= MS_INVALIDATE; break; case 's': flags |= MS_SYNC; break; default: return command_usage(&msync_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&msync_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; if (msync(start, length, flags) < 0) perror("msync"); return 0; } static void mread_help(void) { printf(_( "\n" " reads a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mread -v 512 20' - dumps 20 bytes read from 512 bytes into the mapping\n" "\n" " Accesses a range of the current memory mapping, optionally dumping it to\n" " the standard output stream (with -v option) for subsequent inspection.\n" " -f -- verbose mode, dump bytes with offsets relative to start of file.\n" " -r -- reverse order; start accessing from the end of range, moving backward\n" " -v -- verbose mode, dump bytes with offsets relative to start of mapping.\n" " The accesses are performed sequentially from the start offset by default.\n" " Notes:\n" " References to whole pages following the end of the backing file results\n" " in delivery of the SIGBUS signal. SIGBUS signals may also be delivered\n" " on various filesystem conditions, including quota exceeded errors, and\n" " for physical device errors (such as unreadable disk blocks). No attempt\n" " has been made to catch signals at this stage...\n" "\n")); } int mread_f( int argc, char **argv) { off64_t offset, tmp, dumpoffset, printoffset; ssize_t length; size_t dumplen, cnt = 0; char *bp; void *start; int dump = 0, rflag = 0, c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "frv")) != EOF) { switch (c) { case 'f': dump = 2; /* file offset dump */ break; case 'r': rflag = 1; /* read in reverse */ break; case 'v': dump = 1; /* mapping offset dump */ break; default: return command_usage(&mread_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&mread_cmd); } start = check_mapping_range(mapping, offset, length, 0); if (!start) return 0; dumpoffset = offset - mapping->offset; if (dump == 2) printoffset = offset; else printoffset = dumpoffset; if (alloc_buffer(pagesize, 0, 0) < 0) return 0; bp = (char *)buffer; dumplen = length % pagesize; if (!dumplen) dumplen = pagesize; if (rflag) { for (tmp = length - 1, c = 0; tmp >= 0; tmp--, c = 1) { *bp = *(((char *)mapping->addr) + dumpoffset + tmp); cnt++; if (c && cnt == dumplen) { if (dump) { dump_buffer(printoffset, dumplen); printoffset += dumplen; } bp = (char *)buffer; dumplen = pagesize; cnt = 0; } else { bp++; } } } else { for (tmp = 0, c = 0; tmp < length; tmp++, c = 1) { *bp = *(((char *)mapping->addr) + dumpoffset + tmp); cnt++; if (c && cnt == dumplen) { if (dump) dump_buffer(printoffset + tmp - (dumplen - 1), dumplen); bp = (char *)buffer; dumplen = pagesize; cnt = 0; } else { bp++; } } } return 0; } int munmap_f( int argc, char **argv) { ssize_t length; unsigned int offset; if (munmap(mapping->addr, mapping->length) < 0) { perror("munmap"); return 0; } free(mapping->name); /* Shuffle the mapping table entries down over the removed entry */ offset = mapping - &maptable[0]; length = mapcount * sizeof(mmap_region_t); length -= (offset + 1) * sizeof(mmap_region_t); if (length) memmove(mapping, mapping + 1, length); /* Resize the memory allocated for the table, possibly freeing */ if (--mapcount) { maptable = (mmap_region_t *)realloc(maptable, /* shrinking */ mapcount * sizeof(mmap_region_t)); if (offset == mapcount) offset--; mapping = maptable + offset; } else { free(maptable); mapping = maptable = NULL; } maplist_f(); return 0; } static void mwrite_help(void) { printf(_( "\n" " dirties a range of bytes in the current memory mapping\n" "\n" " Example:\n" " 'mwrite 512 20 - writes 20 bytes at 512 bytes into the current mapping.\n" "\n" " Stores a byte into memory for a range within a mapping.\n" " The default stored value is 'X', repeated to fill the range specified.\n" " -S -- use an alternate seed character\n" " -r -- reverse order; start storing from the end of range, moving backward\n" " The stores are performed sequentially from the start offset by default.\n" "\n")); } int mwrite_f( int argc, char **argv) { off64_t offset, tmp; ssize_t length; void *start; char *sp; int seed = 'X'; int rflag = 0; int c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "rS:")) != EOF) { switch (c) { case 'r': rflag = 1; break; case 'S': seed = (int)strtol(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&mwrite_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&mwrite_cmd); } start = check_mapping_range(mapping, offset, length, 0); if (!start) return 0; offset -= mapping->offset; if (rflag) { for (tmp = offset + length -1; tmp >= offset; tmp--) ((char *)mapping->addr)[tmp] = seed; } else { for (tmp = offset; tmp < offset + length; tmp++) ((char *)mapping->addr)[tmp] = seed; } return 0; } void mmap_init(void) { mmap_cmd.name = "mmap"; mmap_cmd.altname = "mm"; mmap_cmd.cfunc = mmap_f; mmap_cmd.argmin = 0; mmap_cmd.argmax = -1; mmap_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK; mmap_cmd.args = _("[N] | [-rwx] [off len]"); mmap_cmd.oneline = _("mmap a range in the current file, show mappings"); mmap_cmd.help = mmap_help; mread_cmd.name = "mread"; mread_cmd.altname = "mr"; mread_cmd.cfunc = mread_f; mread_cmd.argmin = 0; mread_cmd.argmax = -1; mread_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; mread_cmd.args = _("[-r] [off len]"); mread_cmd.oneline = _("reads data from a region in the current memory mapping"); mread_cmd.help = mread_help; msync_cmd.name = "msync"; msync_cmd.altname = "ms"; msync_cmd.cfunc = msync_f; msync_cmd.argmin = 0; msync_cmd.argmax = -1; msync_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; msync_cmd.args = _("[-ais] [off len]"); msync_cmd.oneline = _("flush a region in the current memory mapping"); msync_cmd.help = msync_help; munmap_cmd.name = "munmap"; munmap_cmd.altname = "mu"; munmap_cmd.cfunc = munmap_f; munmap_cmd.argmin = 0; munmap_cmd.argmax = 0; munmap_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; munmap_cmd.oneline = _("unmaps the current memory mapping"); mwrite_cmd.name = "mwrite"; mwrite_cmd.altname = "mw"; mwrite_cmd.cfunc = mwrite_f; mwrite_cmd.argmin = 0; mwrite_cmd.argmax = -1; mwrite_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; mwrite_cmd.args = _("[-r] [-S seed] [off len]"); mwrite_cmd.oneline = _("writes data into a region in the current memory mapping"); mwrite_cmd.help = mwrite_help; add_command(&mmap_cmd); add_command(&mread_cmd); add_command(&msync_cmd); add_command(&munmap_cmd); add_command(&mwrite_cmd); } xfsprogs-3.1.9ubuntu2/io/parent.c0000664000000000000000000002455311650373061013673 0ustar /* * Copyright (c) 2005-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include "init.h" #include "io.h" #define PARENTBUF_SZ 16384 #define BSTATBUF_SZ 16384 static cmdinfo_t parent_cmd; static int verbose_flag; static int err_status; static __u64 inodes_checked; static char *mntpt; /* * check out a parent entry to see if the values seem valid */ static void check_parent_entry(xfs_bstat_t *bstatp, parent_t *parent) { int sts; char fullpath[PATH_MAX]; struct stat statbuf; char *str; sprintf(fullpath, _("%s%s"), mntpt, parent->p_name); sts = lstat(fullpath, &statbuf); if (sts != 0) { fprintf(stderr, _("inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n"), (unsigned long long) bstatp->bs_ino, fullpath); if (verbose_flag) { fprintf(stderr, _("path \"%s\" does not stat for inode: %llu; err = %s\n"), fullpath, (unsigned long long) bstatp->bs_ino, strerror(errno)); } err_status++; return; } else { if (verbose_flag > 1) { printf(_("path \"%s\" found\n"), fullpath); } } if (statbuf.st_ino != bstatp->bs_ino) { fprintf(stderr, _("inode-path for inode: %llu is incorrect - wrong inode#\n"), (unsigned long long) bstatp->bs_ino); if (verbose_flag) { fprintf(stderr, _("ino mismatch for path \"%s\" %llu vs %llu\n"), fullpath, (unsigned long long)statbuf.st_ino, (unsigned long long)bstatp->bs_ino); } err_status++; return; } else if (verbose_flag > 1) { printf(_("inode number match: %llu\n"), (unsigned long long)statbuf.st_ino); } /* get parent path */ str = strrchr(fullpath, '/'); *str = '\0'; sts = stat(fullpath, &statbuf); if (sts != 0) { fprintf(stderr, _("parent path \"%s\" does not stat: %s\n"), fullpath, strerror(errno)); err_status++; return; } else { if (parent->p_ino != statbuf.st_ino) { fprintf(stderr, _("inode-path for inode: %llu is incorrect - wrong parent inode#\n"), (unsigned long long) bstatp->bs_ino); if (verbose_flag) { fprintf(stderr, _("ino mismatch for path \"%s\" %llu vs %llu\n"), fullpath, (unsigned long long)parent->p_ino, (unsigned long long)statbuf.st_ino); } err_status++; return; } else { if (verbose_flag > 1) { printf(_("parent ino match for %llu\n"), (unsigned long long) parent->p_ino); } } } } static void check_parents(parent_t *parentbuf, size_t *parentbuf_size, jdm_fshandle_t *fshandlep, xfs_bstat_t *statp) { int error, i; __u32 count; parent_t *entryp; do { error = jdm_parentpaths(fshandlep, statp, parentbuf, *parentbuf_size, &count); if (error == ERANGE) { *parentbuf_size *= 2; parentbuf = (parent_t *)realloc(parentbuf, *parentbuf_size); } else if (error) { fprintf(stderr, _("parentpaths failed for ino %llu: %s\n"), (unsigned long long) statp->bs_ino, strerror(errno)); err_status++; break; } } while (error == ERANGE); if (count == 0) { /* no links for inode - something wrong here */ fprintf(stderr, _("inode-path for inode: %llu is missing\n"), (unsigned long long) statp->bs_ino); err_status++; } entryp = parentbuf; for (i = 0; i < count; i++) { check_parent_entry(statp, entryp); entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); } } static int do_bulkstat(parent_t *parentbuf, size_t *parentbuf_size, xfs_bstat_t *bstatbuf, int fsfd, jdm_fshandle_t *fshandlep) { __s32 buflenout; __u64 lastino = 0; xfs_bstat_t *p; xfs_bstat_t *endp; xfs_fsop_bulkreq_t bulkreq; struct stat mntstat; if (stat(mntpt, &mntstat)) { fprintf(stderr, _("can't stat mount point \"%s\": %s\n"), mntpt, strerror(errno)); return 1; } bulkreq.lastip = &lastino; bulkreq.icount = BSTATBUF_SZ; bulkreq.ubuffer = (void *)bstatbuf; bulkreq.ocount = &buflenout; while (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) == 0) { if (*(bulkreq.ocount) == 0) { return 0; } for (p = bstatbuf, endp = bstatbuf + *bulkreq.ocount; p < endp; p++) { /* inode being modified, get synced data with iget */ if ( (!p->bs_nlink || !p->bs_mode) && p->bs_ino != 0 ) { if (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq) < 0) { fprintf(stderr, _("failed to get bulkstat information for inode %llu\n"), (unsigned long long) p->bs_ino); continue; } if (!p->bs_nlink || !p->bs_mode || !p->bs_ino) { fprintf(stderr, _("failed to get valid bulkstat information for inode %llu\n"), (unsigned long long) p->bs_ino); continue; } } /* skip root */ if (p->bs_ino == mntstat.st_ino) { continue; } if (verbose_flag > 1) { printf(_("checking inode %llu\n"), (unsigned long long) p->bs_ino); } /* print dotted progress */ if ((inodes_checked % 100) == 0 && verbose_flag == 1) { printf("."); fflush(stdout); } inodes_checked++; check_parents(parentbuf, parentbuf_size, fshandlep, p); } }/*while*/ fprintf(stderr, _("syssgi bulkstat failed: %s\n"), strerror(errno)); return 1; } static int parent_check(void) { int fsfd; jdm_fshandle_t *fshandlep; parent_t *parentbuf; size_t parentbuf_size = PARENTBUF_SZ; xfs_bstat_t *bstatbuf; err_status = 0; inodes_checked = 0; sync(); fsfd = file->fd; fshandlep = jdm_getfshandle(mntpt); if (fshandlep == NULL) { fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"), mntpt, strerror(errno)); return 1; } /* allocate buffers */ bstatbuf = (xfs_bstat_t *)calloc(BSTATBUF_SZ, sizeof(xfs_bstat_t)); parentbuf = (parent_t *)malloc(parentbuf_size); if (!bstatbuf || !parentbuf) { fprintf(stderr, _("unable to allocate buffers: %s\n"), strerror(errno)); return 1; } if (do_bulkstat(parentbuf, &parentbuf_size, bstatbuf, fsfd, fshandlep) != 0) err_status++; if (err_status > 0) fprintf(stderr, _("num errors: %d\n"), err_status); else printf(_("succeeded checking %llu inodes\n"), (unsigned long long) inodes_checked); free(bstatbuf); free(parentbuf); return err_status; } static void print_parent_entry(parent_t *parent, int fullpath) { printf(_("p_ino = %llu\n"), (unsigned long long) parent->p_ino); printf(_("p_gen = %u\n"), parent->p_gen); printf(_("p_reclen = %u\n"), parent->p_reclen); if (fullpath) printf(_("p_name = \"%s%s\"\n"), mntpt, parent->p_name); else printf(_("p_name = \"%s\"\n"), parent->p_name); } static int parent_list(int fullpath) { void *handlep; size_t handlen; int error, i; int retval = 1; __u32 count; parent_t *entryp; parent_t *parentbuf = NULL; char *path = file->name; int pb_size = PARENTBUF_SZ; /* XXXX for linux libhandle version - to set libhandle fsfd cache */ { void *fshandle; size_t fshlen; if (path_to_fshandle(mntpt, &fshandle, &fshlen) != 0) { fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"), progname, path, strerror(errno)); goto error; } } if (path_to_handle(path, &handlep, &handlen) != 0) { fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path); goto error; } do { parentbuf = (parent_t *)realloc(parentbuf, pb_size); if (!parentbuf) { fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"), progname, strerror(errno)); return 1; } if (fullpath) { error = parentpaths_by_handle(handlep, handlen, parentbuf, pb_size, &count); } else { error = parents_by_handle(handlep, handlen, parentbuf, pb_size, &count); } if (error == ERANGE) { pb_size *= 2; } else if (error) { fprintf(stderr, _("%s: %s call failed for \"%s\": %s\n"), progname, fullpath ? "parentpaths" : "parents", path, strerror(errno)); goto error; } } while (error == ERANGE); if (count == 0) { /* no links for inode - something wrong here */ fprintf(stderr, _("%s: inode-path is missing\n"), progname); goto error; } entryp = parentbuf; for (i = 0; i < count; i++) { print_parent_entry(entryp, fullpath); entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); } retval = 0; error: free(parentbuf); return retval; } int parent_f(int argc, char **argv) { int c; int listpath_flag = 0; int check_flag = 0; fs_path_t *fs; static int tab_init; if (!tab_init) { tab_init = 1; fs_table_initialise(0, NULL, 0, NULL); } fs = fs_table_lookup(file->name, FS_MOUNT_POINT); if (!fs) { fprintf(stderr, _("file argument, \"%s\", is not in a mounted XFS filesystem\n"), file->name); return 1; } mntpt = fs->fs_dir; verbose_flag = 0; while ((c = getopt(argc, argv, "cpv")) != EOF) { switch (c) { case 'c': check_flag = 1; break; case 'p': listpath_flag = 1; break; case 'v': verbose_flag++; break; default: return command_usage(&parent_cmd); } } if (!check_flag && !listpath_flag) /* default case */ exitcode = parent_list(listpath_flag); else { if (listpath_flag) exitcode = parent_list(listpath_flag); if (check_flag) exitcode = parent_check(); } return 0; } static void parent_help(void) { printf(_( "\n" " list the current file's parents and their filenames\n" "\n" " -c -- check the current file's file system for parent consistency\n" " -p -- list the current file's parents and their full paths\n" " -v -- verbose mode\n" "\n")); } void parent_init(void) { parent_cmd.name = "parent"; parent_cmd.cfunc = parent_f; parent_cmd.argmin = 0; parent_cmd.argmax = -1; parent_cmd.args = _("[-cpv]"); parent_cmd.flags = CMD_NOMAP_OK; parent_cmd.oneline = _("print or check parent inodes"); parent_cmd.help = parent_help; if (expert) add_command(&parent_cmd); } xfsprogs-3.1.9ubuntu2/io/io.h0000664000000000000000000001001612062210562012775 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Read/write patterns (default is always "forward") */ #define IO_RANDOM ( 0) #define IO_FORWARD ( 1) #define IO_BACKWARD (-1) /* * File descriptor options */ #define IO_READONLY (1<<0) #define IO_DIRECT (1<<1) #define IO_REALTIME (1<<2) #define IO_APPEND (1<<3) #define IO_OSYNC (1<<4) #define IO_CREAT (1<<5) #define IO_TRUNC (1<<6) #define IO_FOREIGN (1<<7) #define IO_NONBLOCK (1<<8) /* * Regular file I/O control */ typedef struct fileio { int fd; /* open file descriptor */ int flags; /* flags describing file state */ char *name; /* file name at time of open */ xfs_fsop_geom_t geom; /* XFS filesystem geometry */ } fileio_t; extern fileio_t *filetable; /* open file table */ extern int filecount; /* number of open files */ extern fileio_t *file; /* active file in file table */ extern int filelist_f(void); /* * Memory mapped file regions */ typedef struct mmap_region { void *addr; /* address of start of mapping */ size_t length; /* length of mapping */ off64_t offset; /* start offset into backing file */ int prot; /* protection mode of the mapping */ char *name; /* name of backing file */ } mmap_region_t; extern mmap_region_t *maptable; /* mmap'd region array */ extern int mapcount; /* #entries in the mapping table */ extern mmap_region_t *mapping; /* active mapping table entry */ extern int maplist_f(void); extern void *check_mapping_range(mmap_region_t *, off64_t, size_t, int); /* * Various xfs_io helper routines/globals */ extern off64_t filesize(void); extern int openfile(char *, xfs_fsop_geom_t *, int, mode_t); extern int addfile(char *, int , xfs_fsop_geom_t *, int); extern void printxattr(uint, int, int, const char *, int, int); extern unsigned int recurse_all; extern unsigned int recurse_dir; extern void *buffer; extern size_t buffersize; extern int vectors; extern struct iovec *iov; extern int alloc_buffer(size_t, int, unsigned int); extern int read_buffer(int, off64_t, long long, long long *, int, int); extern void dump_buffer(off64_t, ssize_t); extern void attr_init(void); extern void bmap_init(void); extern void file_init(void); extern void freeze_init(void); extern void fsync_init(void); extern void getrusage_init(void); extern void help_init(void); extern void imap_init(void); extern void inject_init(void); extern void mmap_init(void); extern void open_init(void); extern void parent_init(void); extern void pread_init(void); extern void prealloc_init(void); extern void pwrite_init(void); extern void quit_init(void); extern void shutdown_init(void); extern void truncate_init(void); #ifdef HAVE_FADVISE extern void fadvise_init(void); #else #define fadvise_init() do { } while (0) #endif #ifdef HAVE_RESBLKS extern void resblks_init(void); #else #define resblks_init() do { } while (0) #endif #ifdef HAVE_SENDFILE extern void sendfile_init(void); #else #define sendfile_init() do { } while (0) #endif #ifdef HAVE_MADVISE extern void madvise_init(void); #else #define madvise_init() do { } while (0) #endif #ifdef HAVE_MINCORE extern void mincore_init(void); #else #define mincore_init() do { } while (0) #endif #ifdef HAVE_FIEMAP extern void fiemap_init(void); #else #define fiemap_init() do { } while (0) #endif #ifdef HAVE_SYNC_FILE_RANGE extern void sync_range_init(void); #else #define sync_range_init() do { } while (0) #endif xfsprogs-3.1.9ubuntu2/io/fiemap.c0000664000000000000000000002043412062210562013627 0ustar /* * Copyright (c) 2010 Red Hat, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t fiemap_cmd; static void fiemap_help(void) { printf(_( "\n" " prints the block mapping for a file's data or attribute forks" "\n" " Example:\n" " 'fiemap -v' - tabular format verbose map\n" "\n" " fiemap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -v -- Verbose information\n" "\n")); } static int numlen( __u64 val, int base) { __u64 tmp; int len; for (len = 0, tmp = val; tmp > 0; tmp = tmp/base) len++; return (len == 0 ? 1 : len); } static void print_verbose( struct fiemap_extent *extent, int blocksize, int foff_w, int boff_w, int tot_w, int flg_w, int max_extents, int *cur_extent, __u64 *last_logical) { __u64 lstart; __u64 llast; __u64 len; __u64 block; char lbuf[48]; char bbuf[48]; char flgbuf[16]; llast = *last_logical / blocksize; lstart = extent->fe_logical / blocksize; len = extent->fe_length / blocksize; block = extent->fe_physical / blocksize; memset(lbuf, 0, sizeof(lbuf)); memset(bbuf, 0, sizeof(bbuf)); if (lstart != llast) { snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", llast, lstart - 1ULL); printf("%4d: %-*s %-*s %*llu\n", *cur_extent, foff_w, lbuf, boff_w, _("hole"), tot_w, lstart - llast); (*cur_extent)++; memset(lbuf, 0, sizeof(lbuf)); } if ((*cur_extent + 1) == max_extents) return; snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", lstart, lstart + len - 1ULL); snprintf(bbuf, sizeof(bbuf), "%llu..%llu", block, block + len - 1ULL); snprintf(flgbuf, sizeof(flgbuf), "0x%x", extent->fe_flags); printf("%4d: %-*s %-*s %*llu %*s\n", *cur_extent, foff_w, lbuf, boff_w, bbuf, tot_w, len, flg_w, flgbuf); (*cur_extent)++; *last_logical = extent->fe_logical + extent->fe_length; } static void print_plain( struct fiemap_extent *extent, int lflag, int blocksize, int max_extents, int *cur_extent, __u64 *last_logical) { __u64 lstart; __u64 llast; __u64 block; __u64 len; llast = *last_logical / blocksize; lstart = extent->fe_logical / blocksize; len = extent->fe_length / blocksize; block = extent->fe_physical / blocksize; if (lstart != llast) { printf("\t%d: [%llu..%llu]: hole", *cur_extent, llast, lstart - 1ULL); if (lflag) printf(_(" %llu blocks\n"), lstart - llast); else printf("\n"); (*cur_extent)++; } if ((*cur_extent + 1) == max_extents) return; printf("\t%d: [%llu..%llu]: %llu..%llu", *cur_extent, lstart, lstart + len - 1ULL, block, block + len - 1ULL); if (lflag) printf(_(" %llu blocks\n"), len); else printf("\n"); (*cur_extent)++; *last_logical = extent->fe_logical + extent->fe_length; } int fiemap_f( int argc, char **argv) { struct fiemap *fiemap; int max_extents = 0; int num_extents = 32; int last = 0; int lflag = 0; int vflag = 0; int fiemap_flags = FIEMAP_FLAG_SYNC; int c; int i; int map_size; int ret; int cur_extent = 0; int foff_w = 16; /* 16 just for a good minimum range */ int boff_w = 16; int tot_w = 5; /* 5 since its just one number */ int flg_w = 5; __u64 blocksize = 512; __u64 last_logical = 0; struct stat st; while ((c = getopt(argc, argv, "aln:v")) != EOF) { switch (c) { case 'a': fiemap_flags |= FIEMAP_FLAG_XATTR; break; case 'l': lflag = 1; break; case 'n': max_extents = atoi(optarg); break; case 'v': vflag++; break; default: return command_usage(&fiemap_cmd); } } if (max_extents) num_extents = min(num_extents, max_extents); map_size = sizeof(struct fiemap) + (num_extents * sizeof(struct fiemap_extent)); fiemap = malloc(map_size); if (!fiemap) { fprintf(stderr, _("%s: malloc of %d bytes failed.\n"), progname, map_size); exitcode = 1; return 0; } printf("%s:\n", file->name); if (vflag) { for (i = 0; i < fiemap->fm_mapped_extents; i++) { char lbuf[32]; char bbuf[32]; __u64 logical; __u64 block; __u64 len; struct fiemap_extent *extent; extent = &fiemap->fm_extents[i]; logical = extent->fe_logical / blocksize; len = extent->fe_length / blocksize; block = extent->fe_physical / blocksize; snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]", logical, logical + len - 1); snprintf(bbuf, sizeof(bbuf), "%llu..%llu", block, block + len - 1); foff_w = max(foff_w, strlen(lbuf)); boff_w = max(boff_w, strlen(bbuf)); tot_w = max(tot_w, numlen(len, 10)); flg_w = max(flg_w, numlen(extent->fe_flags, 16)); if (extent->fe_flags & FIEMAP_EXTENT_LAST) break; } printf("%4s: %-*s %-*s %*s %*s\n", _("EXT"), foff_w, _("FILE-OFFSET"), boff_w, _("BLOCK-RANGE"), tot_w, _("TOTAL"), flg_w, _("FLAGS")); } while (!last && ((cur_extent + 1) != max_extents)) { if (max_extents) num_extents = min(num_extents, max_extents - (cur_extent + 1)); memset(fiemap, 0, map_size); fiemap->fm_flags = fiemap_flags; fiemap->fm_start = last_logical; fiemap->fm_length = -1LL; fiemap->fm_extent_count = num_extents; ret = ioctl(file->fd, FS_IOC_FIEMAP, (unsigned long)fiemap); if (ret < 0) { fprintf(stderr, "%s: ioctl(FS_IOC_FIEMAP) [\"%s\"]: " "%s\n", progname, file->name, strerror(errno)); free(fiemap); exitcode = 1; return 0; } /* No more extents to map, exit */ if (!fiemap->fm_mapped_extents) break; for (i = 0; i < fiemap->fm_mapped_extents; i++) { struct fiemap_extent *extent; extent = &fiemap->fm_extents[i]; if (vflag) print_verbose(extent, blocksize, foff_w, boff_w, tot_w, flg_w, max_extents, &cur_extent, &last_logical); else print_plain(extent, lflag, blocksize, max_extents, &cur_extent, &last_logical); if (extent->fe_flags & FIEMAP_EXTENT_LAST) { last = 1; break; } if ((cur_extent + 1) == max_extents) break; } } if ((cur_extent + 1) == max_extents) goto out; memset(&st, 0, sizeof(st)); if (fstat(file->fd, &st)) { fprintf(stderr, "%s: fstat failed: %s\n", progname, strerror(errno)); free(fiemap); exitcode = 1; return 0; } if (cur_extent && last_logical < st.st_size) { char lbuf[32]; snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", last_logical / blocksize, (st.st_size / blocksize) - 1); if (vflag) { printf("%4d: %-*s %-*s %*llu\n", cur_extent, foff_w, lbuf, boff_w, _("hole"), tot_w, (st.st_size - last_logical) / blocksize); } else { printf("\t%d: %s %s", cur_extent, lbuf, _("hole")); if (lflag) printf(_(" %llu blocks\n"), (st.st_size - last_logical) / blocksize); else printf("\n"); } } out: free(fiemap); return 0; } void fiemap_init(void) { fiemap_cmd.name = "fiemap"; fiemap_cmd.cfunc = fiemap_f; fiemap_cmd.argmin = 0; fiemap_cmd.argmax = -1; fiemap_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fiemap_cmd.args = _("[-alv] [-n nx]"); fiemap_cmd.oneline = _("print block mapping for a file"); fiemap_cmd.help = fiemap_help; add_command(&fiemap_cmd); } xfsprogs-3.1.9ubuntu2/io/fsync.c0000664000000000000000000000321611604735741013523 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "init.h" #include "io.h" static cmdinfo_t fsync_cmd; static cmdinfo_t fdatasync_cmd; static int fsync_f( int argc, char **argv) { if (fsync(file->fd) < 0) { perror("fsync"); return 0; } return 0; } static int fdatasync_f( int argc, char **argv) { if (fdatasync(file->fd) < 0) { perror("fdatasync"); return 0; } return 0; } void fsync_init(void) { fsync_cmd.name = "fsync"; fsync_cmd.altname = "s"; fsync_cmd.cfunc = fsync_f; fsync_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fsync_cmd.oneline = _("calls fsync(2) to flush all in-core file state to disk"); fdatasync_cmd.name = "fdatasync"; fdatasync_cmd.altname = "ds"; fdatasync_cmd.cfunc = fdatasync_f; fdatasync_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fdatasync_cmd.oneline = _("calls fdatasync(2) to flush the files in-core data to disk"); add_command(&fsync_cmd); add_command(&fdatasync_cmd); } xfsprogs-3.1.9ubuntu2/io/inject.c0000664000000000000000000001170711604735741013661 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t inject_cmd; static int error_tag(char *name) { static struct { int tag; char *name; } *e, eflags[] = { #define XFS_ERRTAG_NOERROR 0 { XFS_ERRTAG_NOERROR, "noerror" }, #define XFS_ERRTAG_IFLUSH_1 1 { XFS_ERRTAG_IFLUSH_1, "iflush1" }, #define XFS_ERRTAG_IFLUSH_2 2 { XFS_ERRTAG_IFLUSH_2, "iflush2" }, #define XFS_ERRTAG_IFLUSH_3 3 { XFS_ERRTAG_IFLUSH_3, "iflush3" }, #define XFS_ERRTAG_IFLUSH_4 4 { XFS_ERRTAG_IFLUSH_4, "iflush4" }, #define XFS_ERRTAG_IFLUSH_5 5 { XFS_ERRTAG_IFLUSH_5, "iflush5" }, #define XFS_ERRTAG_IFLUSH_6 6 { XFS_ERRTAG_IFLUSH_6, "iflush6" }, #define XFS_ERRTAG_DA_READ_BUF 7 { XFS_ERRTAG_DA_READ_BUF, "dareadbuf" }, #define XFS_ERRTAG_BTREE_CHECK_LBLOCK 8 { XFS_ERRTAG_BTREE_CHECK_LBLOCK, "btree_chk_lblk" }, #define XFS_ERRTAG_BTREE_CHECK_SBLOCK 9 { XFS_ERRTAG_BTREE_CHECK_SBLOCK, "btree_chk_sblk" }, #define XFS_ERRTAG_ALLOC_READ_AGF 10 { XFS_ERRTAG_ALLOC_READ_AGF, "readagf" }, #define XFS_ERRTAG_IALLOC_READ_AGI 11 { XFS_ERRTAG_IALLOC_READ_AGI, "readagi" }, #define XFS_ERRTAG_ITOBP_INOTOBP 12 { XFS_ERRTAG_ITOBP_INOTOBP, "itobp" }, #define XFS_ERRTAG_IUNLINK 13 { XFS_ERRTAG_IUNLINK, "iunlink" }, #define XFS_ERRTAG_IUNLINK_REMOVE 14 { XFS_ERRTAG_IUNLINK_REMOVE, "iunlinkrm" }, #define XFS_ERRTAG_DIR_INO_VALIDATE 15 { XFS_ERRTAG_DIR_INO_VALIDATE, "dirinovalid" }, #define XFS_ERRTAG_BULKSTAT_READ_CHUNK 16 { XFS_ERRTAG_BULKSTAT_READ_CHUNK, "bulkstat" }, #define XFS_ERRTAG_IODONE_IOERR 17 { XFS_ERRTAG_IODONE_IOERR, "logiodone" }, #define XFS_ERRTAG_STRATREAD_IOERR 18 { XFS_ERRTAG_STRATREAD_IOERR, "stratread" }, #define XFS_ERRTAG_STRATCMPL_IOERR 19 { XFS_ERRTAG_STRATCMPL_IOERR, "stratcmpl" }, #define XFS_ERRTAG_DIOWRITE_IOERR 20 { XFS_ERRTAG_DIOWRITE_IOERR, "diowrite" }, #define XFS_ERRTAG_BMAPIFORMAT 21 { XFS_ERRTAG_BMAPIFORMAT, "bmapifmt" }, #define XFS_ERRTAG_MAX 22 { XFS_ERRTAG_MAX, NULL } }; int count; /* Search for a name */ if (name) { for (e = eflags; e->name; e++) if (strcmp(name, e->name) == 0) return e->tag; return -1; } /* Dump all the names */ fputs("tags: [ ", stdout); for (count = 0, e = eflags; e->name; e++, count++) { if (count) { fputs(", ", stdout); if (!(count % 5)) fputs("\n\t", stdout); } fputs(e->name, stdout); } fputs(" ]\n", stdout); return 0; } static void inject_help(void) { printf(_( "\n" " inject errors into the filesystem of the currently open file\n" "\n" " Example:\n" " 'inject readagf' - cause errors on allocation group freespace reads\n" "\n" " Causes the kernel to generate and react to errors within XFS, provided\n" " the XFS kernel code has been built with debugging features enabled.\n" " With no arguments, displays the list of error injection tags.\n" "\n")); } static int inject_f( int argc, char **argv) { xfs_error_injection_t error; int command = XFS_IOC_ERROR_INJECTION; if (argc == 1) return error_tag(NULL); while (--argc > 0) { error.fd = file->fd; if ((error.errtag = error_tag(argv[argc])) < 0) { fprintf(stderr, _("no such tag -- %s\n"), argv[1]); continue; } if (error.errtag == XFS_ERRTAG_NOERROR) command = XFS_IOC_ERROR_CLEARALL; if ((xfsctl(file->name, file->fd, command, &error)) < 0) { perror("XFS_IOC_ERROR_INJECTION"); continue; } } return 0; } void inject_init(void) { inject_cmd.name = "inject"; inject_cmd.cfunc = inject_f; inject_cmd.argmin = 0; inject_cmd.argmax = -1; inject_cmd.flags = CMD_NOMAP_OK; inject_cmd.args = _("[tag ...]"); inject_cmd.oneline = _("inject errors into a filesystem"); inject_cmd.help = inject_help; if (expert) add_command(&inject_cmd); } xfsprogs-3.1.9ubuntu2/io/fadvise.c0000664000000000000000000000714611604735741014030 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t fadvise_cmd; static void fadvise_help(void) { printf(_( "\n" " advise the page cache about expected I/O patterns on the current file\n" "\n" " Modifies kernel page cache behaviour when operating on the current file.\n" " The range arguments are required by some advise commands ([*] below).\n" " With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" " -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" " -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" " -r -- expect random page references (POSIX_FADV_RANDOM)\n" " -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" " -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" " Notes: these interfaces are not supported in Linux kernels before 2.6.\n" " NORMAL sets the default readahead setting on the file.\n" " RANDOM sets the readahead setting on the file to zero.\n" " SEQUENTIAL sets double the default readahead setting on the file.\n" " WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" "\n")); } static int fadvise_f( int argc, char **argv) { off64_t offset = 0, length = 0; int c, range = 0, advise = POSIX_FADV_NORMAL; while ((c = getopt(argc, argv, "dnrsw")) != EOF) { switch (c) { case 'd': /* Don't need these pages */ advise = POSIX_FADV_DONTNEED; range = 1; break; case 'n': /* Data will be accessed once */ advise = POSIX_FADV_NOREUSE; range = 1; break; case 'r': /* Expect random page references */ advise = POSIX_FADV_RANDOM; range = 0; break; case 's': /* Expect sequential page references */ advise = POSIX_FADV_SEQUENTIAL; range = 0; break; case 'w': /* Will need these pages */ advise = POSIX_FADV_WILLNEED; range = 1; break; default: return command_usage(&fadvise_cmd); } } if (range) { size_t blocksize, sectsize; if (optind != argc - 2) return command_usage(&fadvise_cmd); init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else if (optind != argc) { return command_usage(&fadvise_cmd); } if (posix_fadvise64(file->fd, offset, length, advise) < 0) { perror("fadvise"); return 0; } return 0; } void fadvise_init(void) { fadvise_cmd.name = "fadvise"; fadvise_cmd.cfunc = fadvise_f; fadvise_cmd.argmin = 0; fadvise_cmd.argmax = -1; fadvise_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fadvise_cmd.args = _("[-dnrsw] [off len]"); fadvise_cmd.oneline = _("advisory commands for sections of a file"); fadvise_cmd.help = fadvise_help; add_command(&fadvise_cmd); } xfsprogs-3.1.9ubuntu2/io/freeze.c0000664000000000000000000000367511604735741013672 0ustar /* * Copyright (c) 2001-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t freeze_cmd; static cmdinfo_t thaw_cmd; int freeze_f( int argc, char **argv) { int level = 1; if (xfsctl(file->name, file->fd, XFS_IOC_FREEZE, &level) < 0) { fprintf(stderr, _("%s: cannot freeze filesystem at %s: %s\n"), progname, file->name, strerror(errno)); exitcode = 1; return 0; } return 0; } int thaw_f( int argc, char **argv) { int level = 1; if (xfsctl(file->name, file->fd, XFS_IOC_THAW, &level) < 0) { fprintf(stderr, _("%s: cannot unfreeze filesystem mounted at %s: %s\n"), progname, file->name, strerror(errno)); exitcode = 1; return 0; } return 0; } void freeze_init(void) { freeze_cmd.name = "freeze"; freeze_cmd.cfunc = freeze_f; freeze_cmd.argmin = 0; freeze_cmd.argmax = 0; freeze_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; freeze_cmd.oneline = _("freeze filesystem of current file"); thaw_cmd.name = "thaw"; thaw_cmd.cfunc = thaw_f; thaw_cmd.argmin = 0; thaw_cmd.argmax = 0; thaw_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; thaw_cmd.oneline = _("unfreeze filesystem of current file"); if (expert) { add_command(&freeze_cmd); add_command(&thaw_cmd); } } xfsprogs-3.1.9ubuntu2/io/attr.c0000664000000000000000000002302511604735741013353 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t chattr_cmd; static cmdinfo_t lsattr_cmd; static unsigned int orflags; static unsigned int andflags; unsigned int recurse_all; unsigned int recurse_dir; static struct xflags { uint flag; char *shortname; char *longname; } xflags[] = { { XFS_XFLAG_REALTIME, "r", "realtime" }, { XFS_XFLAG_PREALLOC, "p", "prealloc" }, { XFS_XFLAG_IMMUTABLE, "i", "immutable" }, { XFS_XFLAG_APPEND, "a", "append-only" }, { XFS_XFLAG_SYNC, "s", "sync" }, { XFS_XFLAG_NOATIME, "A", "no-atime" }, { XFS_XFLAG_NODUMP, "d", "no-dump" }, { XFS_XFLAG_RTINHERIT, "t", "rt-inherit" }, { XFS_XFLAG_PROJINHERIT, "P", "proj-inherit" }, { XFS_XFLAG_NOSYMLINKS, "n", "nosymlinks" }, { XFS_XFLAG_EXTSIZE, "e", "extsize" }, { XFS_XFLAG_EXTSZINHERIT, "E", "extsz-inherit" }, { XFS_XFLAG_NODEFRAG, "f", "no-defrag" }, { XFS_XFLAG_FILESTREAM, "S", "filestream" }, { 0, NULL, NULL } }; #define CHATTR_XFLAG_LIST "r"/*p*/"iasAdtPneEfS" static void lsattr_help(void) { printf(_( "\n" " displays the set of extended inode flags associated with the current file\n" "\n" " Each individual flag is displayed as a single character, in this order:\n" " r -- file data is stored in the realtime section\n" " p -- file has preallocated extents (cannot be changed using chattr)\n" " i -- immutable, file cannot be modified\n" " a -- append-only, file can only be appended to\n" " s -- all updates are synchronous\n" " A -- the access time is not updated for this inode\n" " d -- do not include this file in a dump of the filesystem\n" " t -- child created in this directory has realtime bit set by default\n" " P -- child created in this directory has parents project ID by default\n" " n -- symbolic links cannot be created in this directory\n" " e -- for non-realtime files, observe the inode extent size value\n" " E -- children created in this directory inherit the extent size value\n" " f -- do not include this file when defragmenting the filesystem\n" " S -- enable filestreams allocator for this directory\n" "\n" " Options:\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, but only list attributes on directories\n" " -a -- show all flags which can be set alongside those which are set\n" " -v -- verbose mode; show long names of flags, not single characters\n" "\n")); } static void chattr_help(void) { printf(_( "\n" " modifies the set of extended inode flags associated with the current file\n" "\n" " Examples:\n" " 'chattr +a' - sets the append-only flag\n" " 'chattr -a' - clears the append-only flag\n" "\n" " -R -- recursively descend (useful when current file is a directory)\n" " -D -- recursively descend, only modifying attributes on directories\n" " +/-r -- set/clear the realtime flag\n" " +/-i -- set/clear the immutable flag\n" " +/-a -- set/clear the append-only flag\n" " +/-s -- set/clear the sync flag\n" " +/-A -- set/clear the no-atime flag\n" " +/-d -- set/clear the no-dump flag\n" " +/-t -- set/clear the realtime inheritance flag\n" " +/-P -- set/clear the project ID inheritance flag\n" " +/-n -- set/clear the no-symbolic-links flag\n" " +/-e -- set/clear the extent-size flag\n" " +/-E -- set/clear the extent-size inheritance flag\n" " +/-f -- set/clear the no-defrag flag\n" " +/-S -- set/clear the filestreams allocator flag\n" " Note1: user must have certain capabilities to modify immutable/append-only.\n" " Note2: immutable/append-only files cannot be deleted; removing these files\n" " requires the immutable/append-only flag to be cleared first.\n" " Note3: the realtime flag can only be set if the filesystem has a realtime\n" " section, and the (regular) file must be empty when the flag is set.\n" "\n")); } void printxattr( uint flags, int verbose, int dofname, const char *fname, int dobraces, int doeol) { struct xflags *p; int first = 1; if (dobraces) fputs("[", stdout); for (p = xflags; p->flag; p++) { if (flags & p->flag) { if (verbose) { if (first) first = 0; else fputs(", ", stdout); fputs(p->longname, stdout); } else { fputs(p->shortname, stdout); } } else if (!verbose) { fputs("-", stdout); } } if (dobraces) fputs("]", stdout); if (dofname) printf(" %s ", fname); if (doeol) fputs("\n", stdout); } static int lsattr_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { struct fsxattr fsx; int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); else if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, path, strerror(errno)); else printxattr(fsx.fsx_xflags, 0, 1, path, 0, 1); if (fd != -1) close(fd); return 0; } static int lsattr_f( int argc, char **argv) { struct fsxattr fsx; char *name = file->name; int c, aflag = 0, vflag = 0; recurse_all = recurse_dir = 0; while ((c = getopt(argc, argv, "DRav")) != EOF) { switch (c) { case 'D': recurse_all = 0; recurse_dir = 1; break; case 'R': recurse_all = 1; recurse_dir = 0; break; case 'a': aflag = 1; vflag = 0; break; case 'v': aflag = 0; vflag = 1; break; default: return command_usage(&lsattr_cmd); } } if (recurse_all || recurse_dir) { nftw(name, lsattr_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); } else if ((xfsctl(name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, name, strerror(errno)); } else { printxattr(fsx.fsx_xflags, vflag, !aflag, name, vflag, !aflag); if (aflag) { fputs("/", stdout); printxattr(-1, 0, 1, name, 0, 1); } } return 0; } static int chattr_callback( const char *path, const struct stat *stat, int status, struct FTW *data) { struct fsxattr attr; int fd; if (recurse_dir && !S_ISDIR(stat->st_mode)) return 0; if ((fd = open(path, O_RDONLY)) == -1) { fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) { fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, path, strerror(errno)); } else { attr.fsx_xflags |= orflags; attr.fsx_xflags &= ~andflags; if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) fprintf(stderr, _("%s: cannot set flags on %s: %s\n"), progname, path, strerror(errno)); } if (fd != -1) close(fd); return 0; } static int chattr_f( int argc, char **argv) { struct fsxattr attr; struct xflags *p; unsigned int i = 0; char *c, *name = file->name; orflags = andflags = 0; recurse_all = recurse_dir = 0; while (++i < argc) { if (argv[i][0] == '-' && argv[i][1] == 'R') { recurse_all = 1; } else if (argv[i][0] == '-' && argv[i][1] == 'D') { recurse_dir = 1; } else if (argv[i][0] == '+') { for (c = &argv[i][1]; *c; c++) { for (p = xflags; p->flag; p++) { if (strncmp(p->shortname, c, 1) == 0) { orflags |= p->flag; break; } } if (!p->flag) { fprintf(stderr, _("%s: unknown flag\n"), progname); return 0; } } } else if (argv[i][0] == '-') { for (c = &argv[i][1]; *c; c++) { for (p = xflags; p->flag; p++) { if (strncmp(p->shortname, c, 1) == 0) { andflags |= p->flag; break; } } if (!p->flag) { fprintf(stderr, _("%s: unknown flag\n"), progname); return 0; } } } else { fprintf(stderr, _("%s: bad chattr command, not +/-X\n"), progname); return 0; } } if (recurse_all || recurse_dir) { nftw(name, chattr_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); } else if (xfsctl(name, file->fd, XFS_IOC_FSGETXATTR, &attr) < 0) { fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, name, strerror(errno)); } else { attr.fsx_xflags |= orflags; attr.fsx_xflags &= ~andflags; if (xfsctl(name, file->fd, XFS_IOC_FSSETXATTR, &attr) < 0) fprintf(stderr, _("%s: cannot set flags on %s: %s\n"), progname, name, strerror(errno)); } return 0; } void attr_init(void) { chattr_cmd.name = "chattr"; chattr_cmd.cfunc = chattr_f; chattr_cmd.args = _("[-R|-D] [+/-"CHATTR_XFLAG_LIST"]"); chattr_cmd.argmin = 1; chattr_cmd.argmax = -1; chattr_cmd.flags = CMD_NOMAP_OK; chattr_cmd.oneline = _("change extended inode flags on the currently open file"); chattr_cmd.help = chattr_help; lsattr_cmd.name = "lsattr"; lsattr_cmd.cfunc = lsattr_f; lsattr_cmd.args = _("[-R|-D|-a|-v]"); lsattr_cmd.argmin = 0; lsattr_cmd.argmax = 1; lsattr_cmd.flags = CMD_NOMAP_OK; lsattr_cmd.oneline = _("list extended inode flags set on the currently open file"); lsattr_cmd.help = lsattr_help; add_command(&chattr_cmd); add_command(&lsattr_cmd); } xfsprogs-3.1.9ubuntu2/io/getrusage.c0000664000000000000000000000700611604735741014370 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "init.h" static cmdinfo_t getrusage_cmd; /* * Report process resource utilisation. Formatting options: * "Shell" format: 0.000u 0.000s 0:00.00 0.0% 0+0k 0+0io 0pf+0w * Verbose format: * 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k * 0inputs+0outputs (0major+0minor)pagefaults 0swaps * Comma Separated Value format: 0.000,0.000,00:00:00.00,0.0,0,0,0,0,0,0 */ static int getrusage_f( int argc, char **argv) { struct timeval wallclk, timenow; struct rusage rusage; double usrtime, systime, elapsed, pct_cpu; char ts[64]; int Cflag, vflag; int c; Cflag = vflag = 0; while ((c = getopt(argc, argv, "Cv")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'v': vflag = 1; break; default: return command_usage(&getrusage_cmd); } } if (optind != argc) return command_usage(&getrusage_cmd); if (getrusage(RUSAGE_SELF, &rusage) < 0) { perror("getrusage"); return 0; } gettimeofday(&timenow, NULL); wallclk = tsub(timenow, stopwatch); elapsed = (double)wallclk.tv_sec + ((double)wallclk.tv_usec / 1000000.0); usrtime = (double)rusage.ru_utime.tv_sec + ((double)rusage.ru_utime.tv_usec / 1000000.0); systime = (double)rusage.ru_stime.tv_sec + ((double)rusage.ru_stime.tv_usec / 1000000.0); if (elapsed < usrtime + systime) pct_cpu = 100.0; else pct_cpu = ((usrtime + systime) / elapsed) * 100; c = Cflag ? VERBOSE_FIXED_TIME : TERSE_FIXED_TIME; timestr(&wallclk, ts, sizeof(ts), c); if (Cflag) printf("%.3f,%.3f,%s,%.1f,%ld,%ld,%ld,%ld,%ld,%ld,%ld\n", usrtime, systime, ts, pct_cpu, rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap, rusage.ru_inblock, rusage.ru_oublock, rusage.ru_nvcsw, rusage.ru_nivcsw); else if (vflag) printf("%.2fuser %.2fsystem %selapsed %.0f%%CPU " "(%ldavgtext+%ldavgdata %ldmaxresident)k\n" "%ldinputs+%ldoutputs " "(%ldmajor+%ldminor)pagefaults %ldswaps\n", usrtime, systime, ts, pct_cpu, rusage.ru_ixrss, rusage.ru_idrss, rusage.ru_maxrss, rusage.ru_inblock, rusage.ru_oublock, rusage.ru_majflt, rusage.ru_minflt, rusage.ru_nswap); else printf("%.3fu %.3fs %s %.1f%%\t" "%ld+%ldk %ld+%ldio %ldpf+%ldw\n", usrtime, systime, ts, pct_cpu, rusage.ru_maxrss, rusage.ru_ixrss, rusage.ru_inblock, rusage.ru_oublock, rusage.ru_majflt, rusage.ru_nswap); return 0; } void getrusage_init(void) { getrusage_cmd.name = "getrusage"; getrusage_cmd.altname = "g"; getrusage_cmd.argmin = 0; getrusage_cmd.argmax = -1; getrusage_cmd.cfunc = getrusage_f; getrusage_cmd.flags = CMD_NOFILE_OK | CMD_NOMAP_OK | CMD_FOREIGN_OK; getrusage_cmd.oneline = _("report process resource usage"); if (expert) add_command(&getrusage_cmd); } xfsprogs-3.1.9ubuntu2/io/sendfile.c0000664000000000000000000001076311604735741014177 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t sendfile_cmd; static void sendfile_help(void) { printf(_( "\n" " transfer a range of bytes from the given offset between files\n" "\n" " Example:\n" " 'send -f 2 512 20' - writes 20 bytes at 512 bytes into the open file\n" "\n" " Copies data between one file descriptor and another. Because this copying\n" " is done within the kernel, sendfile does not need to transfer data to and\n" " from user space.\n" " -f -- specifies an input file from which to source data to write\n" " -i -- specifies an input file name from which to source data to write.\n" " An offset and length in the source file can be optionally specified.\n" "\n")); } static int send_buffer( off64_t offset, size_t count, int fd, long long *total) { off64_t off = offset; ssize_t bytes, bytes_remaining = count; int ops = 0; *total = 0; while (count > 0) { bytes = sendfile64(file->fd, fd, &off, bytes_remaining); if (bytes == 0) break; if (bytes < 0) { perror("sendfile64"); return -1; } ops++; *total += bytes; if (bytes >= bytes_remaining) break; bytes_remaining -= bytes; } return ops; } static int sendfile_f( int argc, char **argv) { off64_t offset = 0; long long count, total; size_t blocksize, sectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *infile = NULL; int Cflag, qflag; int c, fd = -1; Cflag = qflag = 0; init_cvtnum(&blocksize, §size); while ((c = getopt(argc, argv, "Cf:i:q")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'q': qflag = 1; break; case 'f': fd = atoi(argv[1]); if (fd < 0 || fd >= filecount) { printf(_("value %d is out of range (0-%d)\n"), fd, filecount-1); return 0; } break; case 'i': infile = optarg; break; default: return command_usage(&sendfile_cmd); } } if (infile && fd != -1) return command_usage(&sendfile_cmd); if (!infile) fd = filetable[fd].fd; else if ((fd = openfile(infile, NULL, IO_READONLY, 0)) < 0) return 0; if (optind == argc - 2) { offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); goto done; } optind++; count = cvtnum(blocksize, sectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); goto done; } } else { struct stat64 stat; if (fstat64(fd, &stat) < 0) { perror("fstat64"); goto done; } count = stat.st_size; } gettimeofday(&t1, NULL); c = send_buffer(offset, count, fd, &total); if (c < 0) goto done; if (qflag) goto done; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("sent %lld/%lld bytes from offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } done: if (infile) close(fd); return 0; } void sendfile_init(void) { sendfile_cmd.name = "sendfile"; sendfile_cmd.altname = "send"; sendfile_cmd.cfunc = sendfile_f; sendfile_cmd.argmin = 2; sendfile_cmd.argmax = -1; sendfile_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; sendfile_cmd.args = _("-i infile | -f N [off len]"); sendfile_cmd.oneline = _("Transfer data directly between file descriptors"); sendfile_cmd.help = sendfile_help; add_command(&sendfile_cmd); } xfsprogs-3.1.9ubuntu2/io/xfs_freeze.sh0000664000000000000000000000137011146407622014723 0ustar #!/bin/sh -f # # Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. # OPTS="" USAGE="Usage: xfs_freeze -f | -u " DIRNAME=`dirname $0` VERSION=false FREEZE=false THAW=false while getopts "fuV" c do case $c in f) FREEZE=true;; u) THAW=true;; V) VERSION=true;; \?) echo $USAGE 1>&2 exit 2 ;; esac done if $VERSION ; then $DIRNAME/xfs_io -p xfs_freeze -V exit 0 fi shift `expr $OPTIND - 1` if [ "$1" = "" ]; then echo $USAGE 1>&2 exit 2 fi if $FREEZE ; then $DIRNAME/xfs_io -F -r -p xfs_freeze -x -c "freeze" "$1" status=$? [ $status -ne 0 ] && exit $status elif $THAW ; then $DIRNAME/xfs_io -F -r -p xfs_freeze -x -c "thaw" "$1" status=$? [ $status -ne 0 ] && exit $status else echo $USAGE 1>&2 exit 2 fi exit 0 xfsprogs-3.1.9ubuntu2/io/bmap.c0000664000000000000000000003064311604735741013324 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "init.h" #include "io.h" static cmdinfo_t bmap_cmd; static void bmap_help(void) { printf(_( "\n" " prints the block mapping for an XFS file's data or attribute forks" "\n" " Example:\n" " 'bmap -vp' - tabular format verbose map, including unwritten extents\n" "\n" " bmap prints the map of disk blocks used by the current file.\n" " The map lists each extent used by the file, as well as regions in the\n" " file that do not have any corresponding blocks (holes).\n" " By default, each line of the listing takes the following form:\n" " extent: [startoffset..endoffset]: startblock..endblock\n" " Holes are marked by replacing the startblock..endblock with 'hole'.\n" " All the file offsets and disk blocks are in units of 512-byte blocks.\n" " -a -- prints the attribute fork map instead of the data fork.\n" " -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" " -l -- also displays the length of each extent in 512-byte blocks.\n" " -n -- query n extents.\n" " -p -- obtain all unwritten extents as well (w/ -v show which are unwritten.)\n" " -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" " Note: the bmap for non-regular files can be obtained provided the file\n" " was opened appropriately (in particular, must be opened read-only).\n" "\n")); } static int numlen( off64_t val) { off64_t tmp; int len; for (len = 0, tmp = val; tmp > 0; tmp = tmp/10) len++; return (len == 0 ? 1 : len); } int bmap_f( int argc, char **argv) { struct fsxattr fsx; struct getbmapx *map; struct xfs_fsop_geom fsgeo; int map_size; int loop = 0; int flg = 0; int aflag = 0; int lflag = 0; int nflag = 0; int pflag = 0; int vflag = 0; int is_rt = 0; int bmv_iflags = 0; /* flags for XFS_IOC_GETBMAPX */ int i = 0; int c; int egcnt; while ((c = getopt(argc, argv, "adln:pv")) != EOF) { switch (c) { case 'a': /* Attribute fork. */ bmv_iflags |= BMV_IF_ATTRFORK; aflag = 1; break; case 'l': /* list number of blocks with each extent */ lflag = 1; break; case 'n': /* number of extents specified */ nflag = atoi(optarg); break; case 'd': /* do not recall possibly offline DMAPI files */ bmv_iflags |= BMV_IF_NO_DMAPI_READ; break; case 'p': /* report unwritten preallocated blocks */ pflag = 1; bmv_iflags |= BMV_IF_PREALLOC; break; case 'v': /* Verbose output */ vflag++; break; default: return command_usage(&bmap_cmd); } } if (aflag) bmv_iflags &= ~(BMV_IF_PREALLOC|BMV_IF_NO_DMAPI_READ); if (vflag) { c = xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo); if (c < 0) { fprintf(stderr, _("%s: can't get geometry [\"%s\"]: %s\n"), progname, file->name, strerror(errno)); exitcode = 1; return 0; } c = xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx); if (c < 0) { fprintf(stderr, _("%s: cannot read attrs on \"%s\": %s\n"), progname, file->name, strerror(errno)); exitcode = 1; return 0; } if (fsx.fsx_xflags == XFS_XFLAG_REALTIME) { /* * ag info not applicable to rt, continue * without ag output. */ is_rt = 1; } } map_size = nflag ? nflag+2 : 32; /* initial guess - 32 */ map = malloc(map_size*sizeof(*map)); if (map == NULL) { fprintf(stderr, _("%s: malloc of %d bytes failed.\n"), progname, (int)(map_size * sizeof(*map))); exitcode = 1; return 0; } /* Try the xfsctl(XFS_IOC_GETBMAPX) for the number of extents specified * by nflag, or the initial guess number of extents (32). * * If there are more extents than we guessed, use xfsctl * (XFS_IOC_FSGETXATTR[A]) to get the extent count, realloc some more * space based on this count, and try again. * * If the initial FGETBMAPX attempt returns EINVAL, this may mean * that we tried the FGETBMAPX on a zero length file. If we get * EINVAL, check the length with fstat() and return "no extents" * if the length == 0. * * Why not do the xfsctl(XFS_IOC_FSGETXATTR[A]) first? Two reasons: * (1) The extent count may be wrong for a file with delayed * allocation blocks. The XFS_IOC_GETBMAPX forces the real * allocation and fixes up the extent count. * (2) For XFS_IOC_GETBMAP[X] on a DMAPI file that has been moved * offline by a DMAPI application (e.g., DMF) the * XFS_IOC_FSGETXATTR only reflects the extents actually online. * Doing XFS_IOC_GETBMAPX call first forces that data blocks online * and then everything proceeds normally (see PV #545725). * * If you don't want this behavior on a DMAPI offline file, * try the "-d" option which sets the BMV_IF_NO_DMAPI_READ * iflag for XFS_IOC_GETBMAPX. */ do { /* loop a miximum of two times */ memset(map, 0, sizeof(*map)); /* zero header */ map->bmv_length = -1; map->bmv_count = map_size; map->bmv_iflags = bmv_iflags; i = xfsctl(file->name, file->fd, XFS_IOC_GETBMAPX, map); if (i < 0) { if ( errno == EINVAL && !aflag && filesize() == 0) { break; } else { fprintf(stderr, _("%s: xfsctl(XFS_IOC_GETBMAPX)" " iflags=0x%x [\"%s\"]: %s\n"), progname, map->bmv_iflags, file->name, strerror(errno)); free(map); exitcode = 1; return 0; } } if (nflag) break; if (map->bmv_entries < map->bmv_count-1) break; /* Get number of extents from xfsctl XFS_IOC_FSGETXATTR[A] * syscall. */ i = xfsctl(file->name, file->fd, aflag ? XFS_IOC_FSGETXATTRA : XFS_IOC_FSGETXATTR, &fsx); if (i < 0) { fprintf(stderr, "%s: xfsctl(XFS_IOC_FSGETXATTR%s) " "[\"%s\"]: %s\n", progname, aflag ? "A" : "", file->name, strerror(errno)); free(map); exitcode = 1; return 0; } if (2 * fsx.fsx_nextents > map_size) { map_size = 2 * fsx.fsx_nextents + 1; map = realloc(map, map_size*sizeof(*map)); if (map == NULL) { fprintf(stderr, _("%s: cannot realloc %d bytes\n"), progname, (int)(map_size*sizeof(*map))); exitcode = 1; return 0; } } } while (++loop < 2); if (!nflag) { if (map->bmv_entries <= 0) { printf(_("%s: no extents\n"), file->name); free(map); return 0; } } egcnt = nflag ? min(nflag, map->bmv_entries) : map->bmv_entries; printf("%s:\n", file->name); if (!vflag) { for (i = 0; i < egcnt; i++) { printf("\t%d: [%lld..%lld]: ", i, (long long) map[i + 1].bmv_offset, (long long)(map[i + 1].bmv_offset + map[i + 1].bmv_length - 1LL)); if (map[i + 1].bmv_block == -1) printf(_("hole")); else { printf("%lld..%lld", (long long) map[i + 1].bmv_block, (long long)(map[i + 1].bmv_block + map[i + 1].bmv_length - 1LL)); } if (lflag) printf(_(" %lld blocks\n"), (long long)map[i+1].bmv_length); else printf("\n"); } } else { /* * Verbose mode displays: * extent: [startoffset..endoffset]: startblock..endblock \ * ag# (agoffset..agendoffset) totalbbs */ #define MINRANGE_WIDTH 16 #define MINAG_WIDTH 2 #define MINTOT_WIDTH 5 #define NFLG 5 /* count of flags */ #define FLG_NULL 000000 /* Null flag */ #define FLG_PRE 010000 /* Unwritten extent */ #define FLG_BSU 001000 /* Not on begin of stripe unit */ #define FLG_ESU 000100 /* Not on end of stripe unit */ #define FLG_BSW 000010 /* Not on begin of stripe width */ #define FLG_ESW 000001 /* Not on end of stripe width */ int agno; off64_t agoff, bbperag; int foff_w, boff_w, aoff_w, tot_w, agno_w; char rbuf[32], bbuf[32], abuf[32]; int sunit, swidth; foff_w = boff_w = aoff_w = MINRANGE_WIDTH; tot_w = MINTOT_WIDTH; if (is_rt) sunit = swidth = bbperag = 0; else { bbperag = (off64_t)fsgeo.agblocks * (off64_t)fsgeo.blocksize / BBSIZE; sunit = (fsgeo.sunit * fsgeo.blocksize) / BBSIZE; swidth = (fsgeo.swidth * fsgeo.blocksize) / BBSIZE; } flg = sunit | pflag; /* * Go through the extents and figure out the width * needed for all columns. */ for (i = 0; i < egcnt; i++) { snprintf(rbuf, sizeof(rbuf), "[%lld..%lld]:", (long long) map[i + 1].bmv_offset, (long long)(map[i + 1].bmv_offset + map[i + 1].bmv_length - 1LL)); if (map[i + 1].bmv_oflags & BMV_OF_PREALLOC) flg = 1; if (map[i + 1].bmv_block == -1) { foff_w = max(foff_w, strlen(rbuf)); tot_w = max(tot_w, numlen(map[i+1].bmv_length)); } else { snprintf(bbuf, sizeof(bbuf), "%lld..%lld", (long long) map[i + 1].bmv_block, (long long)(map[i + 1].bmv_block + map[i + 1].bmv_length - 1LL)); boff_w = max(boff_w, strlen(bbuf)); if (!is_rt) { agno = map[i + 1].bmv_block / bbperag; agoff = map[i + 1].bmv_block - (agno * bbperag); snprintf(abuf, sizeof(abuf), "(%lld..%lld)", (long long)agoff, (long long)(agoff + map[i + 1].bmv_length - 1LL)); aoff_w = max(aoff_w, strlen(abuf)); } else aoff_w = 0; foff_w = max(foff_w, strlen(rbuf)); tot_w = max(tot_w, numlen(map[i+1].bmv_length)); } } agno_w = is_rt ? 0 : max(MINAG_WIDTH, numlen(fsgeo.agcount)); printf("%4s: %-*s %-*s %*s %-*s %*s%s\n", _("EXT"), foff_w, _("FILE-OFFSET"), boff_w, is_rt ? _("RT-BLOCK-RANGE") : _("BLOCK-RANGE"), agno_w, is_rt ? "" : _("AG"), aoff_w, is_rt ? "" : _("AG-OFFSET"), tot_w, _("TOTAL"), flg ? _(" FLAGS") : ""); for (i = 0; i < egcnt; i++) { flg = FLG_NULL; if (map[i + 1].bmv_oflags & BMV_OF_PREALLOC) { flg |= FLG_PRE; } /* * If striping enabled, determine if extent starts/ends * on a stripe unit boundary. */ if (sunit) { if (map[i + 1].bmv_block % sunit != 0) { flg |= FLG_BSU; } if (((map[i + 1].bmv_block + map[i + 1].bmv_length ) % sunit ) != 0) { flg |= FLG_ESU; } if (map[i + 1].bmv_block % swidth != 0) { flg |= FLG_BSW; } if (((map[i + 1].bmv_block + map[i + 1].bmv_length ) % swidth ) != 0) { flg |= FLG_ESW; } } snprintf(rbuf, sizeof(rbuf), "[%lld..%lld]:", (long long) map[i + 1].bmv_offset, (long long)(map[i + 1].bmv_offset + map[i + 1].bmv_length - 1LL)); if (map[i + 1].bmv_block == -1) { printf("%4d: %-*s %-*s %*s %-*s %*lld\n", i, foff_w, rbuf, boff_w, _("hole"), agno_w, "", aoff_w, "", tot_w, (long long)map[i+1].bmv_length); } else { snprintf(bbuf, sizeof(bbuf), "%lld..%lld", (long long) map[i + 1].bmv_block, (long long)(map[i + 1].bmv_block + map[i + 1].bmv_length - 1LL)); printf("%4d: %-*s %-*s", i, foff_w, rbuf, boff_w, bbuf); if (!is_rt) { agno = map[i + 1].bmv_block / bbperag; agoff = map[i + 1].bmv_block - (agno * bbperag); snprintf(abuf, sizeof(abuf), "(%lld..%lld)", (long long)agoff, (long long)(agoff + map[i + 1].bmv_length - 1LL)); printf(" %*d %-*s", agno_w, agno, aoff_w, abuf); } else printf(" "); printf(" %*lld", tot_w, (long long)map[i+1].bmv_length); if (flg == FLG_NULL && !pflag) { printf("\n"); } else { printf(" %-*.*o\n", NFLG, NFLG, flg); } } } if ((flg || pflag) && vflag > 1) { printf(_(" FLAG Values:\n")); printf(_(" %*.*o Unwritten preallocated extent\n"), NFLG+1, NFLG+1, FLG_PRE); printf(_(" %*.*o Doesn't begin on stripe unit\n"), NFLG+1, NFLG+1, FLG_BSU); printf(_(" %*.*o Doesn't end on stripe unit\n"), NFLG+1, NFLG+1, FLG_ESU); printf(_(" %*.*o Doesn't begin on stripe width\n"), NFLG+1, NFLG+1, FLG_BSW); printf(_(" %*.*o Doesn't end on stripe width\n"), NFLG+1, NFLG+1, FLG_ESW); } } free(map); return 0; } void bmap_init(void) { bmap_cmd.name = "bmap"; bmap_cmd.cfunc = bmap_f; bmap_cmd.argmin = 0; bmap_cmd.argmax = -1; bmap_cmd.flags = CMD_NOMAP_OK; bmap_cmd.args = _("[-adlpv] [-n nx]"); bmap_cmd.oneline = _("print block mapping for an XFS file"); bmap_cmd.help = bmap_help; add_command(&bmap_cmd); } xfsprogs-3.1.9ubuntu2/io/file.c0000664000000000000000000000513211604735741013317 0ustar /* * Copyright (c) 2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "io.h" static cmdinfo_t file_cmd; static cmdinfo_t print_cmd; fileio_t *filetable; int filecount; fileio_t *file; static void print_fileio( fileio_t *file, int index, int braces) { printf(_("%c%03d%c %-14s (%s,%s,%s,%s%s%s%s)\n"), braces? '[' : ' ', index, braces? ']' : ' ', file->name, file->flags & IO_FOREIGN ? _("foreign") : _("xfs"), file->flags & IO_OSYNC ? _("sync") : _("non-sync"), file->flags & IO_DIRECT ? _("direct") : _("non-direct"), file->flags & IO_READONLY ? _("read-only") : _("read-write"), file->flags & IO_REALTIME ? _(",real-time") : "", file->flags & IO_APPEND ? _(",append-only") : "", file->flags & IO_NONBLOCK ? _(",non-block") : ""); } int filelist_f(void) { int i; for (i = 0; i < filecount; i++) print_fileio(&filetable[i], i, &filetable[i] == file); return 0; } static int print_f( int argc, char **argv) { filelist_f(); maplist_f(); return 0; } static int file_f( int argc, char **argv) { int i; if (argc <= 1) return filelist_f(); i = atoi(argv[1]); if (i < 0 || i >= filecount) { printf(_("value %d is out of range (0-%d)\n"), i, filecount-1); } else { file = &filetable[i]; filelist_f(); } return 0; } void file_init(void) { file_cmd.name = "file"; file_cmd.altname = "f"; file_cmd.args = _("[N]"); file_cmd.cfunc = file_f; file_cmd.argmin = 0; file_cmd.argmax = 1; file_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; file_cmd.oneline = _("set the current file"); print_cmd.name = "print"; print_cmd.altname = "p"; print_cmd.cfunc = print_f; print_cmd.argmin = 0; print_cmd.argmax = 0; print_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK | CMD_FLAG_GLOBAL; print_cmd.oneline = _("list current open files and memory mappings"); add_command(&file_cmd); add_command(&print_cmd); } xfsprogs-3.1.9ubuntu2/io/init.h0000664000000000000000000000225211140033220013322 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define CMD_NOFILE_OK (1<<0) /* command doesn't need an open file */ #define CMD_NOMAP_OK (1<<1) /* command doesn't need a mapped region */ #define CMD_FOREIGN_OK (1<<2) /* command not restricted to XFS files */ extern char *progname; extern int exitcode; extern int expert; extern size_t pagesize; extern struct timeval stopwatch; #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) extern void init_cvtnum(size_t *blocksize, size_t *sectsize); xfsprogs-3.1.9ubuntu2/io/xfs_bmap.sh0000775000000000000000000000117611140033220014350 0ustar #!/bin/sh -f # # Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. # OPTS="" VERSION=false USAGE="Usage: xfs_bmap [-adlpvV] [-n nx] file..." DIRNAME=`dirname $0` while getopts "adln:pvV" c do case $c in a) OPTS=$OPTS" -a";; d) OPTS=$OPTS" -d";; l) OPTS=$OPTS" -l";; n) OPTS=$OPTS" -n "$OPTARG;; p) OPTS=$OPTS" -p";; v) OPTS=$OPTS" -v";; V) VERSION=true;; \?) echo $USAGE 1>&2 exit 2 ;; esac done $VERSION && $DIRNAME/xfs_io -p xfs_bmap -V shift `expr $OPTIND - 1` while [ "$1" != "" ] do $DIRNAME/xfs_io -r -p xfs_bmap -c "bmap $OPTS" "$1" status=$? [ $status -ne 0 ] && exit $status shift done exit 0 xfsprogs-3.1.9ubuntu2/io/prealloc.c0000664000000000000000000001410111604735741014175 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if defined(HAVE_FALLOCATE) #include #endif #include #include #include #include "init.h" #include "io.h" #ifndef FALLOC_FL_PUNCH_HOLE #define FALLOC_FL_PUNCH_HOLE 0x02 #endif static cmdinfo_t allocsp_cmd; static cmdinfo_t freesp_cmd; static cmdinfo_t resvsp_cmd; static cmdinfo_t unresvsp_cmd; static cmdinfo_t zero_cmd; #if defined(HAVE_FALLOCATE) static cmdinfo_t falloc_cmd; static cmdinfo_t fpunch_cmd; #endif static int offset_length( char *offset, char *length, xfs_flock64_t *segment) { size_t blocksize, sectsize; init_cvtnum(&blocksize, §size); memset(segment, 0, sizeof(*segment)); segment->l_whence = SEEK_SET; segment->l_start = cvtnum(blocksize, sectsize, offset); if (segment->l_start < 0) { printf(_("non-numeric offset argument -- %s\n"), offset); return 0; } segment->l_len = cvtnum(blocksize, sectsize, length); if (segment->l_len < 0) { printf(_("non-numeric length argument -- %s\n"), length); return 0; } return 1; } static int allocsp_f( int argc, char **argv) { xfs_flock64_t segment; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (xfsctl(file->name, file->fd, XFS_IOC_ALLOCSP64, &segment) < 0) { perror("XFS_IOC_ALLOCSP64"); return 0; } return 0; } static int freesp_f( int argc, char **argv) { xfs_flock64_t segment; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (xfsctl(file->name, file->fd, XFS_IOC_FREESP64, &segment) < 0) { perror("XFS_IOC_FREESP64"); return 0; } return 0; } static int resvsp_f( int argc, char **argv) { xfs_flock64_t segment; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (xfsctl(file->name, file->fd, XFS_IOC_RESVSP64, &segment) < 0) { perror("XFS_IOC_RESVSP64"); return 0; } return 0; } static int unresvsp_f( int argc, char **argv) { xfs_flock64_t segment; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (xfsctl(file->name, file->fd, XFS_IOC_UNRESVSP64, &segment) < 0) { perror("XFS_IOC_UNRESVSP64"); return 0; } return 0; } static int zero_f( int argc, char **argv) { xfs_flock64_t segment; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (xfsctl(file->name, file->fd, XFS_IOC_ZERO_RANGE, &segment) < 0) { perror("XFS_IOC_ZERO_RANGE"); return 0; } return 0; } #if defined (HAVE_FALLOCATE) static int fallocate_f( int argc, char **argv) { xfs_flock64_t segment; int mode = 0; int c; while ((c = getopt(argc, argv, "kp")) != EOF) { switch (c) { case 'k': mode = FALLOC_FL_KEEP_SIZE; break; case 'p': mode = FALLOC_FL_PUNCH_HOLE; break; default: command_usage(&falloc_cmd); } } if (optind != argc - 2) return command_usage(&falloc_cmd); if (!offset_length(argv[optind], argv[optind+1], &segment)) return 0; if (fallocate(file->fd, mode, segment.l_start, segment.l_len)) { perror("fallocate"); return 0; } return 0; } static int fpunch_f( int argc, char **argv) { xfs_flock64_t segment; int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; if (!offset_length(argv[1], argv[2], &segment)) return 0; if (fallocate(file->fd, mode, segment.l_start, segment.l_len)) { perror("fallocate"); return 0; } return 0; } #endif /* HAVE_FALLOCATE */ void prealloc_init(void) { allocsp_cmd.name = "allocsp"; allocsp_cmd.cfunc = allocsp_f; allocsp_cmd.argmin = 2; allocsp_cmd.argmax = 2; allocsp_cmd.flags = CMD_NOMAP_OK; allocsp_cmd.args = _("off len"); allocsp_cmd.oneline = _("allocates zeroed space for part of a file"); freesp_cmd.name = "freesp"; freesp_cmd.cfunc = freesp_f; freesp_cmd.argmin = 2; freesp_cmd.argmax = 2; freesp_cmd.flags = CMD_NOMAP_OK; freesp_cmd.args = _("off len"); freesp_cmd.oneline = _("frees space associated with part of a file"); resvsp_cmd.name = "resvsp"; resvsp_cmd.cfunc = resvsp_f; resvsp_cmd.argmin = 2; resvsp_cmd.argmax = 2; resvsp_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; resvsp_cmd.args = _("off len"); resvsp_cmd.oneline = _("reserves space associated with part of a file"); unresvsp_cmd.name = "unresvsp"; unresvsp_cmd.cfunc = unresvsp_f; unresvsp_cmd.argmin = 2; unresvsp_cmd.argmax = 2; unresvsp_cmd.args = _("off len"); unresvsp_cmd.flags = CMD_NOMAP_OK; unresvsp_cmd.oneline = _("frees reserved space associated with part of a file"); zero_cmd.name = "zero"; zero_cmd.cfunc = zero_f; zero_cmd.argmin = 2; zero_cmd.argmax = 2; zero_cmd.flags = CMD_NOMAP_OK; zero_cmd.args = _("off len"); zero_cmd.oneline = _("Converts the given range of a file to allocated zeros"); add_command(&allocsp_cmd); add_command(&freesp_cmd); add_command(&resvsp_cmd); add_command(&unresvsp_cmd); add_command(&zero_cmd); #if defined (HAVE_FALLOCATE) falloc_cmd.name = "falloc"; falloc_cmd.cfunc = fallocate_f; falloc_cmd.argmin = 2; falloc_cmd.argmax = -1; falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; falloc_cmd.args = _("[-k] [-p] off len"); falloc_cmd.oneline = _("allocates space associated with part of a file via fallocate"); add_command(&falloc_cmd); fpunch_cmd.name = "fpunch"; fpunch_cmd.cfunc = fpunch_f; fpunch_cmd.argmin = 2; fpunch_cmd.argmax = 2; fpunch_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; fpunch_cmd.args = _("off len"); fpunch_cmd.oneline = _("de-allocates space assocated with part of a file via fallocate"); add_command(&fpunch_cmd); #endif /* HAVE_FALLOCATE */ } xfsprogs-3.1.9ubuntu2/io/init.c0000664000000000000000000000773312062210562013340 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" char *progname; int exitcode; int expert; size_t pagesize; struct timeval stopwatch; void usage(void) { fprintf(stderr, _("Usage: %s [-adfmrRstx] [-p prog] [-c cmd]... file\n"), progname); exit(1); } void init_cvtnum( size_t *blocksize, size_t *sectsize) { if (!file || (file->flags & IO_FOREIGN)) { *blocksize = 4096; *sectsize = 512; } else { *blocksize = file->geom.blocksize; *sectsize = file->geom.sectsize; } } static void init_commands(void) { attr_init(); bmap_init(); fadvise_init(); file_init(); freeze_init(); fsync_init(); getrusage_init(); help_init(); imap_init(); inject_init(); madvise_init(); mincore_init(); mmap_init(); open_init(); parent_init(); pread_init(); prealloc_init(); fiemap_init(); pwrite_init(); quit_init(); resblks_init(); sendfile_init(); shutdown_init(); truncate_init(); sync_range_init(); } static int init_args_command( int index) { if (index >= filecount) return 0; file = &filetable[index++]; return index; } static int init_check_command( const cmdinfo_t *ct) { if (ct->flags & CMD_FLAG_GLOBAL) return 1; if (!file && !(ct->flags & CMD_NOFILE_OK)) { fprintf(stderr, _("no files are open, try 'help open'\n")); return 0; } if (!mapping && !(ct->flags & CMD_NOMAP_OK)) { fprintf(stderr, _("no mapped regions, try 'help mmap'\n")); return 0; } if (file && !(ct->flags & CMD_FOREIGN_OK) && (file->flags & IO_FOREIGN)) { fprintf(stderr, _("foreign file active, %s command is for XFS filesystems only\n"), ct->name); return 0; } return 1; } void init( int argc, char **argv) { int c, flags = 0; char *sp; mode_t mode = 0600; xfs_fsop_geom_t geometry = { 0 }; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); pagesize = getpagesize(); gettimeofday(&stopwatch, NULL); while ((c = getopt(argc, argv, "ac:dFfmp:nrRstVx")) != EOF) { switch (c) { case 'a': flags |= IO_APPEND; break; case 'c': add_user_command(optarg); break; case 'd': flags |= IO_DIRECT; break; case 'F': /* Ignored / deprecated now, handled automatically */ break; case 'f': flags |= IO_CREAT; break; case 'm': mode = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { fprintf(stderr, _("non-numeric mode -- %s\n"), optarg); exit(1); } break; case 'n': flags |= IO_NONBLOCK; break; case 'p': progname = optarg; break; case 'r': flags |= IO_READONLY; break; case 's': flags |= IO_OSYNC; break; case 't': flags |= IO_TRUNC; break; case 'R': flags |= IO_REALTIME; break; case 'x': expert = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); default: usage(); } } while (optind < argc) { if ((c = openfile(argv[optind], &geometry, flags, mode)) < 0) exit(1); if (!platform_test_xfs_fd(c)) flags |= IO_FOREIGN; if (addfile(argv[optind], c, &geometry, flags) < 0) exit(1); optind++; } init_commands(); add_args_command(init_args_command); add_check_command(init_check_command); } int main( int argc, char **argv) { init(argc, argv); command_loop(); return exitcode; } xfsprogs-3.1.9ubuntu2/io/imap.c0000664000000000000000000000351111604735741013325 0ustar /* * Copyright (c) 2001-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" #include "io.h" static cmdinfo_t imap_cmd; int imap_f(int argc, char **argv) { int count; int nent; int i; __u64 last = 0; xfs_inogrp_t *t; xfs_fsop_bulkreq_t bulkreq; if (argc != 2) nent = 1; else nent = atoi(argv[1]); t = malloc(nent * sizeof(*t)); bulkreq.lastip = &last; bulkreq.icount = nent; bulkreq.ubuffer = (void *)t; bulkreq.ocount = &count; while (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, &bulkreq) == 0) { if (count == 0) return 0; for (i = 0; i < count; i++) { printf(_("ino %10llu count %2d mask %016llx\n"), (unsigned long long)t[i].xi_startino, t[i].xi_alloccount, (unsigned long long)t[i].xi_allocmask); } } perror("xfsctl(XFS_IOC_FSINUMBERS)"); exitcode = 1; return 0; } void imap_init(void) { imap_cmd.name = "imap"; imap_cmd.cfunc = imap_f; imap_cmd.argmin = 0; imap_cmd.argmax = 0; imap_cmd.args = _("[nentries]"); imap_cmd.flags = CMD_NOMAP_OK; imap_cmd.oneline = _("inode map for filesystem of current file"); if (expert) add_command(&imap_cmd); } xfsprogs-3.1.9ubuntu2/quota/0000775000000000000000000000000012062211564012744 5ustar xfsprogs-3.1.9ubuntu2/quota/util.c0000664000000000000000000002410711650373061014074 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "quota.h" #define SECONDS_IN_A_DAY (24 * 60 * 60) #define SECONDS_IN_A_HOUR (60 * 60) #define SECONDS_IN_A_MINUTE (60) char * time_to_string( time_t origin, uint flags) { static char timestamp[32]; time_t now, timer; uint days, hours, minutes, seconds; if (flags & ABSOLUTE_FLAG) { timer = origin; } else { time(&now); timer = MAX(origin - now, 0); } if (timer > 60) /* roundup */ timer += 30; days = timer / SECONDS_IN_A_DAY; if (days) timer %= SECONDS_IN_A_DAY; hours = timer / SECONDS_IN_A_HOUR; if (hours) timer %= SECONDS_IN_A_HOUR; minutes = timer / SECONDS_IN_A_MINUTE; seconds = timer % SECONDS_IN_A_MINUTE; if (flags & LIMIT_FLAG) { snprintf(timestamp, sizeof(timestamp), (flags & HUMAN_FLAG) ? _("[-none-]") : _("[--none--]")); } else if (origin == 0) { snprintf(timestamp, sizeof(timestamp), (flags & HUMAN_FLAG) ? _("[------]") : _("[--------]")); } else if ((hours == 0 && minutes == 0 && seconds == 0) || (!(flags & VERBOSE_FLAG) && days > 0)) { snprintf(timestamp, sizeof(timestamp), "[%u %s]", days, days == 1 ? _("day") : _("days")); } else if (flags & VERBOSE_FLAG) { snprintf(timestamp, sizeof(timestamp), "[%u %s %02u:%02u:%02u]", days, days == 1 ? _("day") : _("days"), hours, minutes, seconds); } else { /* non-verbose, less than a day remaining */ snprintf(timestamp, sizeof(timestamp), (flags & HUMAN_FLAG) ? "%02u:%02u:%02u" : "[%02u:%02u:%02u]", hours, minutes, seconds); } return timestamp; } static int round_snprintf( char *sp, size_t size, const char *fmt_round, const char *fmt_not_round, __uint64_t value, __uint64_t divisor) { double v = (double)value / divisor; value /= divisor; if (v == (double)value) return snprintf(sp, size, fmt_round, (uint)value); else return snprintf(sp, size, fmt_not_round, v); } /* Basic blocks (512) bytes are returned from quotactl */ #define BBS_TO_EXABYTES(bbs) ((__uint64_t)(bbs)>>51) #define BBS_TO_PETABYTES(bbs) ((__uint64_t)(bbs)>>41) #define BBS_TO_TERABYTES(bbs) ((__uint64_t)(bbs)>>31) #define BBS_TO_GIGABYTES(bbs) ((__uint64_t)(bbs)>>21) #define BBS_TO_MEGABYTES(bbs) ((__uint64_t)(bbs)>>11) #define BBS_TO_KILOBYTES(bbs) ((__uint64_t)(bbs)>>1) #define BBEXABYTE ((__uint64_t)1<<51) #define BBPETABYTE ((__uint64_t)1<<41) #define BBTERABYTE ((__uint64_t)1<<31) #define BBGIGABYTE ((__uint64_t)1<<21) #define BBMEGABYTE ((__uint64_t)1<<11) #define BBKILOBYTE ((__uint64_t)1<< 1) char * bbs_to_string( __uint64_t v, char *sp, uint size) { if (v == 0) snprintf(sp, size, "%4u", (uint)v); else if (BBS_TO_EXABYTES(v)) round_snprintf(sp, size, "%3uE", "%3.1fE", v, BBEXABYTE); else if (BBS_TO_PETABYTES(v)) round_snprintf(sp, size, "%3uP", "%3.1fP", v, BBPETABYTE); else if (BBS_TO_TERABYTES(v)) round_snprintf(sp, size, "%3uT", "%3.1fT", v, BBTERABYTE); else if (BBS_TO_GIGABYTES(v)) round_snprintf(sp, size, "%3uG", "%3.1fG", v, BBGIGABYTE); else if (BBS_TO_MEGABYTES(v)) round_snprintf(sp, size, "%3uM", "%3.1fM", v, BBMEGABYTE); else if (BBS_TO_KILOBYTES(v)) round_snprintf(sp, size, "%3uK", "%3.1fK", v, BBKILOBYTE); else snprintf(sp, size, "%4u", (uint)v << BBSHIFT); /* bytes */ return sp; } #define THOUSAND ((__uint64_t)1000) #define MILLION ((__uint64_t)1000*1000) #define BILLION ((__uint64_t)1000*1000*1000) #define TRILLION ((__uint64_t)1000*1000*1000*1000) #define GAZILLION ((__uint64_t)1000*1000*1000*1000*1000) #define RIDICULOUS ((__uint64_t)1000*1000*1000*1000*1000*1000) #define STOPALREADY ((__uint64_t)1000*1000*1000*1000*1000*1000*1000) char * num_to_string( __uint64_t v, char *sp, uint size) { if (v == 0) snprintf(sp, size, "%4u", (uint)v); else if (v > STOPALREADY) round_snprintf(sp, size, "%3us", "%3.1fs", v, STOPALREADY); else if (v > RIDICULOUS) round_snprintf(sp, size, "%3ur", "%3.1fr", v, RIDICULOUS); else if (v > GAZILLION) round_snprintf(sp, size, "%3ug", "%3.1fg", v, GAZILLION); else if (v > TRILLION) round_snprintf(sp, size, "%3ut", "%3.1ft", v, TRILLION); else if (v > BILLION) round_snprintf(sp, size, "%3ub", "%3.1fb", v, BILLION); else if (v > MILLION) round_snprintf(sp, size, "%3um", "%3.1fm", v, MILLION); else if (v > THOUSAND) round_snprintf(sp, size, "%3uk", "%3.1fk", v, THOUSAND); else snprintf(sp, size, "%4u", (uint)v); return sp; } char * pct_to_string( __uint64_t portion, __uint64_t whole, char *buf, uint size) { uint percent; percent = whole ? (uint) (100.0 * portion / whole + 0.5) : 0; if (snprintf(buf, size, "%3u", percent) < 0) return "???"; return buf; } char * form_to_string( uint form) { char *forms[] = { _("Blocks"), _("Inodes"), _("Realtime Blocks") }; if (form & XFS_BLOCK_QUOTA) return forms[0]; if (form & XFS_INODE_QUOTA) return forms[1]; if (form & XFS_RTBLOCK_QUOTA) return forms[2]; return NULL; } char * type_to_string( uint type) { char *types[] = { _("User"), _("Group"), _("Project") }; if (type & XFS_USER_QUOTA) return types[0]; if (type & XFS_GROUP_QUOTA) return types[1]; if (type & XFS_PROJ_QUOTA) return types[2]; return NULL; } /* * Identifier caches - user/group/project names/IDs */ #define NID 4096 #define IDMASK (NID-1) typedef struct { __uint32_t id; char name[NMAX+1]; } idcache_t; static idcache_t uidnc[NID]; static idcache_t gidnc[NID]; static idcache_t pidnc[NID]; static int uentriesleft = NID; static int gentriesleft = NID; static int pentriesleft = NID; static idcache_t * getnextpwent( __uint32_t id, int byid) { struct passwd *pw; static idcache_t idc; /* /etc/passwd */ if ((pw = byid? getpwuid(id) : getpwent()) == NULL) return NULL; idc.id = pw->pw_uid; strncpy(idc.name, pw->pw_name, NMAX); return &idc; } static idcache_t * getnextgrent( __uint32_t id, int byid) { struct group *gr; static idcache_t idc; if ((gr = byid? getgrgid(id) : getgrent()) == NULL) return NULL; idc.id = gr->gr_gid; strncpy(idc.name, gr->gr_name, NMAX); return &idc; } static idcache_t * getnextprent( __uint32_t id, int byid) { fs_project_t *pr; static idcache_t idc; if ((pr = byid? getprprid(id) : getprent()) == NULL) return NULL; idc.id = pr->pr_prid; strncpy(idc.name, pr->pr_name, NMAX); return &idc; } char * uid_to_name( __uint32_t id) { idcache_t *ncp, *idp; /* Check cache for name first */ ncp = &uidnc[id & IDMASK]; if (ncp->id == id && ncp->name[0]) return ncp->name; if (uentriesleft) { /* * Fill this cache while seaching for a name. * This lets us run through the file serially. */ if (uentriesleft == NID) setpwent(); while (((idp = getnextpwent(id, 0)) != NULL) && uentriesleft) { uentriesleft--; ncp = &uidnc[idp->id & IDMASK]; if (ncp->name[0] == '\0' || idp->id == id) memcpy(ncp, idp, sizeof(idcache_t)); if (idp->id == id) return ncp->name; } endpwent(); uentriesleft = 0; ncp = &uidnc[id & IDMASK]; } /* Not cached - do it the slow way & insert into cache */ if ((idp = getnextpwent(id, 1)) == NULL) return NULL; memcpy(ncp, idp, sizeof(idcache_t)); return ncp->name; } char * gid_to_name( __uint32_t id) { idcache_t *ncp, *idp; /* Check cache for name first */ ncp = &gidnc[id & IDMASK]; if (ncp->id == id && ncp->name[0]) return ncp->name; if (gentriesleft) { /* * Fill this cache while seaching for a name. * This lets us run through the file serially. */ if (gentriesleft == NID) setgrent(); while (((idp = getnextgrent(id, 0)) != NULL) && gentriesleft) { gentriesleft--; ncp = &gidnc[idp->id & IDMASK]; if (ncp->name[0] == '\0' || idp->id == id) memcpy(ncp, idp, sizeof(idcache_t)); if (idp->id == id) return ncp->name; } endgrent(); gentriesleft = 0; ncp = &gidnc[id & IDMASK]; } /* Not cached - do it the slow way & insert into cache */ if ((idp = getnextgrent(id, 1)) == NULL) return NULL; memcpy(ncp, idp, sizeof(idcache_t)); return ncp->name; } char * prid_to_name( __uint32_t id) { idcache_t *ncp, *idp; /* Check cache for name first */ ncp = &pidnc[id & IDMASK]; if (ncp->id == id && ncp->name[0]) return ncp->name; if (pentriesleft) { /* * Fill this cache while seaching for a name. * This lets us run through the file serially. */ if (pentriesleft == NID) setprent(); while (((idp = getnextprent(id, 0)) != NULL) && pentriesleft) { pentriesleft--; ncp = &pidnc[idp->id & IDMASK]; if (ncp->name[0] == '\0' || idp->id == id) memcpy(ncp, idp, sizeof(idcache_t)); if (idp->id == id) return ncp->name; } endprent(); pentriesleft = 0; ncp = &pidnc[id & IDMASK]; } /* Not cached - do it the slow way & insert into cache */ if ((idp = getnextprent(id, 1)) == NULL) return NULL; memcpy(ncp, idp, sizeof(idcache_t)); return ncp->name; } /* * Utility routine for opening an output file so that it can * be "securely" written to (i.e. without vulnerability to a * symlink attack). * * Returns NULL on failure, stdout on NULL input. */ FILE * fopen_write_secure( char *fname) { FILE *fp; int fd; if (!fname) return stdout; if ((fd = open(fname, O_CREAT|O_WRONLY|O_EXCL, 0600)) < 0) { exitcode = 1; fprintf(stderr, _("%s: open on %s failed: %s\n"), progname, fname, strerror(errno)); return NULL; } if ((fp = fdopen(fd, "w")) == NULL) { exitcode = 1; fprintf(stderr, _("%s: fdopen on %s failed: %s\n"), progname, fname, strerror(errno)); close(fd); return NULL; } return fp; } xfsprogs-3.1.9ubuntu2/quota/Makefile0000664000000000000000000000154111330256617014412 0ustar # # Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_quota HFILES = init.h quota.h CFILES = init.c util.c \ edit.c free.c path.c project.c quot.c quota.c report.c state.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c LSRCFILES = $(shell echo $(PCFILES) | sed -e "s/$(PKG_PLATFORM).c//g") LLDLIBS = $(LIBXCMD) LTDEPENDENCIES = $(LIBXCMD) LLDFLAGS = -static ifeq ($(ENABLE_READLINE),yes) LLDLIBS += $(LIBREADLINE) $(LIBTERMCAP) CFLAGS += -DENABLE_READLINE endif ifeq ($(ENABLE_EDITLINE),yes) LLDLIBS += $(LIBEDITLINE) $(LIBTERMCAP) CFLAGS += -DENABLE_EDITLINE endif default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) install-dev: -include .dep xfsprogs-3.1.9ubuntu2/quota/free.c0000664000000000000000000002227711650373061014046 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "init.h" #include "quota.h" static cmdinfo_t free_cmd; static void free_help(void) { printf(_( "\n" " reports the number of free disk blocks and inodes\n" "\n" " This command reports the number of total, used, and available disk blocks.\n" " It can optionally report the same set of numbers for inodes and realtime\n" " disk blocks, and will report on all known XFS filesystem mount points and\n" " project quota paths by default (see 'print' command for a list).\n" " -b -- report the block count values\n" " -i -- report the inode count values\n" " -r -- report the realtime block count values\n" " -h -- report in a human-readable format\n" " -N -- suppress the header from the output\n" "\n")); } /* * The data and realtime block counts returned (count, used, and * free) are all in basic block units. */ static int mount_free_space_data( struct fs_path *mount, __uint64_t *bcount, __uint64_t *bused, __uint64_t *bfree, __uint64_t *icount, __uint64_t *iused, __uint64_t *ifree, __uint64_t *rcount, __uint64_t *rused, __uint64_t *rfree) { struct xfs_fsop_counts fscounts; struct xfs_fsop_geom fsgeo; struct statfs st; __uint64_t logsize, count, free; int fd; if ((fd = open(mount->fs_dir, O_RDONLY)) < 0) { exitcode = 1; fprintf(stderr, "%s: cannot open %s: %s\n", progname, mount->fs_dir, strerror(errno)); return 0; } if (platform_fstatfs(fd, &st) < 0) { perror("fstatfs"); close(fd); return 0; } if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) { perror("XFS_IOC_FSGEOMETRY_V1"); close(fd); return 0; } if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSCOUNTS, &fscounts)) < 0) { perror("XFS_IOC_FSCOUNTS"); close(fd); return 0; } logsize = fsgeo.logstart ? fsgeo.logblocks : 0; count = (fsgeo.datablocks - logsize) * fsgeo.blocksize; free = fscounts.freedata * fsgeo.blocksize; *bcount = BTOBB(count); *bfree = BTOBB(free); *bused = BTOBB(count - free); *icount = st.f_files; *ifree = st.f_ffree; *iused = st.f_files - st.f_ffree; count = fsgeo.rtextents * fsgeo.rtextsize * fsgeo.blocksize; free = fscounts.freertx * fsgeo.rtextsize * fsgeo.blocksize; *rcount = BTOBB(count); *rfree = BTOBB(free); *rused = BTOBB(count - free); close(fd); return 1; } /* * The data and realtime block counts returned (count, used, and * free) are all in basic block units. */ static int projects_free_space_data( struct fs_path *path, __uint64_t *bcount, __uint64_t *bused, __uint64_t *bfree, __uint64_t *icount, __uint64_t *iused, __uint64_t *ifree, __uint64_t *rcount, __uint64_t *rused, __uint64_t *rfree) { fs_quota_stat_t qfs; fs_disk_quota_t d; struct fsxattr fsx; uint type = XFS_PROJ_QUOTA; char *dev = path->fs_name; int fd; if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, &qfs) < 0 || !(qfs.qs_flags & XFS_QUOTA_PDQ_ACCT)) return 0; if ((fd = open(path->fs_dir, O_RDONLY)) < 0) { exitcode = 1; fprintf(stderr, "%s: cannot open %s: %s\n", progname, path->fs_dir, strerror(errno)); return 0; } if ((xfsctl(path->fs_dir, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { exitcode = 1; perror("XFS_IOC_FSGETXATTR"); close(fd); return 0; } if (!(fsx.fsx_xflags & XFS_XFLAG_PROJINHERIT)) { exitcode = 1; fprintf(stderr, _("%s: project quota flag not set on %s\n"), progname, path->fs_dir); close(fd); return 0; } if (path->fs_prid != fsx.fsx_projid) { exitcode = 1; fprintf(stderr, _("%s: project ID %u (%s) doesn't match ID %u (%s)\n"), progname, path->fs_prid, projects_file, fsx.fsx_projid, path->fs_dir); close(fd); return 0; } xfsquotactl(XFS_QSYNC, dev, type, fsx.fsx_projid, NULL); if (xfsquotactl(XFS_GETQUOTA, dev, type, fsx.fsx_projid, &d) < 0) { perror("XFS_GETQUOTA"); close(fd); return 0; } /* If no softlimit is set for any of blk/ino/rt, get actual usage */ if (!d.d_blk_softlimit || !d.d_ino_softlimit || !d.d_rtb_softlimit) { mount_free_space_data(path, bcount, bused, bfree, icount, iused, ifree, rcount, rused, rfree); } if (d.d_blk_softlimit) { *bcount = d.d_blk_softlimit; *bfree = (d.d_blk_softlimit - d.d_bcount); } *bused = d.d_bcount; if (d.d_ino_softlimit) { *icount = d.d_ino_softlimit; *ifree = (d.d_ino_softlimit - d.d_icount); } *iused = d.d_icount; if (d.d_rtb_softlimit) { *rcount = d.d_rtb_softlimit; *rfree = (d.d_rtb_softlimit - d.d_rtbcount); } *rused = d.d_rtbcount; close(fd); return 1; } static int free_space( FILE *fp, uint form, fs_path_t *path, uint flags) { __uint64_t bcount, bused, bfree; __uint64_t icount, iused, ifree; __uint64_t rcount, rused, rfree; char a[8], s[8], u[8], p[8]; int count; count = (path->fs_flags & FS_PROJECT_PATH) ? projects_free_space_data(path, &bcount, &bused, &bfree, &icount, &iused, &ifree, &rcount, &rused, &rfree) : mount_free_space_data(path, &bcount, &bused, &bfree, &icount, &iused, &ifree, &rcount, &rused, &rfree); if (!count) return 0; if (!(flags & NO_HEADER_FLAG)) { fprintf(fp, (flags & HUMAN_FLAG) ? _("Filesystem ") : _("Filesystem ")); if (form & (XFS_BLOCK_QUOTA|XFS_RTBLOCK_QUOTA)) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Size Used Avail Use%%") : _(" 1K-blocks Used Available Use%%")); else if (form & XFS_INODE_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Inodes Used Free Use%%") : _(" Inodes IUsed IFree IUse%%")); fprintf(fp, _(" Pathname\n")); } if (flags & HUMAN_FLAG) { count = fprintf(fp, "%-12s", path->fs_name); if (count > 13) fprintf(fp, "\n%12s", " "); } else { count = fprintf(fp, "%-19s", path->fs_name); if (count > 20) fprintf(fp, "\n%19s", " "); } if (form & XFS_BLOCK_QUOTA) { if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %3s%%", bbs_to_string(bcount, s, sizeof(s)), bbs_to_string(bused, u, sizeof(u)), bbs_to_string(bfree, a, sizeof(a)), pct_to_string(bused, bcount, p, sizeof(p))); else fprintf(fp, " %10llu %10llu %10llu %3s%%", (unsigned long long)bcount >> 1, (unsigned long long)bused >> 1, (unsigned long long)bfree >> 1, pct_to_string(bused, bcount, p, sizeof(p))); } else if (form & XFS_INODE_QUOTA) { if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %3s%%", num_to_string(icount, s, sizeof(s)), num_to_string(iused, u, sizeof(u)), num_to_string(ifree, a, sizeof(a)), pct_to_string(iused, icount, p, sizeof(p))); else fprintf(fp, " %10llu %10llu %10llu %3s%%", (unsigned long long)icount, (unsigned long long)iused, (unsigned long long)ifree, pct_to_string(iused, icount, p, sizeof(p))); } else if (form & XFS_RTBLOCK_QUOTA) { if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %3s%%", bbs_to_string(rcount, s, sizeof(s)), bbs_to_string(rused, u, sizeof(u)), bbs_to_string(rfree, a, sizeof(a)), pct_to_string(rused, rcount, p, sizeof(p))); else fprintf(fp, " %10llu %10llu %10llu %3s%%", (unsigned long long)rcount >> 1, (unsigned long long)rused >> 1, (unsigned long long)rfree >> 1, pct_to_string(rused, rcount, p, sizeof(p))); } fprintf(fp, " %s\n", path->fs_dir); return 1; } static void free_space_list( FILE *fp, uint form, char *dir, uint flags) { fs_cursor_t cursor; fs_path_t *path; fs_cursor_initialise(dir, 0, &cursor); while ((path = fs_cursor_next_entry(&cursor))) { if (free_space(fp, form, path, flags)) flags |= NO_HEADER_FLAG; } } static int free_f( int argc, char **argv) { FILE *fp = NULL; char *fname = NULL; int c, flags = 0, form = 0; while ((c = getopt(argc, argv, "bf:hNir")) != EOF) { switch (c) { case 'f': fname = optarg; break; case 'b': form |= XFS_BLOCK_QUOTA; break; case 'i': form |= XFS_INODE_QUOTA; break; case 'r': form |= XFS_RTBLOCK_QUOTA; break; case 'h': flags |= HUMAN_FLAG; break; case 'N': flags |= NO_HEADER_FLAG; break; default: return command_usage(&free_cmd); } } if (!form) form = XFS_BLOCK_QUOTA; if ((fp = fopen_write_secure(fname)) == NULL) return 0; if (argc == optind) free_space_list(fp, form, NULL, flags); else while (argc > optind) free_space_list(fp, form, argv[optind++], flags); if (fname) fclose(fp); return 0; } void free_init(void) { free_cmd.name = "df"; free_cmd.altname = "free"; free_cmd.cfunc = free_f; free_cmd.argmin = 0; free_cmd.argmax = -1; free_cmd.args = _("[-bir] [-hn] [-f file]"); free_cmd.oneline = _("show free and used counts for blocks and inodes"); free_cmd.help = free_help; add_command(&free_cmd); } xfsprogs-3.1.9ubuntu2/quota/irix.c0000664000000000000000000000304511140033220014050 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "quota.h" #include static int xcommand_to_qcommand( uint command, uint type) { switch (command) { case XFS_QUOTAON: return Q_XQUOTAON; case XFS_QUOTAOFF: return Q_XQUOTAOFF; case XFS_GETQUOTA: if (type == XFS_GROUP_QUOTA) return Q_XGETGQUOTA; if (type == XFS_PROJ_QUOTA) return Q_XGETPQUOTA; return Q_XGETQUOTA; case XFS_SETQLIM: if (type == XFS_GROUP_QUOTA) return Q_XSETGQLIM; if (type == XFS_PROJ_QUOTA) return Q_XSETPQLIM; return Q_XSETQLIM; case XFS_GETQSTAT: return Q_XGETQSTAT; case XFS_QUOTARM: return Q_XQUOTARM; case XFS_QSYNC: return Q_SYNC; } return 0; } int xfsquotactl( int command, const char *device, uint type, uint id, void *addr) { int qcommand; qcommand = xcommand_to_qcommand(command, type); return quotactl(qcommand, (char *)device, id, addr); } xfsprogs-3.1.9ubuntu2/quota/freebsd.c0000664000000000000000000000153711140033220014513 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "quota.h" int xfsquotactl( int command, const char *device, uint type, uint id, void *addr) { errno = -ENOSYS; return -1; } xfsprogs-3.1.9ubuntu2/quota/linux.c0000664000000000000000000000314011140033220014230 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "quota.h" #include #ifndef PRJQUOTA #define PRJQUOTA 2 #endif static int xtype_to_qtype( uint type) { switch (type) { case XFS_USER_QUOTA: return USRQUOTA; case XFS_GROUP_QUOTA: return GRPQUOTA; case XFS_PROJ_QUOTA: return PRJQUOTA; } return 0; } static int xcommand_to_qcommand( uint command) { switch (command) { case XFS_QUOTAON: return Q_XQUOTAON; case XFS_QUOTAOFF: return Q_XQUOTAOFF; case XFS_GETQUOTA: return Q_XGETQUOTA; case XFS_SETQLIM: return Q_XSETQLIM; case XFS_GETQSTAT: return Q_XGETQSTAT; case XFS_QUOTARM: return Q_XQUOTARM; case XFS_QSYNC: return Q_XQUOTASYNC; } return 0; } int xfsquotactl( int command, const char *device, uint type, uint id, void *addr) { int qcommand, qtype; qtype = xtype_to_qtype(type); qcommand = xcommand_to_qcommand(command); return quotactl(QCMD(qcommand, qtype), device, id, addr); } xfsprogs-3.1.9ubuntu2/quota/darwin.c0000664000000000000000000000166511140033220014367 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "quota.h" #include int xfsquotactl( int command, const char *device, uint type, uint id, void *addr) { /* return quotactl(device, QCMD(command, type), id, addr); */ errno = -ENOSYS; return -1; } xfsprogs-3.1.9ubuntu2/quota/quota.c0000664000000000000000000002443411604735741014261 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "quota.h" static cmdinfo_t quota_cmd; static void quota_help(void) { printf(_( "\n" " display usage and quota information\n" "\n" " -g -- display group quota information\n" " -p -- display project quota information\n" " -u -- display user quota information\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -v -- increase verbosity in reporting (also dumps zero values)\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n")); } static int quota_mount( FILE *fp, __uint32_t id, char *name, uint form, uint type, fs_path_t *mount, uint flags) { fs_disk_quota_t d; char *dev = mount->fs_name; char c[8], h[8], s[8]; uint qflags; int count; xfsquotactl(XFS_QSYNC, dev, type, 0, NULL); if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) return 0; if (!(flags & VERBOSE_FLAG)) { count = 0; if ((form & XFS_BLOCK_QUOTA) && d.d_bcount) count++; if ((form & XFS_INODE_QUOTA) && d.d_icount) count++; if ((form & XFS_RTBLOCK_QUOTA) && d.d_rtbcount) count++; if (!count) return 0; } if (!(flags & NO_HEADER_FLAG)) { fprintf(fp, _("Disk quotas for %s %s (%u)\nFilesystem%s"), type_to_string(type), name, id, (flags & HUMAN_FLAG) ? " " : " "); if (form & XFS_BLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Blocks Quota Limit Warn/Time ") : _(" Blocks Quota Limit Warn/Time ")); if (form & XFS_INODE_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Files Quota Limit Warn/Time ") : _(" Files Quota Limit Warn/Time ")); if (form & XFS_RTBLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _("Realtime Quota Limit Warn/Time ") : _(" Realtime Quota Limit Warn/Time ")); fputs("Mounted on\n", fp); } if (flags & HUMAN_FLAG) { count = fprintf(fp, "%-12s", dev); if (count > 13) fprintf(fp, "\n%12s", " "); } else { count = fprintf(fp, "%-19s", dev); if (count > 20) fprintf(fp, "\n%19s", " "); } if (form & XFS_BLOCK_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit) qflags |= LIMIT_FLAG; if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s ", bbs_to_string(d.d_bcount, c, sizeof(c)), bbs_to_string(d.d_blk_softlimit, s, sizeof(s)), bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)), d.d_bwarns, time_to_string(d.d_btimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s ", (unsigned long long)d.d_bcount >> 1, (unsigned long long)d.d_blk_softlimit >> 1, (unsigned long long)d.d_blk_hardlimit >> 1, d.d_bwarns, time_to_string(d.d_btimer, qflags)); } if (form & XFS_INODE_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit) qflags |= LIMIT_FLAG; if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s ", num_to_string(d.d_icount, c, sizeof(c)), num_to_string(d.d_ino_softlimit, s, sizeof(s)), num_to_string(d.d_ino_hardlimit, h, sizeof(h)), d.d_iwarns, time_to_string(d.d_itimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s ", (unsigned long long)d.d_icount, (unsigned long long)d.d_ino_softlimit, (unsigned long long)d.d_ino_hardlimit, d.d_iwarns, time_to_string(d.d_itimer, qflags)); } if (form & XFS_RTBLOCK_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit) qflags |= LIMIT_FLAG; if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s ", bbs_to_string(d.d_rtbcount, c, sizeof(c)), bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)), bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)), d.d_rtbwarns, time_to_string(d.d_rtbtimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s ", (unsigned long long)d.d_rtbcount >> 1, (unsigned long long)d.d_rtb_softlimit >> 1, (unsigned long long)d.d_rtb_hardlimit >> 1, d.d_rtbwarns, time_to_string(d.d_rtbtimer, qflags)); } fprintf(fp, "%s\n", mount->fs_dir); return 1; } static void quota( FILE *fp, __uint32_t id, char *name, uint form, uint type, uint flags) { fs_cursor_t cursor; fs_path_t *path; fs_cursor_initialise(NULL, FS_MOUNT_POINT, &cursor); while ((path = fs_cursor_next_entry(&cursor))) { if (quota_mount(fp, id, name, form, type, path, flags)) flags |= NO_HEADER_FLAG; } } static char * getusername( uid_t uid, int numeric) { static char buffer[32]; if (!numeric) { struct passwd *u = getpwuid(uid); if (u) return u->pw_name; } snprintf(buffer, sizeof(buffer), "#%u", uid); return &buffer[0]; } static void quota_user_type( FILE *fp, char *name, uint form, uint type, uint flags) { struct passwd *u; uid_t id; if (name) { if (isdigit(name[0])) { id = atoi(name); name = getusername(id, flags & NO_LOOKUP_FLAG); } else if ((u = getpwnam(name))) { id = u->pw_uid; name = u->pw_name; } else { exitcode = 1; fprintf(stderr, _("%s: cannot find user %s\n"), progname, name); return; } } else { id = getuid(); name = getusername(id, flags & NO_LOOKUP_FLAG); } quota(fp, id, name, form, type, flags); } static char * getgroupname( gid_t gid, int numeric) { static char buffer[32]; if (!numeric) { struct group *g = getgrgid(gid); if (g) return g->gr_name; } snprintf(buffer, sizeof(buffer), "#%u", gid); return &buffer[0]; } static void quota_group_type( FILE *fp, char *name, uint form, uint type, uint flags) { struct group *g; gid_t gid, *gids = NULL; int i, ngroups, dofree = 0; if (name) { if (isdigit(name[0])) { gid = atoi(name); name = getgroupname(gid, flags & NO_LOOKUP_FLAG); } else { if ((g = getgrnam(name))) { gid = g->gr_gid; name = g->gr_name; } else { exitcode = 1; fprintf(stderr, _("%s: cannot find group %s\n"), progname, name); return; } } gids = &gid; ngroups = 1; } else if ( ((ngroups = sysconf(_SC_NGROUPS_MAX)) < 0) || ((gids = malloc(ngroups * sizeof(gid_t))) == NULL) || ((ngroups = getgroups(ngroups, gids)) < 0)) { dofree = (gids != NULL); gid = getgid(); gids = &gid; ngroups = 1; } else { dofree = (gids != NULL); } for (i = 0; i < ngroups; i++, name = NULL) { if (!name) name = getgroupname(gids[i], flags & NO_LOOKUP_FLAG); quota(fp, gids[i], name, form, type, flags); } if (dofree) free(gids); } static char * getprojectname( prid_t prid, int numeric) { static char buffer[32]; if (!numeric) { fs_project_t *p = getprprid(prid); if (p) return p->pr_name; } snprintf(buffer, sizeof(buffer), "#%u", (unsigned int)prid); return &buffer[0]; } static void quota_proj_type( FILE *fp, char *name, uint form, uint type, uint flags) { fs_project_t *p; prid_t id; if (!name) { exitcode = 1; fprintf(stderr, _("%s: must specify a project name/ID\n"), progname); return; } if (isdigit(name[0])) { id = atoi(name); name = getprojectname(id, flags & NO_LOOKUP_FLAG); } else if ((p = getprnam(name))) { id = p->pr_prid; name = p->pr_name; } else { exitcode = 1; fprintf(stderr, _("%s: cannot find project %s\n"), progname, name); return; } quota(fp, id, name, form, type, flags); } static void quota_any_type( FILE *fp, char *name, uint form, uint type, uint flags) { switch (type) { case XFS_USER_QUOTA: quota_user_type(fp, name, form, type, flags); break; case XFS_GROUP_QUOTA: quota_group_type(fp, name, form, type, flags); break; case XFS_PROJ_QUOTA: quota_proj_type(fp, name, form, type, flags); break; } } static int quota_f( int argc, char **argv) { FILE *fp = NULL; char *fname = NULL; int c, flags = 0, type = 0, form = 0; while ((c = getopt(argc, argv, "bf:ghnNipruv")) != EOF) { switch (c) { case 'f': fname = optarg; break; case 'b': form |= XFS_BLOCK_QUOTA; break; case 'i': form |= XFS_INODE_QUOTA; break; case 'r': form |= XFS_RTBLOCK_QUOTA; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; case 'h': flags |= HUMAN_FLAG; break; case 'n': flags |= NO_LOOKUP_FLAG; break; case 'N': flags |= NO_HEADER_FLAG; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage("a_cmd); } } if (!form) form = XFS_BLOCK_QUOTA; if (!type) type = XFS_USER_QUOTA; if ((fp = fopen_write_secure(fname)) == NULL) return 0; if (argc == optind) quota_any_type(fp, NULL, form, type, flags); else while (argc > optind) quota_any_type(fp, argv[optind++], form, type, flags); if (fname) fclose(fp); return 0; } void quota_init(void) { quota_cmd.name = "quota"; quota_cmd.altname = "l"; quota_cmd.cfunc = quota_f; quota_cmd.argmin = 0; quota_cmd.argmax = -1; quota_cmd.args = _("[-bir] [-gpu] [-hnNv] [-f file] [id|name]..."); quota_cmd.oneline = _("show usage and limits"); quota_cmd.help = quota_help; add_command("a_cmd); } xfsprogs-3.1.9ubuntu2/quota/quot.c0000664000000000000000000002175311604735741014121 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "init.h" #include "quota.h" typedef struct du { struct du *next; __uint64_t blocks; __uint64_t blocks30; __uint64_t blocks60; __uint64_t blocks90; __uint64_t nfiles; __uint32_t id; } du_t; #define TSIZE 500 static __uint64_t sizes[TSIZE]; static __uint64_t overflow; #define NDU 60000 #define DUHASH 8209 static du_t du[3][NDU]; static du_t *duhash[3][DUHASH]; static int ndu[3]; /* #usr/grp/prj */ #define NBSTAT 4069 static time_t now; static cmdinfo_t quot_cmd; static void quot_help(void) { printf(_( "\n" " display a summary of filesystem ownership\n" "\n" " -a -- summarise for all local XFS filesystem mount points\n" " -c -- display three columns giving file size in kilobytes, number of files\n" " of that size, and cumulative total of kilobytes in that size or\n" " smaller file. The last row is used as an overflow bucket and is the\n" " total of all files greater than 500 kilobytes.\n" " -v -- display three columns containing the number of kilobytes not\n" " accessed in the last 30, 60, and 90 days.\n" " -g -- display group summary\n" " -p -- display project summary\n" " -u -- display user summary\n" " -b -- display number of blocks used\n" " -i -- display number of inodes used\n" " -r -- display number of realtime blocks used\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the initial header\n" " -f -- send output to a file\n" " The (optional) user/group/project can be specified either by name or by\n" " number (i.e. uid/gid/projid).\n" "\n")); } static void quot_bulkstat_add( xfs_bstat_t *p, uint flags) { du_t *dp; du_t **hp; __uint64_t size; __uint32_t i, id; if ((p->bs_mode & S_IFMT) == 0) return; size = howmany((p->bs_blocks * p->bs_blksize), 0x400ULL); if (flags & HISTOGRAM_FLAG) { if (!(S_ISDIR(p->bs_mode) || S_ISREG(p->bs_mode))) return; if (size >= TSIZE) { overflow += size; size = TSIZE - 1; } sizes[(int)size]++; return; } for (i = 0; i < 3; i++) { id = (i == 0) ? p->bs_uid : ((i == 1) ? p->bs_gid : bstat_get_projid(p)); hp = &duhash[i][id % DUHASH]; for (dp = *hp; dp; dp = dp->next) if (dp->id == id) break; if (dp == NULL) { if (ndu[i] >= NDU) return; dp = &du[i][(ndu[i]++)]; dp->next = *hp; *hp = dp; dp->id = id; dp->nfiles = 0; dp->blocks = 0; dp->blocks30 = 0; dp->blocks60 = 0; dp->blocks90 = 0; } dp->blocks += size; if (now - p->bs_atime.tv_sec > 30 * (60*60*24)) dp->blocks30 += size; if (now - p->bs_atime.tv_sec > 60 * (60*60*24)) dp->blocks60 += size; if (now - p->bs_atime.tv_sec > 90 * (60*60*24)) dp->blocks90 += size; dp->nfiles++; } } static void quot_bulkstat_mount( char *fsdir, uint flags) { xfs_fsop_bulkreq_t bulkreq; xfs_bstat_t *buf; __u64 last = 0; __s32 count; int i, sts, fsfd; du_t **dp; /* * Initialize tables between checks; because of the qsort * in report() the hash tables must be rebuilt each time. */ for (sts = 0; sts < TSIZE; sts++) sizes[sts] = 0; overflow = 0; for (i = 0; i < 3; i++) for (dp = duhash[i]; dp < &duhash[i][DUHASH]; dp++) *dp = NULL; ndu[0] = ndu[1] = ndu[2] = 0; fsfd = open(fsdir, O_RDONLY); if (fsfd < 0) { perror(fsdir); return; } buf = (xfs_bstat_t *)calloc(NBSTAT, sizeof(xfs_bstat_t)); if (!buf) { perror("calloc"); return; } bulkreq.lastip = &last; bulkreq.icount = NBSTAT; bulkreq.ubuffer = buf; bulkreq.ocount = &count; while ((sts = xfsctl(fsdir, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq)) == 0) { if (count == 0) break; for (i = 0; i < count; i++) quot_bulkstat_add(&buf[i], flags); } if (sts < 0) perror("XFS_IOC_FSBULKSTAT"), free(buf); close(fsfd); } static int qcompare( du_t *p1, du_t *p2) { if (p1->blocks > p2->blocks) return -1; if (p1->blocks < p2->blocks) return 1; if (p1->id > p2->id) return 1; else if (p1->id < p2->id) return -1; return 0; } typedef char *(*idtoname_t)(__uint32_t); static void quot_report_mount_any_type( FILE *fp, du_t *dp, int count, idtoname_t names, uint form, uint type, fs_path_t *mount, uint flags) { char *cp; fprintf(fp, _("%s (%s) %s:\n"), mount->fs_name, mount->fs_dir, type_to_string(type)); qsort(dp, count, sizeof(dp[0]), (int (*)(const void *, const void *))qcompare); for (; dp < &dp[count]; dp++) { if (dp->blocks == 0) return; fprintf(fp, "%8llu ", (unsigned long long) dp->blocks); if (form & XFS_INODE_QUOTA) fprintf(fp, "%8llu ", (unsigned long long) dp->nfiles); if (!(flags & NO_LOOKUP_FLAG) && ((cp = (names)(dp->id)) != NULL)) fprintf(fp, "%-8.8s", cp); else fprintf(fp, "#%-7d", dp->id); if (flags & VERBOSE_FLAG) fprintf(fp, " %8llu %8llu %8llu", (unsigned long long) dp->blocks30, (unsigned long long) dp->blocks60, (unsigned long long) dp->blocks90); fputc('\n', fp); } } static void quot_report_mount( FILE *fp, uint form, uint type, fs_path_t *mount, uint flags) { switch (type) { case XFS_GROUP_QUOTA: quot_report_mount_any_type(fp, du[1], ndu[1], gid_to_name, form, type, mount, flags); break; case XFS_PROJ_QUOTA: quot_report_mount_any_type(fp, du[2], ndu[2], prid_to_name, form, type, mount, flags); break; case XFS_USER_QUOTA: quot_report_mount_any_type(fp, du[0], ndu[0], uid_to_name, form, type, mount, flags); } } static void quot_report( FILE *fp, uint form, uint type, char *dir, uint flags) { fs_cursor_t cursor; fs_path_t *mount; now = time(NULL); fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { quot_bulkstat_mount(mount->fs_dir, flags); quot_report_mount(fp, form, type, mount, flags); } } static void quot_histogram_mount( FILE *fp, fs_path_t *mount, uint flags) { __uint64_t t = 0; int i; fprintf(fp, _("%s (%s):\n"), mount->fs_name, mount->fs_dir); for (i = 0; i < TSIZE - 1; i++) if (sizes[i] > 0) { t += sizes[i] * i; fprintf(fp, _("%d\t%llu\t%llu\n"), i, (unsigned long long) sizes[i], (unsigned long long) t); } fprintf(fp, _("%d\t%llu\t%llu\n"), TSIZE - 1, (unsigned long long) sizes[TSIZE - 1], (unsigned long long) (overflow + t)); } static void quot_histogram( FILE *fp, char *dir, uint flags) { fs_cursor_t cursor; fs_path_t *mount; fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { quot_bulkstat_mount(mount->fs_dir, flags); quot_histogram_mount(fp, mount, flags); } } static void quot_any_type( FILE *fp, uint form, uint type, char *dir, uint flags) { if (flags & HISTOGRAM_FLAG) quot_histogram(fp, dir, flags); else quot_report(fp, form, type, dir, flags); } static int quot_f( int argc, char **argv) { FILE *fp = NULL; char *fname = NULL; int c, flags = 0, type = 0, form = 0; while ((c = getopt(argc, argv, "abcf:ghinpruv")) != EOF) { switch (c) { case 'f': fname = optarg; break; case 'b': form |= XFS_BLOCK_QUOTA; break; case 'i': form |= XFS_INODE_QUOTA; break; case 'r': form |= XFS_RTBLOCK_QUOTA; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; case 'a': flags |= ALL_MOUNTS_FLAG; break; case 'c': flags |= HISTOGRAM_FLAG; break; case 'n': flags |= NO_LOOKUP_FLAG; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage("_cmd); } } if (!form) form = XFS_BLOCK_QUOTA; if (!type) type = XFS_USER_QUOTA; if ((fp = fopen_write_secure(fname)) == NULL) return 0; if (argc == optind) { if (flags & ALL_MOUNTS_FLAG) quot_any_type(fp, form, type, NULL, flags); else if (fs_path->fs_flags & FS_MOUNT_POINT) quot_any_type(fp, form, type, fs_path->fs_dir, flags); } else while (argc > optind) { quot_any_type(fp, form, type, argv[optind++], flags); } if (fname) fclose(fp); return 0; } void quot_init(void) { quot_cmd.name = "quot"; quot_cmd.cfunc = quot_f; quot_cmd.argmin = 0; quot_cmd.argmax = -1; quot_cmd.args = _("[-bir] [-gpu] [-acv] [-f file]"); quot_cmd.oneline = _("summarize filesystem ownership"); quot_cmd.help = quot_help; if (expert) add_command("_cmd); } xfsprogs-3.1.9ubuntu2/quota/project.c0000664000000000000000000002320511604735741014571 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "init.h" #include "quota.h" static cmdinfo_t project_cmd; static prid_t prid; static int recurse_depth = -1; enum { CHECK_PROJECT = 0x1, SETUP_PROJECT = 0x2, CLEAR_PROJECT = 0x4, }; #define EXCLUDED_FILE_TYPES(x) \ (S_ISCHR((x)) \ || S_ISBLK((x)) \ || S_ISFIFO((x)) \ || S_ISLNK((x)) \ || S_ISSOCK((x))) static void project_help(void) { printf(_( "\n" " list projects or setup a project tree for tree quota management\n" "\n" " Example:\n" " 'project -c logfiles'\n" " (match project 'logfiles' to a directory, and setup the directory tree)\n" "\n" " Without arguments, report all projects found in the /etc/projects file.\n" " The project quota mechanism in XFS can be used to implement a form of\n" " directory tree quota, where a specified directory and all of the files\n" " and subdirectories below it (i.e. a tree) can be restricted to using a\n" " subset of the available space in the filesystem.\n" "\n" " A managed tree must be setup initially using the -c option with a project.\n" " The specified project name or identifier is matched to one or more trees\n" " defined in /etc/projects, and these trees are then recursively descended\n" " to mark the affected inodes as being part of that tree - which sets inode\n" " flags and the project identifier on every file.\n" " Once this has been done, new files created in the tree will automatically\n" " be accounted to the tree based on their project identifier. An attempt to\n" " create a hard link to a file in the tree will only succeed if the project\n" " identifier matches the project identifier for the tree. The xfs_io utility\n" " can be used to set the project ID for an arbitrary file, but this can only\n" " be done by a privileged user.\n" "\n" " A previously setup tree can be cleared from project quota control through\n" " use of the -C option, which will recursively descend the tree, clearing\n" " the affected inodes from project quota control.\n" "\n" " The -c option can be used to check whether a tree is setup, it reports\n" " nothing if the tree is correct, otherwise it reports the paths of inodes\n" " which do not have the project ID of the rest of the tree, or if the inode\n" " flag is not set.\n" "\n" " The -p option can be used to manually specify project path without\n" " need to create /etc/projects file. This option can be used multiple times\n" " to specify multiple paths. When using this option only one projid/name can\n" " be specified at command line. Note that /etc/projects is also used if exists.\n" "\n" " The -d option allows to descend at most levels of directories\n" " below the command line arguments. -d 0 means only apply the actions\n" " to the top level of the projects. -d -1 means no recursion limit (default).\n" "\n" " The /etc/projid and /etc/projects file formats are simple, and described\n" " on the xfs_quota man page.\n" "\n")); } static int check_project( const char *path, const struct stat *stat, int flag, struct FTW *data) { struct fsxattr fsx; int fd; if (recurse_depth >= 0 && data->level > recurse_depth) return -1; if (flag == FTW_NS ){ exitcode = 1; fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path); return 0; } if (EXCLUDED_FILE_TYPES(stat->st_mode)) { fprintf(stderr, _("%s: skipping special file %s\n"), progname, path); return 0; } if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) { exitcode = 1; fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); } else if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, path, strerror(errno)); } else { if (fsx.fsx_projid != prid) printf(_("%s - project identifier is not set" " (inode=%u, tree=%u)\n"), path, fsx.fsx_projid, (unsigned int)prid); if (!(fsx.fsx_xflags & XFS_XFLAG_PROJINHERIT)) printf(_("%s - project inheritance flag is not set\n"), path); } if (fd != -1) close(fd); return 0; } static int clear_project( const char *path, const struct stat *stat, int flag, struct FTW *data) { struct fsxattr fsx; int fd; if (recurse_depth >= 0 && data->level > recurse_depth) return -1; if (flag == FTW_NS ){ exitcode = 1; fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path); return 0; } if (EXCLUDED_FILE_TYPES(stat->st_mode)) { fprintf(stderr, _("%s: skipping special file %s\n"), progname, path); return 0; } if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) { exitcode = 1; fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); return 0; } else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, path, strerror(errno)); close(fd); return 0; } fsx.fsx_projid = 0; fsx.fsx_xflags &= ~XFS_XFLAG_PROJINHERIT; if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot clear project on %s: %s\n"), progname, path, strerror(errno)); } close(fd); return 0; } static int setup_project( const char *path, const struct stat *stat, int flag, struct FTW *data) { struct fsxattr fsx; int fd; if (recurse_depth >= 0 && data->level > recurse_depth) return -1; if (flag == FTW_NS ){ exitcode = 1; fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path); return 0; } if (EXCLUDED_FILE_TYPES(stat->st_mode)) { fprintf(stderr, _("%s: skipping special file %s\n"), progname, path); return 0; } if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) { exitcode = 1; fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, path, strerror(errno)); return 0; } else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot get flags on %s: %s\n"), progname, path, strerror(errno)); close(fd); return 0; } fsx.fsx_projid = prid; fsx.fsx_xflags |= XFS_XFLAG_PROJINHERIT; if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot set project on %s: %s\n"), progname, path, strerror(errno)); } close(fd); return 0; } static void project_operations( char *project, char *dir, int type) { switch (type) { case CHECK_PROJECT: printf(_("Checking project %s (path %s)...\n"), project, dir); nftw(dir, check_project, 100, FTW_PHYS|FTW_MOUNT); break; case SETUP_PROJECT: printf(_("Setting up project %s (path %s)...\n"), project, dir); nftw(dir, setup_project, 100, FTW_PHYS|FTW_MOUNT); break; case CLEAR_PROJECT: printf(_("Clearing project %s (path %s)...\n"), project, dir); nftw(dir, clear_project, 100, FTW_PHYS|FTW_MOUNT); break; } } static void project( char *project, int type) { fs_cursor_t cursor; fs_path_t *path; int count = 0; fs_cursor_initialise(NULL, FS_PROJECT_PATH, &cursor); while ((path = fs_cursor_next_entry(&cursor))) { if (prid != path->fs_prid && path->fs_prid != -1) continue; project_operations(project, path->fs_dir, type); count++; } printf(_("Processed %d (%s and cmdline) paths for project %s with " "recursion depth %s (%d).\n"), count, projects_file, project, recurse_depth < 0 ? _("infinite") : _("limited"), recurse_depth); } static int project_f( int argc, char **argv) { int c, type = 0, ispath = 0; while ((c = getopt(argc, argv, "cd:p:sC")) != EOF) { switch (c) { case 'c': type = CHECK_PROJECT; break; case 'd': recurse_depth = atoi(optarg); if (recurse_depth < 0) recurse_depth = -1; break; case 'p': ispath = 1; fs_table_insert_project_path(optarg, -1); break; case 's': type = SETUP_PROJECT; break; case 'C': type = CLEAR_PROJECT; break; default: return command_usage(&project_cmd); } } if (argc == optind) return command_usage(&project_cmd); /* no options - just check the given projects */ if (!type) type = CHECK_PROJECT; setprfiles(); if (!ispath && access(projects_file, F_OK) != 0) { exitcode = 1; fprintf(stderr, _("projects file \"%s\" doesn't exist\n"), projects_file); return 0; } if (ispath && argc - optind > 1) { exitcode = 1; fprintf(stderr, _("%s: only one projid/name can be specified " "when using -p , %d found.\n"), progname, argc - optind); return 0; } while (argc > optind) { prid = prid_from_string(argv[optind]); if (prid == -1) { exitcode = 1; fprintf(stderr, _("%s - no such project in %s " "or invalid project number\n"), argv[optind], projects_file); } else project(argv[optind], type); optind++; } return 0; } void project_init(void) { project_cmd.name = "project"; project_cmd.altname = "tree"; project_cmd.cfunc = project_f; project_cmd.args = _("[-c|-s|-C|-d |-p ] project ..."); project_cmd.argmin = 1; project_cmd.argmax = -1; project_cmd.oneline = _("check, setup or clear project quota trees"); project_cmd.help = project_help; if (expert) add_command(&project_cmd); } xfsprogs-3.1.9ubuntu2/quota/report.c0000664000000000000000000003754712062210562014440 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "init.h" #include "quota.h" static cmdinfo_t dump_cmd; static cmdinfo_t report_cmd; static void dump_help(void) { dump_cmd.args = _("[-gpu] [-f file]"); dump_cmd.oneline = _("dump quota information for backup utilities"); printf(_( "\n" " create a backup file which contains quota limits information\n" " -g -- dump out group quota limits\n" " -p -- dump out project quota limits\n" " -u -- dump out user quota limits (default)\n" " -f -- write the dump out to the specified file\n" "\n")); } static void report_help(void) { report_cmd.args = _("[-bir] [-gpu] [-ahntLNU] [-f file]"); report_cmd.oneline = _("report filesystem quota information"); printf(_( "\n" " report used space and inodes, and quota limits, for a filesystem\n" " Example:\n" " 'report -igh'\n" " (reports inode usage for all groups, in an easy-to-read format)\n" " This command is the equivalent of the traditional repquota command, which\n" " prints a summary of the disk usage and quotas for the current filesystem,\n" " or all filesystems.\n" " -a -- report for all mounted filesystems with quota enabled\n" " -h -- report in a human-readable format\n" " -n -- skip identifier-to-name translations, just report IDs\n" " -N -- suppress the header from the output\n" " -t -- terse output format, hides rows which are all zero\n" " -L -- lower ID bound to report on\n" " -U -- upper ID bound to report on\n" " -g -- report group usage and quota information\n" " -p -- report project usage and quota information\n" " -u -- report user usage and quota information\n" " -b -- report blocks-used information only\n" " -i -- report inodes-used information only\n" " -r -- report realtime-blocks-used information only\n" "\n")); } static void dump_file( FILE *fp, uint id, uint type, char *dev) { fs_disk_quota_t d; if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) { if (errno != ENOENT && errno != ENOSYS && errno != ESRCH) perror("XFS_GETQUOTA"); return; } if (!d.d_blk_softlimit && !d.d_blk_hardlimit && !d.d_ino_softlimit && !d.d_ino_hardlimit && !d.d_rtb_softlimit && !d.d_rtb_hardlimit) return; fprintf(fp, "fs = %s\n", dev); /* this branch is for backward compatibility reasons */ if (d.d_rtb_softlimit || d.d_rtb_hardlimit) fprintf(fp, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id, (unsigned long long)d.d_blk_softlimit, (unsigned long long)d.d_blk_hardlimit, (unsigned long long)d.d_ino_softlimit, (unsigned long long)d.d_ino_hardlimit, (unsigned long long)d.d_rtb_softlimit, (unsigned long long)d.d_rtb_hardlimit); else fprintf(fp, "%-10d %7llu %7llu %7llu %7llu\n", id, (unsigned long long)d.d_blk_softlimit, (unsigned long long)d.d_blk_hardlimit, (unsigned long long)d.d_ino_softlimit, (unsigned long long)d.d_ino_hardlimit); } static void dump_limits_any_type( FILE *fp, uint type, char *dir, uint lower, uint upper) { fs_path_t *mount; uint id; if ((mount = fs_table_lookup(dir, FS_MOUNT_POINT)) == NULL) { exitcode = 1; fprintf(stderr, "%s: cannot find mount point %s\n", progname, dir); return; } if (upper) { for (id = lower; id <= upper; id++) dump_file(fp, id, type, mount->fs_name); return; } switch (type) { case XFS_GROUP_QUOTA: { struct group *g; setgrent(); while ((g = getgrent()) != NULL) dump_file(fp, g->gr_gid, type, mount->fs_name); endgrent(); break; } case XFS_PROJ_QUOTA: { struct fs_project *p; setprent(); while ((p = getprent()) != NULL) dump_file(fp, p->pr_prid, type, mount->fs_name); endprent(); break; } case XFS_USER_QUOTA: { struct passwd *u; setpwent(); while ((u = getpwent()) != NULL) dump_file(fp, u->pw_uid, type, mount->fs_name); endpwent(); break; } } } static int dump_f( int argc, char **argv) { FILE *fp; char *fname = NULL; uint lower = 0, upper = 0; int c, type = XFS_USER_QUOTA; while ((c = getopt(argc, argv, "f:gpuL:U:")) != EOF) { switch(c) { case 'f': fname = optarg; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; case 'L': lower = (uint)atoi(optarg); break; case 'U': upper = (uint)atoi(optarg); break; default: return command_usage(&dump_cmd); } } if (argc != optind) return command_usage(&dump_cmd); if ((fp = fopen_write_secure(fname)) == NULL) return 0; dump_limits_any_type(fp, type, fs_path->fs_dir, lower, upper); if (fname) fclose(fp); return 0; } static void report_header( FILE *fp, uint form, uint type, fs_path_t *mount, int flags) { char *typename = type_to_string(type); char scratch[64]; uint i, count; if (flags & NO_HEADER_FLAG) return; /* line 1 */ fprintf(fp, _("%s quota on %s (%s)\n"), typename, mount->fs_dir, mount->fs_name); /* line 2 */ for (i = 0; i < 10; i++) fputc(' ', fp); if (form & XFS_BLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? "%13c %s %13c" : "%20c %s %20c", ' ', form_to_string(XFS_BLOCK_QUOTA), ' '); if (form & XFS_INODE_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? "%13c %s %13c" : "%20c %s %20c", ' ', form_to_string(XFS_INODE_QUOTA), ' '); if (form & XFS_RTBLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? "%9c %s %9c" : "%15c %s %15c", ' ', form_to_string(XFS_RTBLOCK_QUOTA), ' '); fputc('\n', fp); /* line 3 */ snprintf(scratch, sizeof(scratch), "%s ID", typename); fprintf(fp, "%-10s ", scratch); if (form & XFS_BLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Used Soft Hard Warn/Grace ") : _(" Used Soft Hard Warn/Grace ")); if (form & XFS_INODE_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Used Soft Hard Warn/Grace ") : _(" Used Soft Hard Warn/ Grace ")); if (form & XFS_RTBLOCK_QUOTA) fprintf(fp, (flags & HUMAN_FLAG) ? _(" Used Soft Hard Warn/Grace ") : _(" Used Soft Hard Warn/Grace ")); fputc('\n', fp); /* line 4 */ for (i = 0; i < 10; i++) fputc('-', fp); fputc(' ', fp); count = (flags & HUMAN_FLAG) ? 33 : 50; if (form & XFS_BLOCK_QUOTA) { for (i = 0; i < count; i++) fputc('-', fp); fputc(' ', fp); } if (form & XFS_INODE_QUOTA) { for (i = 0; i < count; i++) fputc('-', fp); fputc(' ', fp); } if (form & XFS_RTBLOCK_QUOTA) { for (i = 0; i < count; i++) fputc('-', fp); fputc(' ', fp); } fputc('\n', fp); } static int report_mount( FILE *fp, __uint32_t id, char *name, uint form, uint type, fs_path_t *mount, uint flags) { fs_disk_quota_t d; char *dev = mount->fs_name; char c[8], h[8], s[8]; uint qflags; int count; if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) { if (errno != ENOENT && errno != ENOSYS && errno != ESRCH) perror("XFS_GETQUOTA"); return 0; } if (flags & TERSE_FLAG) { count = 0; if ((form & XFS_BLOCK_QUOTA) && d.d_bcount) count++; if ((form & XFS_INODE_QUOTA) && d.d_icount) count++; if ((form & XFS_RTBLOCK_QUOTA) && d.d_rtbcount) count++; if (!count) return 0; } if (!(flags & NO_HEADER_FLAG)) report_header(fp, form, type, mount, flags); fprintf(fp, "%-10s", name); if (form & XFS_BLOCK_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit) qflags |= LIMIT_FLAG; if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s", bbs_to_string(d.d_bcount, c, sizeof(c)), bbs_to_string(d.d_blk_softlimit, s, sizeof(s)), bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)), d.d_bwarns, time_to_string(d.d_btimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s", (unsigned long long)d.d_bcount >> 1, (unsigned long long)d.d_blk_softlimit >> 1, (unsigned long long)d.d_blk_hardlimit >> 1, d.d_bwarns, time_to_string(d.d_btimer, qflags)); } if (form & XFS_INODE_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit) qflags |= LIMIT_FLAG; if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s", num_to_string(d.d_icount, c, sizeof(c)), num_to_string(d.d_ino_softlimit, s, sizeof(s)), num_to_string(d.d_ino_hardlimit, h, sizeof(h)), d.d_iwarns, time_to_string(d.d_itimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s", (unsigned long long)d.d_icount, (unsigned long long)d.d_ino_softlimit, (unsigned long long)d.d_ino_hardlimit, d.d_iwarns, time_to_string(d.d_itimer, qflags)); } if (form & XFS_RTBLOCK_QUOTA) { qflags = (flags & HUMAN_FLAG); if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit) qflags |= LIMIT_FLAG; if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit) qflags |= QUOTA_FLAG; if (flags & HUMAN_FLAG) fprintf(fp, " %6s %6s %6s %02d %8s", bbs_to_string(d.d_rtbcount, c, sizeof(c)), bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)), bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)), d.d_rtbwarns, time_to_string(d.d_rtbtimer, qflags)); else fprintf(fp, " %10llu %10llu %10llu %02d %9s", (unsigned long long)d.d_rtbcount >> 1, (unsigned long long)d.d_rtb_softlimit >> 1, (unsigned long long)d.d_rtb_hardlimit >> 1, d.d_rtbwarns, time_to_string(d.d_rtbtimer, qflags)); } fputc('\n', fp); return 1; } static void report_user_mount( FILE *fp, uint form, fs_path_t *mount, uint lower, uint upper, uint flags) { struct passwd *u; char n[NMAX]; uint id; if (upper) { /* identifier range specified */ for (id = lower; id <= upper; id++) { snprintf(n, sizeof(n)-1, "#%u", id); if (report_mount(fp, id, n, form, XFS_USER_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } } else { setpwent(); while ((u = getpwent()) != NULL) { if (flags & NO_LOOKUP_FLAG) snprintf(n, sizeof(n)-1, "#%u", u->pw_uid); else strncpy(n, u->pw_name, sizeof(n)-1); if (report_mount(fp, u->pw_uid, n, form, XFS_USER_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } endpwent(); } if (flags & NO_HEADER_FLAG) fputc('\n', fp); } static void report_group_mount( FILE *fp, uint form, fs_path_t *mount, uint lower, uint upper, uint flags) { struct group *g; char n[NMAX]; uint id; if (upper) { /* identifier range specified */ for (id = lower; id <= upper; id++) { snprintf(n, sizeof(n)-1, "#%u", id); if (report_mount(fp, id, n, form, XFS_GROUP_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } } else { setgrent(); while ((g = getgrent()) != NULL) { if (flags & NO_LOOKUP_FLAG) snprintf(n, sizeof(n)-1, "#%u", g->gr_gid); else strncpy(n, g->gr_name, sizeof(n)-1); if (report_mount(fp, g->gr_gid, n, form, XFS_GROUP_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } } if (flags & NO_HEADER_FLAG) fputc('\n', fp); endgrent(); } static void report_project_mount( FILE *fp, uint form, fs_path_t *mount, uint lower, uint upper, uint flags) { fs_project_t *p; char n[NMAX]; uint id; if (upper) { /* identifier range specified */ for (id = lower; id <= upper; id++) { snprintf(n, sizeof(n)-1, "#%u", id); if (report_mount(fp, id, n, form, XFS_PROJ_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } } else { setprent(); while ((p = getprent()) != NULL) { if (flags & NO_LOOKUP_FLAG) snprintf(n, sizeof(n)-1, "#%u", (unsigned int)p->pr_prid); else strncpy(n, p->pr_name, sizeof(n)-1); if (report_mount(fp, p->pr_prid, n, form, XFS_PROJ_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } endprent(); } if (flags & NO_HEADER_FLAG) fputc('\n', fp); } static void report_any_type( FILE *fp, uint form, uint type, char *dir, uint lower, uint upper, uint flags) { fs_cursor_t cursor; fs_path_t *mount; if (type & XFS_USER_QUOTA) { fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { if (xfsquotactl(XFS_QSYNC, mount->fs_name, XFS_USER_QUOTA, 0, NULL) < 0 && errno != ENOENT && errno != ENOSYS) perror("XFS_QSYNC user quota"); report_user_mount(fp, form, mount, lower, upper, flags); } } if (type & XFS_GROUP_QUOTA) { fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { if (xfsquotactl(XFS_QSYNC, mount->fs_name, XFS_GROUP_QUOTA, 0, NULL) < 0 && errno != ENOENT && errno != ENOSYS) perror("XFS_QSYNC group quota"); report_group_mount(fp, form, mount, lower, upper, flags); } } if (type & XFS_PROJ_QUOTA) { fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) { if (xfsquotactl(XFS_QSYNC, mount->fs_name, XFS_PROJ_QUOTA, 0, NULL) < 0 && errno != ENOENT && errno != ENOSYS) perror("XFS_QSYNC proj quota"); report_project_mount(fp, form, mount, lower, upper, flags); } } } static int report_f( int argc, char **argv) { FILE *fp = NULL; char *fname = NULL; uint lower = 0, upper = 0; int c, flags = 0, type = 0, form = 0; while ((c = getopt(argc, argv, "abf:ghiL:NnprtuU:")) != EOF) { switch (c) { case 'f': fname = optarg; break; case 'b': form |= XFS_BLOCK_QUOTA; break; case 'i': form |= XFS_INODE_QUOTA; break; case 'r': form |= XFS_RTBLOCK_QUOTA; break; case 'g': type |= XFS_GROUP_QUOTA; break; case 'p': type |= XFS_PROJ_QUOTA; break; case 'u': type |= XFS_USER_QUOTA; break; case 'a': flags |= ALL_MOUNTS_FLAG; break; case 'h': flags |= HUMAN_FLAG; break; case 'n': flags |= NO_LOOKUP_FLAG; break; case 'N': flags |= NO_HEADER_FLAG; break; case 't': flags |= TERSE_FLAG; break; case 'L': lower = (uint)atoi(optarg); break; case 'U': upper = (uint)atoi(optarg); break; default: return command_usage(&report_cmd); } } if (!form) form = XFS_BLOCK_QUOTA; if (!type) type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA; if ((fp = fopen_write_secure(fname)) == NULL) return 0; if (argc == optind) { if (flags & ALL_MOUNTS_FLAG) report_any_type(fp, form, type, NULL, lower, upper, flags); else if (fs_path->fs_flags & FS_MOUNT_POINT) report_any_type(fp, form, type, fs_path->fs_dir, lower, upper, flags); } else while (argc > optind) { report_any_type(fp, form, type, argv[optind++], lower, upper, flags); } if (fname) fclose(fp); return 0; } void report_init(void) { dump_cmd.name = "dump"; dump_cmd.cfunc = dump_f; dump_cmd.argmin = 0; dump_cmd.argmax = -1; dump_cmd.args = _("[-gpu] [-f file]"); dump_cmd.oneline = _("dump quota information for backup utilities"); dump_cmd.help = dump_help; report_cmd.name = "report"; report_cmd.altname = "repquota"; report_cmd.cfunc = report_f; report_cmd.argmin = 0; report_cmd.argmax = -1; report_cmd.flags = CMD_FLAG_GLOBAL; report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]"); report_cmd.oneline = _("report filesystem quota information"); report_cmd.help = report_help; if (expert) { add_command(&dump_cmd); add_command(&report_cmd); } } xfsprogs-3.1.9ubuntu2/quota/edit.c0000664000000000000000000004027112062210562014036 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "init.h" #include "quota.h" static cmdinfo_t limit_cmd; static cmdinfo_t restore_cmd; static cmdinfo_t timer_cmd; static cmdinfo_t warn_cmd; static void limit_help(void) { printf(_( "\n" " modify quota limits for the specified user\n" "\n" " Example:\n" " 'limit bsoft=100m bhard=110m tanya\n" "\n" " Changes the soft and/or hard block limits, inode limits and/or realtime\n" " block limits that are currently being used for the specified user, group,\n" " or project. The filesystem identified by the current path is modified.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota limits\n" " -p -- modify project quota limits\n" " -u -- modify user quota limits\n" " The block limit values can be specified with a units suffix - accepted\n" " units are: k (kilobytes), m (megabytes), g (gigabytes), and t (terabytes).\n" " The user/group/project can be specified either by name or by number.\n" "\n")); } static void timer_help(void) { printf(_( "\n" " modify quota enforcement timeout for the current filesystem\n" "\n" " Example:\n" " 'timer -i 3days'\n" " (soft inode limit timer is changed to 3 days)\n" "\n" " Changes the timeout value associated with the block limits, inode limits\n" " and/or realtime block limits for all users, groups, or projects on the\n" " current filesystem.\n" " As soon as a user consumes the amount of space or number of inodes set as\n" " the soft limit, a timer is started. If the timer expires and the user is\n" " still over the soft limit, the soft limit is enforced as the hard limit.\n" " The default timeout is 7 days.\n" " -d -- set the default values, used the first time a file is created\n" " -g -- modify group quota timer\n" " -p -- modify project quota timer\n" " -u -- modify user quota timer\n" " -b -- modify the blocks-used timer\n" " -i -- modify the inodes-used timer\n" " -r -- modify the blocks-used timer for the (optional) realtime subvolume\n" " The timeout value is specified as a number of seconds, by default.\n" " However, a suffix may be used to alternatively specify minutes (m),\n" " hours (h), days (d), or weeks (w) - either the full word or the first\n" " letter of the word can be used.\n" "\n")); } static void warn_help(void) { printf(_( "\n" " modify the number of quota warnings sent to the specified user\n" "\n" " Example:\n" " 'warn 2 jimmy'\n" " (tell the quota system that two warnings have been sent to user jimmy)\n" "\n" " Changes the warning count associated with the block limits, inode limits\n" " and/or realtime block limits for the specified user, group, or project.\n" " When a user has been warned the maximum number of times allowed, the soft\n" " limit is enforced as the hard limit. It is intended as an alternative to\n" " the timeout system, where the system administrator updates a count of the\n" " number of warnings issued to people, and they are penalised if the warnings\n" " are ignored.\n" " -d -- set maximum warning count, which triggers soft limit enforcement\n" " -g -- set group quota warning count\n" " -p -- set project quota warning count\n" " -u -- set user quota warning count\n" " -b -- set the blocks-used warning count\n" " -i -- set the inodes-used warning count\n" " -r -- set the blocks-used warn count for the (optional) realtime subvolume\n" " The user/group/project can be specified either by name or by number.\n" "\n")); } static void set_limits( __uint32_t id, uint type, uint mask, char *dev, __uint64_t *bsoft, __uint64_t *bhard, __uint64_t *isoft, __uint64_t *ihard, __uint64_t *rtbsoft, __uint64_t *rtbhard) { fs_disk_quota_t d; memset(&d, 0, sizeof(d)); d.d_version = FS_DQUOT_VERSION; d.d_id = id; d.d_flags = type; d.d_fieldmask = mask; d.d_blk_hardlimit = *bhard; d.d_blk_softlimit = *bsoft; d.d_ino_hardlimit = *ihard; d.d_ino_softlimit = *isoft; d.d_rtb_hardlimit = *rtbhard; d.d_rtb_softlimit = *rtbsoft; if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot set limits: %s\n"), progname, strerror(errno)); } } static void set_user_limits( char *name, uint type, uint mask, __uint64_t *bsoft, __uint64_t *bhard, __uint64_t *isoft, __uint64_t *ihard, __uint64_t *rtbsoft, __uint64_t *rtbhard) { uid_t uid = uid_from_string(name); if (uid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid user name: %s\n"), progname, name); } else set_limits(uid, type, mask, fs_path->fs_name, bsoft, bhard, isoft, ihard, rtbsoft, rtbhard); } static void set_group_limits( char *name, uint type, uint mask, __uint64_t *bsoft, __uint64_t *bhard, __uint64_t *isoft, __uint64_t *ihard, __uint64_t *rtbsoft, __uint64_t *rtbhard) { gid_t gid = gid_from_string(name); if (gid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid group name: %s\n"), progname, name); } else set_limits(gid, type, mask, fs_path->fs_name, bsoft, bhard, isoft, ihard, rtbsoft, rtbhard); } static void set_project_limits( char *name, uint type, uint mask, __uint64_t *bsoft, __uint64_t *bhard, __uint64_t *isoft, __uint64_t *ihard, __uint64_t *rtbsoft, __uint64_t *rtbhard) { prid_t prid = prid_from_string(name); if (prid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid project name: %s\n"), progname, name); } else set_limits(prid, type, mask, fs_path->fs_name, bsoft, bhard, isoft, ihard, rtbsoft, rtbhard); } /* extract number of blocks from an ascii string */ static int extractb( char *string, const char *prefix, int length, uint blocksize, uint sectorsize, __uint64_t *value) { long long v; char *s = string; if (strncmp(string, prefix, length) == 0) { s = string + length + 1; v = cvtnum(blocksize, sectorsize, s); if (v == -1LL) { fprintf(stderr, _("%s: Error: could not parse size %s.\n"), progname, s); return 0; } *value = (__uint64_t)v >> 9; /* syscalls use basic blocks */ if (v > 0 && *value == 0) fprintf(stderr, _("%s: Warning: `%s' in quota blocks is 0 (unlimited).\n"), progname, s); return 1; } return 0; } /* extract number of inodes from an ascii string */ static int extracti( char *string, const char *prefix, int length, __uint64_t *value) { char *sp, *s = string; if (strncmp(string, prefix, length) == 0) { s = string + length + 1; *value = strtoll(s, &sp, 0); return 1; } return 0; } static int limit_f( int argc, char **argv) { char *name; __uint64_t bsoft, bhard, isoft, ihard, rtbsoft, rtbhard; int c, type = 0, mask = 0, flags = 0; uint bsize, ssize, endoptions; init_cvtnum(&bsize, &ssize); bsoft = bhard = isoft = ihard = rtbsoft = rtbhard = 0; while ((c = getopt(argc, argv, "dgpu")) != EOF) { switch (c) { case 'd': flags |= DEFAULTS_FLAG; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; default: return command_usage(&limit_cmd); } } /* * In the usual case, we need at least 2 more arguments - * one (or more) limits and a user name/id. * For setting defaults (-d) we don't want a user name/id. */ if (flags & DEFAULTS_FLAG) { if (argc < optind + 1) return command_usage(&limit_cmd); endoptions = 1; } else if (argc < optind + 2) { return command_usage(&limit_cmd); } else { endoptions = 2; } /* * Extract limit values from remaining optional arguments. */ while (argc > optind + endoptions - 1) { char *s = argv[optind++]; if (extractb(s, "bsoft=", 5, bsize, ssize, &bsoft)) mask |= FS_DQ_BSOFT; else if (extractb(s, "bhard=", 5, bsize, ssize, &bhard)) mask |= FS_DQ_BHARD; else if (extracti(s, "isoft=", 5, &isoft)) mask |= FS_DQ_ISOFT; else if (extracti(s, "ihard=", 5, &ihard)) mask |= FS_DQ_IHARD; else if (extractb(s, "rtbsoft=", 7, bsize, ssize, &rtbsoft)) mask |= FS_DQ_RTBSOFT; else if (extractb(s, "rtbhard=", 7, bsize, ssize, &rtbhard)) mask |= FS_DQ_RTBHARD; else { exitcode = 1; fprintf(stderr, _("%s: unrecognised argument %s\n"), progname, s); return 0; } } if (!mask) { exitcode = 1; fprintf(stderr, _("%s: cannot find any valid arguments\n"), progname); return 0; } name = (flags & DEFAULTS_FLAG) ? "0" : argv[optind++]; if (!type) type = XFS_USER_QUOTA; switch (type) { case XFS_USER_QUOTA: set_user_limits(name, type, mask, &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard); break; case XFS_GROUP_QUOTA: set_group_limits(name, type, mask, &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard); break; case XFS_PROJ_QUOTA: set_project_limits(name, type, mask, &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard); break; } return 0; } /* * Iterate through input file, restoring the limits. * File format is as follows: * fs = * bsoft bhard isoft ihard [rtbsoft rtbhard] */ static void restore_file( FILE *fp, uint type) { char buffer[512]; char devbuffer[512]; char *dev = NULL; uint mask; int cnt; __uint32_t id; __uint64_t bsoft, bhard, isoft, ihard, rtbsoft, rtbhard; while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strncmp("fs = ", buffer, 5) == 0) { dev = strncpy(devbuffer, buffer+5, sizeof(devbuffer)); dev[strlen(dev) - 1] = '\0'; continue; } rtbsoft = rtbhard = 0; cnt = sscanf(buffer, "%u %llu %llu %llu %llu %llu %llu\n", &id, (unsigned long long *)&bsoft, (unsigned long long *)&bhard, (unsigned long long *)&isoft, (unsigned long long *)&ihard, (unsigned long long *)&rtbsoft, (unsigned long long *)&rtbhard); if (cnt == 5 || cnt == 7) { mask = FS_DQ_ISOFT|FS_DQ_IHARD|FS_DQ_BSOFT|FS_DQ_BHARD; if (cnt == 7) mask |= FS_DQ_RTBSOFT|FS_DQ_RTBHARD; set_limits(id, type, mask, dev, &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard); } } } static int restore_f( int argc, char **argv) { FILE *fp = stdin; char *fname = NULL; int c, type = 0; while ((c = getopt(argc, argv, "f:gpu")) != EOF) { switch (c) { case 'f': fname = optarg; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; default: return command_usage(&restore_cmd); } } if (argc < optind) return command_usage(&restore_cmd); if (!type) type = XFS_USER_QUOTA; if (fname) { if ((fp = fopen(fname, "r")) == NULL) { exitcode = 1; fprintf(stderr, _("%s: fopen on %s failed: %s\n"), progname, fname, strerror(errno)); return 0; } } restore_file(fp, type); if (fname) fclose(fp); return 0; } static void set_timer( uint type, uint mask, char *dev, uint value) { fs_disk_quota_t d; memset(&d, 0, sizeof(d)); d.d_version = FS_DQUOT_VERSION; d.d_flags = type; d.d_fieldmask = mask; d.d_itimer = value; d.d_btimer = value; d.d_rtbtimer = value; if (xfsquotactl(XFS_SETQLIM, dev, type, 0, (void *)&d) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot set timer: %s\n"), progname, strerror(errno)); } } static int timer_f( int argc, char **argv) { uint value; int c, type = 0, mask = 0; while ((c = getopt(argc, argv, "bgipru")) != EOF) { switch (c) { case 'b': mask |= FS_DQ_BTIMER; break; case 'i': mask |= FS_DQ_ITIMER; break; case 'r': mask |= FS_DQ_RTBTIMER; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; default: return command_usage(&timer_cmd); } } if (argc != optind + 1) return command_usage(&timer_cmd); value = cvttime(argv[optind++]); if (!mask) mask = FS_DQ_TIMER_MASK; if (!type) type = XFS_USER_QUOTA; set_timer(type, mask, fs_path->fs_name, value); return 0; } static void set_warnings( __uint32_t id, uint type, uint mask, char *dev, uint value) { fs_disk_quota_t d; memset(&d, 0, sizeof(d)); d.d_version = FS_DQUOT_VERSION; d.d_id = id; d.d_flags = type; d.d_fieldmask = mask; d.d_iwarns = value; d.d_bwarns = value; d.d_rtbwarns = value; if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) { exitcode = 1; fprintf(stderr, _("%s: cannot set warnings: %s\n"), progname, strerror(errno)); } } static void set_user_warnings( char *name, uint type, uint mask, uint value) { uid_t uid = uid_from_string(name); if (uid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid user name: %s\n"), progname, name); } else set_warnings(uid, type, mask, fs_path->fs_name, value); } static void set_group_warnings( char *name, uint type, uint mask, uint value) { gid_t gid = gid_from_string(name); if (gid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid group name: %s\n"), progname, name); } else set_warnings(gid, type, mask, fs_path->fs_name, value); } static void set_project_warnings( char *name, uint type, uint mask, uint value) { prid_t prid = prid_from_string(name); if (prid == -1) { exitcode = 1; fprintf(stderr, _("%s: invalid project name: %s\n"), progname, name); } else set_warnings(prid, type, mask, fs_path->fs_name, value); } static int warn_f( int argc, char **argv) { char *name; uint value; int c, flags = 0, type = 0, mask = 0; while ((c = getopt(argc, argv, "bdgipru")) != EOF) { switch (c) { case 'd': flags |= DEFAULTS_FLAG; break; case 'b': mask |= FS_DQ_BWARNS; break; case 'i': mask |= FS_DQ_IWARNS; break; case 'r': mask |= FS_DQ_RTBWARNS; break; case 'g': type = XFS_GROUP_QUOTA; break; case 'p': type = XFS_PROJ_QUOTA; break; case 'u': type = XFS_USER_QUOTA; break; default: return command_usage(&warn_cmd); } } /* * In the usual case, we need at least 2 more arguments - * one (or more) value and a user name/id. * For setting defaults (-d) we don't want a user name/id. */ if (flags & DEFAULTS_FLAG) { if (argc != optind + 1) return command_usage(&warn_cmd); } else if (argc != optind + 2) { return command_usage(&warn_cmd); } value = atoi(argv[optind++]); name = (flags & DEFAULTS_FLAG) ? "0" : argv[optind++]; if (!mask) mask = FS_DQ_WARNS_MASK; if (!type) type = XFS_USER_QUOTA; switch (type) { case XFS_USER_QUOTA: set_user_warnings(name, type, mask, value); break; case XFS_GROUP_QUOTA: set_group_warnings(name, type, mask, value); break; case XFS_PROJ_QUOTA: set_project_warnings(name, type, mask, value); break; } return 0; } void edit_init(void) { limit_cmd.name = "limit"; limit_cmd.cfunc = limit_f; limit_cmd.argmin = 2; limit_cmd.argmax = -1; limit_cmd.args = \ _("[-gpu] bsoft|bhard|isoft|ihard|rtbsoft|rtbhard=N -d|id|name"); limit_cmd.oneline = _("modify quota limits"); limit_cmd.help = limit_help; restore_cmd.name = "restore"; restore_cmd.cfunc = restore_f; restore_cmd.argmin = 0; restore_cmd.argmax = -1; restore_cmd.args = _("[-gpu] [-f file]"); restore_cmd.oneline = _("restore quota limits from a backup file"); timer_cmd.name = "timer"; timer_cmd.cfunc = timer_f; timer_cmd.argmin = 2; timer_cmd.argmax = -1; timer_cmd.args = _("[-bir] [-gpu] value -d|id|name"); timer_cmd.oneline = _("get/set quota enforcement timeouts"); timer_cmd.help = timer_help; warn_cmd.name = "warn"; warn_cmd.cfunc = warn_f; warn_cmd.argmin = 2; warn_cmd.argmax = -1; warn_cmd.args = _("[-bir] [-gpu] value -d|id|name"); warn_cmd.oneline = _("get/set enforcement warning counter"); warn_cmd.help = warn_help; if (expert) { add_command(&limit_cmd); add_command(&restore_cmd); add_command(&timer_cmd); add_command(&warn_cmd); } } xfsprogs-3.1.9ubuntu2/quota/state.c0000664000000000000000000003213611650373061014240 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "init.h" #include "quota.h" static cmdinfo_t off_cmd; static cmdinfo_t state_cmd; static cmdinfo_t enable_cmd; static cmdinfo_t disable_cmd; static cmdinfo_t remove_cmd; static void off_help(void) { printf(_( "\n" " turn filesystem quota off, both accounting and enforcement\n" "\n" " Example:\n" " 'off -uv' (switch off user quota on the current filesystem)\n" " This command is the equivalent of the traditional quotaoff command,\n" " which disables quota completely on a mounted filesystem.\n" " Note that there is no 'on' command - for XFS filesystems (with the\n" " exception of the root filesystem on IRIX) quota can only be enabled\n" " at mount time, through the use of one of the quota mount options.\n" "\n" " The state command is useful for displaying the current state. Using\n" " the -v (verbose) option with the 'off' command will display the quota\n" " state for the affected filesystem once the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n")); } static void state_help(void) { printf(_( "\n" " query the state of quota on the current filesystem\n" "\n" " This is a verbose status command, reporting whether or not accounting\n" " and/or enforcement are enabled for a filesystem, which inodes are in\n" " use as the quota state inodes, and how many extents and blocks are\n" " presently being used to hold that information.\n" " The quota type is specified via -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n")); } static void enable_help(void) { printf(_( "\n" " enable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and has quota accounting enabled, but not\n" " quota enforcement, enforcement can be enabled with this command.\n" " With the -v (verbose) option, the status of the filesystem will be\n" " reported after the operation is complete.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n")); } static void disable_help(void) { printf(_( "\n" " disable quota enforcement on a filesystem\n" "\n" " If a filesystem is mounted and is currently enforcing quota, this\n" " provides a mechanism to switch off the enforcement, but continue to\n" " perform used space (and used inodes) accounting.\n" " The affected quota type is -g (groups), -p (projects) or -u (users).\n" "\n")); } static void remove_help(void) { printf(_( "\n" " remove any space being used by the quota subsystem\n" "\n" " Once quota has been switched 'off' on a filesystem, the space that\n" " was allocated to holding quota metadata can be freed via this command.\n" " The affected quota type is -g (groups), -p (projects) or -u (users)\n" " and defaults to user quota (multiple types can be specified).\n" "\n")); } static void state_qfilestat( FILE *fp, fs_path_t *mount, uint type, fs_qfilestat_t *qfs, int accounting, int enforcing) { fprintf(fp, _("%s quota state on %s (%s)\n"), type_to_string(type), mount->fs_dir, mount->fs_name); fprintf(fp, _(" Accounting: %s\n"), accounting ? _("ON") : _("OFF")); fprintf(fp, _(" Enforcement: %s\n"), enforcing ? _("ON") : _("OFF")); if (qfs->qfs_ino != (__u64) -1) fprintf(fp, _(" Inode: #%llu (%llu blocks, %lu extents)\n"), (unsigned long long)qfs->qfs_ino, (unsigned long long)qfs->qfs_nblks, (unsigned long)qfs->qfs_nextents); else fprintf(fp, _(" Inode: N/A\n")); } static void state_timelimit( FILE *fp, uint form, __uint32_t timelimit) { fprintf(fp, _("%s grace time: %s\n"), form_to_string(form), time_to_string(timelimit, VERBOSE_FLAG | ABSOLUTE_FLAG)); } static void state_quotafile_mount( FILE *fp, uint type, fs_path_t *mount, uint flags) { fs_quota_stat_t s; char *dev = mount->fs_name; if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)&s) < 0) { if (flags & VERBOSE_FLAG) fprintf(fp, _("%s quota are not enabled on %s\n"), type_to_string(type), dev); return; } if (type & XFS_USER_QUOTA) state_qfilestat(fp, mount, XFS_USER_QUOTA, &s.qs_uquota, s.qs_flags & XFS_QUOTA_UDQ_ACCT, s.qs_flags & XFS_QUOTA_UDQ_ENFD); if (type & XFS_GROUP_QUOTA) state_qfilestat(fp, mount, XFS_GROUP_QUOTA, &s.qs_gquota, s.qs_flags & XFS_QUOTA_GDQ_ACCT, s.qs_flags & XFS_QUOTA_GDQ_ENFD); if (type & XFS_PROJ_QUOTA) state_qfilestat(fp, mount, XFS_PROJ_QUOTA, &s.qs_gquota, s.qs_flags & XFS_QUOTA_PDQ_ACCT, s.qs_flags & XFS_QUOTA_PDQ_ENFD); state_timelimit(fp, XFS_BLOCK_QUOTA, s.qs_btimelimit); state_timelimit(fp, XFS_INODE_QUOTA, s.qs_itimelimit); state_timelimit(fp, XFS_RTBLOCK_QUOTA, s.qs_rtbtimelimit); } static void state_quotafile( FILE *fp, uint type, char *dir, uint flags) { fs_cursor_t cursor; fs_path_t *mount; fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor); while ((mount = fs_cursor_next_entry(&cursor))) state_quotafile_mount(fp, type, mount, flags); } static int state_f( int argc, char **argv) { FILE *fp = NULL; char *fname = NULL; int c, flags = 0, type = 0; while ((c = getopt(argc, argv, "af:gpuv")) != EOF) { switch (c) { case 'a': flags |= ALL_MOUNTS_FLAG; break; case 'f': fname = optarg; break; case 'g': type |= XFS_GROUP_QUOTA; break; case 'p': type |= XFS_PROJ_QUOTA; break; case 'u': type |= XFS_USER_QUOTA; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage(&state_cmd); } } if (argc != optind) return command_usage(&state_cmd); if ((fp = fopen_write_secure(fname)) == NULL) return 0; if (!type) type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA; if (flags & ALL_MOUNTS_FLAG) state_quotafile(fp, type, NULL, flags); else if (fs_path && fs_path->fs_flags & FS_MOUNT_POINT) state_quotafile(fp, type, fs_path->fs_dir, flags); if (fname) fclose(fp); return 0; } static void enable_enforcement( char *dir, uint type, uint qflags, uint flags) { fs_path_t *mount; mount = fs_table_lookup(dir, FS_MOUNT_POINT); if (!mount) { exitcode = 1; fprintf(stderr, "%s: unknown mount point %s\n", progname, dir); return; } dir = mount->fs_name; if (xfsquotactl(XFS_QUOTAON, dir, type, 0, (void *)&qflags) < 0) perror("XFS_QUOTAON"); else if (flags & VERBOSE_FLAG) state_quotafile_mount(stdout, type, mount, flags); } static void disable_enforcement( char *dir, uint type, uint qflags, uint flags) { fs_path_t *mount; mount = fs_table_lookup(dir, FS_MOUNT_POINT); if (!mount) { exitcode = 1; fprintf(stderr, "%s: unknown mount point %s\n", progname, dir); return; } dir = mount->fs_name; if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) perror("XFS_QUOTAOFF"); else if (flags & VERBOSE_FLAG) state_quotafile_mount(stdout, type, mount, flags); } static void quotaoff( char *dir, uint type, uint qflags, uint flags) { fs_path_t *mount; mount = fs_table_lookup(dir, FS_MOUNT_POINT); if (!mount) { exitcode = 1; fprintf(stderr, "%s: unknown mount point %s\n", progname, dir); return; } dir = mount->fs_name; if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) perror("XFS_QUOTAOFF"); else if (flags & VERBOSE_FLAG) state_quotafile_mount(stdout, type, mount, flags); } static int remove_qtype_extents( char *dir, uint type) { int error = 0; if ((error = xfsquotactl(XFS_QUOTARM, dir, type, 0, (void *)&type)) < 0) perror("XFS_QUOTARM"); return error; } static void remove_extents( char *dir, uint type, uint flags) { fs_path_t *mount; mount = fs_table_lookup(dir, FS_MOUNT_POINT); if (!mount) { exitcode = 1; fprintf(stderr, "%s: unknown mount point %s\n", progname, dir); return; } dir = mount->fs_name; if (type & XFS_USER_QUOTA) { if (remove_qtype_extents(dir, XFS_USER_QUOTA) < 0) return; } if (type & XFS_GROUP_QUOTA) { if (remove_qtype_extents(dir, XFS_GROUP_QUOTA) < 0) return; } else if (type & XFS_PROJ_QUOTA) { if (remove_qtype_extents(dir, XFS_PROJ_QUOTA) < 0) return; } if (flags & VERBOSE_FLAG) state_quotafile_mount(stdout, type, mount, flags); } static int enable_f( int argc, char **argv) { int c, flags = 0, qflags = 0, type = 0; while ((c = getopt(argc, argv, "gpuv")) != EOF) { switch (c) { case 'g': type |= XFS_GROUP_QUOTA; qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD; break; case 'p': type |= XFS_PROJ_QUOTA; qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD; break; case 'u': type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage(&enable_cmd); } } if (argc != optind) return command_usage(&enable_cmd); if (!type) { type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD; } if (fs_path->fs_flags & FS_MOUNT_POINT) enable_enforcement(fs_path->fs_dir, type, qflags, flags); return 0; } static int disable_f( int argc, char **argv) { int c, flags = 0, qflags = 0, type = 0; while ((c = getopt(argc, argv, "gpuv")) != EOF) { switch (c) { case 'g': type |= XFS_GROUP_QUOTA; qflags |= XFS_QUOTA_GDQ_ENFD; break; case 'p': type |= XFS_PROJ_QUOTA; qflags |= XFS_QUOTA_PDQ_ENFD; break; case 'u': type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ENFD; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage(&disable_cmd); } } if (argc != optind) return command_usage(&disable_cmd); if (!type) { type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ENFD; } if (fs_path->fs_flags & FS_MOUNT_POINT) disable_enforcement(fs_path->fs_dir, type, qflags, flags); return 0; } static int off_f( int argc, char **argv) { int c, flags = 0, qflags = 0, type = 0; while ((c = getopt(argc, argv, "gpuv")) != EOF) { switch (c) { case 'g': type |= XFS_GROUP_QUOTA; qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD; break; case 'p': type |= XFS_PROJ_QUOTA; qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD; break; case 'u': type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage(&off_cmd); } } if (argc != optind) return command_usage(&off_cmd); if (!type) { type |= XFS_USER_QUOTA; qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD; } if (fs_path->fs_flags & FS_MOUNT_POINT) quotaoff(fs_path->fs_dir, type, qflags, flags); return 0; } static int remove_f( int argc, char **argv) { int c, flags = 0, type = 0; while ((c = getopt(argc, argv, "gpuv")) != EOF) { switch (c) { case 'g': type |= XFS_GROUP_QUOTA; break; case 'p': type |= XFS_PROJ_QUOTA; break; case 'u': type |= XFS_USER_QUOTA; break; case 'v': flags |= VERBOSE_FLAG; break; default: return command_usage(&remove_cmd); } } if (argc != optind) return command_usage(&remove_cmd); if (!type) { type |= XFS_USER_QUOTA; } if (fs_path->fs_flags & FS_MOUNT_POINT) remove_extents(fs_path->fs_dir, type, flags); return 0; } void state_init(void) { off_cmd.name = "off"; off_cmd.cfunc = off_f; off_cmd.argmin = 0; off_cmd.argmax = -1; off_cmd.args = _("[-gpu] [-v]"); off_cmd.oneline = _("permanently switch quota off for a path"); off_cmd.help = off_help; state_cmd.name = "state"; state_cmd.cfunc = state_f; state_cmd.argmin = 0; state_cmd.argmax = -1; state_cmd.args = _("[-gpu] [-a] [-v] [-f file]"); state_cmd.oneline = _("get overall quota state information"); state_cmd.help = state_help; enable_cmd.name = "enable"; enable_cmd.cfunc = enable_f; enable_cmd.argmin = 0; enable_cmd.argmax = -1; enable_cmd.args = _("[-gpu] [-v]"); enable_cmd.oneline = _("enable quota enforcement"); enable_cmd.help = enable_help; disable_cmd.name = "disable"; disable_cmd.cfunc = disable_f; disable_cmd.argmin = 0; disable_cmd.argmax = -1; disable_cmd.args = _("[-gpu] [-v]"); disable_cmd.oneline = _("disable quota enforcement"); disable_cmd.help = disable_help; remove_cmd.name = "remove"; remove_cmd.cfunc = remove_f; remove_cmd.argmin = 0; remove_cmd.argmax = -1; remove_cmd.args = _("[-gpu] [-v]"); remove_cmd.oneline = _("remove quota extents from a filesystem"); remove_cmd.help = remove_help; if (expert) { add_command(&off_cmd); add_command(&state_cmd); add_command(&enable_cmd); add_command(&disable_cmd); add_command(&remove_cmd); } } xfsprogs-3.1.9ubuntu2/quota/quota.h0000664000000000000000000000526711140033220014243 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include /* * Different forms of XFS quota */ enum { XFS_BLOCK_QUOTA = 0x1, XFS_INODE_QUOTA = 0x2, XFS_RTBLOCK_QUOTA = 0x4, }; /* * System call definitions mapping to platform-specific quotactl */ extern int xfsquotactl(int __cmd, const char *__device, uint __type, uint __id, void * __addr); enum { XFS_QUOTAON, /* enable accounting/enforcement */ XFS_QUOTAOFF, /* disable accounting/enforcement */ XFS_GETQUOTA, /* get disk limits and usage */ XFS_SETQLIM, /* set disk limits */ XFS_GETQSTAT, /* get quota subsystem status */ XFS_QUOTARM, /* free disk space used by dquots */ XFS_QSYNC, /* flush delayed allocate space */ }; /* * Utility routines */ extern char *type_to_string(uint __type); extern char *form_to_string(uint __form); extern char *time_to_string(time_t __time, uint __flags); extern char *bbs_to_string(__uint64_t __v, char *__c, uint __size); extern char *num_to_string(__uint64_t __v, char *__c, uint __size); extern char *pct_to_string(__uint64_t __v, __uint64_t __t, char *__c, uint __s); extern FILE *fopen_write_secure(char *__filename); /* * Various utility routine flags */ enum { NO_HEADER_FLAG = 0x0001, /* don't print header */ VERBOSE_FLAG = 0x0002, /* increase verbosity */ HUMAN_FLAG = 0x0004, /* human-readable values */ QUOTA_FLAG = 0x0008, /* uid/gid/prid over-quota (soft) */ LIMIT_FLAG = 0x0010, /* uid/gid/prid over-limit (hard) */ ALL_MOUNTS_FLAG = 0x0020, /* iterate over every mounted xfs */ TERSE_FLAG = 0x0040, /* decrease verbosity */ HISTOGRAM_FLAG = 0x0080, /* histogram format output */ DEFAULTS_FLAG = 0x0100, /* use value as a default */ ABSOLUTE_FLAG = 0x0200, /* absolute time, not related to now */ NO_LOOKUP_FLAG = 0x0400, /* skip name lookups, just report ID */ }; /* * Identifier (uid/gid/prid) cache routines */ #define NMAX 32 extern char *uid_to_name(__uint32_t __uid); extern char *gid_to_name(__uint32_t __gid); extern char *prid_to_name(__uint32_t __prid); xfsprogs-3.1.9ubuntu2/quota/init.h0000664000000000000000000000207411140033220014046 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern char *progname; extern int exitcode; extern int expert; extern void edit_init(void); extern void free_init(void); extern void path_init(void); extern void project_init(void); extern void quot_init(void); extern void quota_init(void); extern void report_init(void); extern void state_init(void); extern void init_cvtnum(unsigned int *, unsigned int *); xfsprogs-3.1.9ubuntu2/quota/path.c0000664000000000000000000000643111604735741014061 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "init.h" #include "quota.h" static cmdinfo_t path_cmd; static cmdinfo_t print_cmd; static void printpath( struct fs_path *path, int index, int number, int braces) { fs_quota_stat_t qstat; fs_project_t *prj; int c; if (index == 0) { printf(_("%sFilesystem Pathname\n"), number ? _(" ") : ""); } if (number) { printf(_("%c%03d%c "), braces? '[':' ', index, braces? ']':' '); } printf(_("%-19s %s"), path->fs_dir, path->fs_name); if (path->fs_flags & FS_PROJECT_PATH) { prj = getprprid(path->fs_prid); printf(_(" (project %u"), path->fs_prid); if (prj) printf(_(", %s"), prj->pr_name); printf(")"); } else if (xfsquotactl(XFS_GETQSTAT, path->fs_name, 0, 0, (void *)&qstat) == 0 && qstat.qs_flags) { c = 0; printf(" ("); if (qstat.qs_flags & XFS_QUOTA_UDQ_ENFD) c = printf("%suquota", c ? ", " : ""); else if (qstat.qs_flags & XFS_QUOTA_UDQ_ACCT) c = printf("%suqnoenforce", c ? ", " : ""); if (qstat.qs_flags & XFS_QUOTA_GDQ_ENFD) c = printf("%sgquota", c ? ", " : ""); else if (qstat.qs_flags & XFS_QUOTA_GDQ_ACCT) c = printf("%sgqnoenforce", c ? ", " : ""); if (qstat.qs_flags & XFS_QUOTA_PDQ_ENFD) c = printf("%spquota", c ? ", " : ""); else if (qstat.qs_flags & XFS_QUOTA_PDQ_ACCT) c = printf("%spqnoenforce", c ? ", " : ""); printf(")"); } printf("\n"); } static int pathlist_f(void) { int i; for (i = 0; i < fs_count; i++) printpath(&fs_table[i], i, 1, &fs_table[i] == fs_path); return 0; } static int print_f( int argc, char **argv) { int i; for (i = 0; i < fs_count; i++) printpath(&fs_table[i], i, 0, 0); return 0; } static int path_f( int argc, char **argv) { int i; if (fs_count == 0) { printf(_("No paths are available\n")); return 0; } if (argc <= 1) return pathlist_f(); i = atoi(argv[1]); if (i < 0 || i >= fs_count) { printf(_("value %d is out of range (0-%d)\n"), i, fs_count-1); } else { fs_path = &fs_table[i]; pathlist_f(); } return 0; } void path_init(void) { path_cmd.name = "path"; path_cmd.altname = "paths"; path_cmd.args = _("[N]"); path_cmd.cfunc = path_f; path_cmd.argmin = 0; path_cmd.argmax = 1; path_cmd.flags = CMD_FLAG_GLOBAL; path_cmd.oneline = _("set current path, or show the list of paths"); print_cmd.name = "print"; print_cmd.altname = "p"; print_cmd.cfunc = print_f; print_cmd.argmin = 0; print_cmd.argmax = 0; print_cmd.flags = CMD_FLAG_GLOBAL; print_cmd.oneline = _("list known mount points and projects"); if (expert) add_command(&path_cmd); add_command(&print_cmd); } xfsprogs-3.1.9ubuntu2/quota/init.c0000664000000000000000000000605512062210562014056 0ustar /* * Copyright (c) 2003-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "init.h" char *progname; int exitcode; int expert; static char **projopts; /* table of project names (cmdline) */ static int nprojopts; /* number of entries in name table. */ static void add_project_opt( char *optarg) { nprojopts++; projopts = realloc(projopts, sizeof(char*) * nprojopts); if (!projopts) { perror("realloc"); exit(1); } projopts[nprojopts - 1] = optarg; } static void usage(void) { fprintf(stderr, _("Usage: %s [-p prog] [-c cmd]... [-d project]... [path]\n"), progname); exit(1); } void init_cvtnum( unsigned int *blocksize, unsigned int *sectsize) { *blocksize = 4096; *sectsize = 512; } static void init_commands(void) { edit_init(); free_init(); help_init(); path_init(); project_init(); quot_init(); quota_init(); quit_init(); report_init(); state_init(); } static int init_args_command( int index) { if (index >= fs_count) return 0; do { fs_path = &fs_table[index++]; } while ((fs_path->fs_flags & FS_PROJECT_PATH) && index < fs_count); if (fs_path->fs_flags & FS_PROJECT_PATH) return 0; if (index > fs_count) return 0; return index; } static void init( int argc, char **argv) { int c; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt(argc, argv, "c:d:D:P:p:t:xV")) != EOF) { switch (c) { case 'c': /* commands */ add_user_command(optarg); break; case 'd': add_project_opt(optarg); break; case 't': mtab_file = optarg; break; case 'D': projects_file = optarg; break; case 'P': projid_file = optarg; break; case 'p': progname = optarg; break; case 'x': expert++; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); default: usage(); } } fs_table_initialise(argc - optind, &argv[optind], nprojopts, projopts); free(projopts); init_commands(); add_args_command(init_args_command); /* * Ensure that global commands don't end up with an invalid path pointer * by setting the default device at the first specified on the CLI */ if (argc != optind) fs_path = fs_table_lookup(argv[optind], FS_MOUNT_POINT); else fs_path = &fs_table[0]; } int main( int argc, char **argv) { init(argc, argv); command_loop(); return exitcode; } xfsprogs-3.1.9ubuntu2/doc/0000775000000000000000000000000012062211564012360 5ustar xfsprogs-3.1.9ubuntu2/doc/COPYING0000664000000000000000000017313711140033220013412 0ustar The library named "libhandle" and some specific header files (including ) are licensed under the GNU Lesser General Public License. All other components are licensed under the GNU General Public License. ---------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ---------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ---------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ---------------------------------------------------------------------- xfsprogs-3.1.9ubuntu2/doc/Makefile0000664000000000000000000000110511330256617014022 0ustar # # Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LSRCFILES = INSTALL CHANGES COPYING CREDITS sparse.txt LDIRT = *.gz default: CHANGES.gz include $(BUILDRULES) CHANGES.gz: @echo " [ZIP] $@" $(Q)$(ZIP) --best -c < CHANGES > $@ install: default $(INSTALL) -m 755 -d $(PKG_DOC_DIR) $(INSTALL) -m 644 CHANGES.gz CREDITS $(PKG_DOC_DIR) ifeq ($(PKG_DISTRIBUTION), debian) $(INSTALL) -S CHANGES.gz $(PKG_DOC_DIR)/changelog.gz else $(INSTALL) -m 644 COPYING $(PKG_DOC_DIR) endif install-dev: xfsprogs-3.1.9ubuntu2/doc/INSTALL0000664000000000000000000001051411307015331013405 0ustar This document describes how to configure and build the open source XFS commands and utilites ("xfsprogs") from source, and how to install and run them. See the README file in the top level directory for details about how to contribute to the XFS project. Linux Instructions ================== 0. If you have the binary rpm, simply install it and skip to step 2 (below). The rpm command to do this is: # rpm -Uvh xfsprogs-*.rpm [and optionally, for the development libraries and headers] # rpm -Uvh xfsprogs-devel-*.rpm The Debian command to do this is: # apt-get install xfsprogs [and optionally, for the development libraries and headers] # apt-get install xfslibs-dev 1. Configure, build and install the package The xfsprogs package uses autoconf/configure and expects a GNU build environment (your platform must at least have both autoconf and gmake). You will also need to have installed either the e2fsprogs-devel package (on an RPM based system) or the uuid-dev package (on a Debian system) as some of the commands make use of the UUID library provided by these. To build the package and install it manually, use the following steps: # make # su root # make install [and optionally, for the development libraries and headers] # make install-dev Note that there are so many "install" variants out there that we wrote our own script (see "install-sh" in the top level directory). If you wish to turn off debugging asserts in the command build and turn on the optimizer then set the shell environment variables: OPTIMIZER=-O1 DEBUG=-DNDEBUG before running make or Makepkgs. Mac OS X Instructions ===================== 0. Note: since there is no XFS implementation on Mac OS X, you are severely limited in what you can do. mkfs.xfs(8), xfs_db(8) and xfs_repair(8) are the only functional tools on this platform, as they do not interact with the XFS kernel code at all. Still, it can be useful to have access to these utilities from Mac OS X in a dual boot configuration, for example. 1. Configure, build and install the package The xfsprogs package uses autoconf/configure and expects a GNU build environment (your platform must at least have both autoconf, make, and glibtool). You will also need to have built and installed the UUID library which is provided by the e2fsprogs source package. Building libuuid: [download; unzip/untar e2fsprogs; cd e2fsprogs] $ ./configure --prefix=/usr --mandir=/usr/share/man $ make lib/ext2fs/ext2_types.h $ cd lib/uuid $ make $ su root # make install [verify that you now have a /usr/lib/libuuid.a] Building xfsprogs: [firstly set these environment variables to these values] TAR=/usr/bin/gnutar LIBTOOL=/usr/bin/glibtool INSTALL_GROUP=wheel LOCAL_CONFIGURE_OPTIONS="--enable-gettext=no" $ make $ su root # make install [and optionally, for the development libraries and headers] # make install-dev IRIX Instructions ================= 0. Note: building this package on IRIX is mainly useful for the XFS developers who want to run purify on some of the tools. Most tools are not functional due to incomplete support for the syssgi and fcntl interfaces that XFS provides and which these tools make extensive use of. 1. Configure, build and install the package The xfsprogs package uses autoconf/configure and expects a GNU build environment which can be obtained by installing a number of freeware packages (gcc, autoconf, libtool, gmake). Even though IRIX provides a set of UUID functions via libc, you still need to have built and installed the UUID library which is provided by the e2fsprogs source package. This is because some difficult to resolve differences exist between the UUID functions and data types, which makes co-existence of these more trouble than its worth at the moment. Follow the instructions above for building and installing libuuid. Building xfsprogs: [firstly set these environment variables to these values] INSTALL_GROUP=sys CC=/usr/freeware/bin/gcc TAR=/usr/freeware/bin/tar MAKE=/usr/freeware/bin/gmake LIBTOOL=/usr/freeware/bin/libtool MSGFMT=/usr/freeware/bin/msgfmt MSGMERGE=/usr/freeware/bin/msgmerge XGETTEXT=/usr/freeware/bin/xgettext $ make $ su root # make install [and optionally, for the development libraries and headers] # make install-dev xfsprogs-3.1.9ubuntu2/doc/CREDITS0000664000000000000000000000376011140033220013371 0ustar This is a credits-file of people that have contributed to the Linux/XFS project. It is sorted by name and formatted to allow easy grepping and beautification by scripts (i.e. it follows the same format Linus has used in the kernel). The fields are: name (N), email (E), web-address (W), PGP key ID and fingerprint (P), description (D), and snail-mail address (S). ---------- N: Jens Axboe E: axboe@suse.de D: Block/elevator/kiobuf hacking, IDE kiobuf support S: Peter Bangs Vej 258, 2TH S: 2500 Valby S: Denmark N: Ethan Benson E: erbenson@alaska.net D: Additional inode flags (immutable, append-only, etc) S: P.O. Box 770525 S: Eagle River, AK 99577 S: Alaska N: Nicolas Boullis E: nboullis@debian.org D: fix XFS recovery on 64-bit big-endian architectures N: Danny Cox E: danscox@mindspring.com D: ACL port to Linux N: Thomas Graichen E: tgr@spoiled.org D: Original XFS FAQ maintainer D: PowerPC and Alpha porting S: Berlin, Germany N: Juergen Hasch E: hasch@t-online.de D: libacl fixes S: Meisenstr. 23, 73066 Uhingen, Germany N: Bill Jones E: jones@hpc.utexas.edu D: fsr port to Linux S: Austin, Texas, USA N: Jan Kara E: jack@atrey.karlin.mff.cuni.cz E: jack@suse.cz D: Quota 3.01 user tools, allowing different forms of quota to coexist D: Merging XFS support into quota user tools W: http://atrey.karlin.mff.cuni.cz/~jack/ S: Krosenska' 543 S: 181 00 Praha 8 S: Czech Republic N: Andi Kleen E: ak@muc.de D: Most recently, fine-tuning default mkfs/mount logsize/logbufs values S: Schwalbenstr. 96 S: 85551 Ottobrunn S: Germany N: Seth Mos E: seth@arosa.nl D: XFS FAQ ( http://oss.sgi.com/projects/xfs/faq.html ) maintainer W: http://iserv.nl/ S: Den Helder, The Netherlands N: Bart Samwel E: bart@samwel.tk W: http://www.xs4all.nl/~bsamwel/laptop_mode/ D: Laptop mode for XFS N: Robert Stickel E: previously: rstickel@connex.com D: libacl port to Linux N: John Trostel E: john.trostel@gtri.gatech.edu D: libacl extensions for Linux S: GTRI/EOEML, Georgia Institute of Technology, Atlanta, GA 30332, USA xfsprogs-3.1.9ubuntu2/doc/sparse.txt0000664000000000000000000000210311140033220014375 0ustar This document describes how to use the sparse source code checking tool to check the source code of the open source XFS commands and utilites ("xfsprogs"). First you need to install sparse, either from your distribution or from source as provided at http://www.kernel.org/pub/software/devel/sparse/. To simply build the xfsprogs source code while checking the source using sparse just set the compiler to cgcc, which is a wrapper that calls both sparse and gcc using: CC=cgcc ./configure Now that default warnings from sparse are a little bit verbose checking for various not that important things and also complaining about the glibc system headers. It does however not check for bitwise annotation which are very important for xfsprogs to verify the endianess handling of the on-disk structures is correct. To get a more reasonable set of warnings build xfsprogs using: LCFLAGS="-Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl" make You are of course free to experiment with the warnings flags documented in the sparse manpage to check xfsprogs for other issues. xfsprogs-3.1.9ubuntu2/doc/CHANGES0000664000000000000000000017361412062210562013364 0ustar xfsprogs-3.1.9 (31 October 2012) - Print nice details if agsize is out of bounds in mkfs.xfs. - Various fixes for fragmented multi-block dir2 handling in xfs_repair. - Fix extent record printing in xfs_db on big endian arches. - Use the correct macros when dumping block maps in extent form in xfs_db, thanks to Peter Watkins. - Add sync file range support to xfs_io. - Implement preadv/pwritev in xfs_io. - Link against libreadline for libxcmd, thanks to Mike Frysinger. - Clean up mkfs.xfs output on invalid inode size. - Various build fixes, thanks to Mike Frysinger and Jan Engelhardt. xfsprogs-3.1.8 (20 March 2012) - Fix xfs_repair segfault on a corrupted filesystem by validating the acl count before reading it. - Avoid xfs_repair deadlocks on prefetched buffers. - Fix various incorrect printf formats, thanks to Jakub Bogusz for reporting. - Polish translation update, thanks to Jakub Bogusz. - Refuse mkfs.xfs on misaligned devices when using 4k sectors, unless the -f option is specified, and then force 512b sector size, thanks to Carlos Maiolino. - Avoid a possible loop on the unlinked inode list in phase 3 of xfs_repair, thanks to Stefan Pfetzing for reporting. - Allocate inode and free extent records individually in xfs_repair. - Fix a possible deadlock btree nodes in xfs_repair by using recursive locking, thanks to Arkadiusz Miśkiewicz for reporting and testing. - Fix possible xfs_repair deadlocks in inode prefetching, thanks to Arkadiusz Miśkiewicz for reporting and testing. - Make xfs_repair handle filesystems with the log in ag 0, thanks to Sindre Skogen for reporting. - Deprecate the -F foreign flag to xfs_io. - Add debian linux-libc-dev build dependancy. - Add an extended fiemap configure check. - Various cleanups in xfs_repair. - Update xfs_check man page to recommend xfs_repair over xfs_check, thanks to Arkadiusz Miśkiewicz. - Update the on-disk extent count as part of inode repair when moving inodes to lost+found to avoid to avoid tripping over a check in xfs_iformat, thanks to Arkadiusz Miśkiewicz for reporting and testing. - Check for size parsing errors in xfs_quota, thanks to James Lawrie for reporting. - Fix fiemap loop continuation in xfs_io. - Make mkfs.xfs properly handle physical sector size. - Fix /proc/mounts parsing in xfs_fsr. - Fix xfs_repair when ag_stride options with attributes and dirv1 code, thanks to Tom Crane for reporting and testing. - Fix message formats in process_dinode_int. - Fix xfs_repair handling of link counts when the on-disk count overflows 8 bits. - Fix messages from set_nlinks in xfs_repair. xfsprogs-3.1.7 (17 November 2011) - Pull in fix for debian/control - Polish translation update, thanks to Jakub Bogusz - Fix xfs_repair link count on lost+found, thanks to Carlos Maiolino - Fix various incorrect printf formats xfsprogs-3.1.6 (14 October 2011) - Re-synch of the header and libxfs files with the kernel code as of Linux 2.6.37, including reviving xfs_repair radix tree code. - Fix a xfs_repair phase 4 hang, thanks to Ajeet Yadav. - Subcommand names within various programs are no longer translated/localized, thanks to Arkadiusz Mi?kiewicz. - Build system fixes, thanks to Ted Ts'o. - Updates to teh xfs_info(8)/xfs_growfs(8) man page, thanks to Roman Ovchinnikov. - xfs_quota "df" no longer reports values twice what they should have been for project quotas. - mkfs.xfs now requires that sub-options are non-empty strings; thanks to Chris Pearson for reporting. - Better handling of short reads in libxfs. - xfs_quota now prints "N/A" rather than a large number for the quota file inode number for disabled quota types. - Bogus (unrelated) mount point entries no longer cause xfs_growfs, xfs_quota, and xfs_io to quit early. - xfs_repair no longer fails when the sector size of an underlying device is larger than the sector size in a hosted filesystem image. - Various other internal improvements, including refactoring and eliminating more build warnings. xfsprogs-3.1.5 (30 March 2011) - Polish translation update, thanks to Jakub Bogusz - xfs_repair now warns if running in low memory mode - Phase 2 of xfs_repair is now multithreaded - xfs_quota no longer attempts to get quota information if not enabled - Inode flags are now properly validated by xfs_repair - Metadump now obfuscates all file names reliably - xfs_io now supports the "fiemap" command, a more generic form of the "bmap" command - xfs_io now supports the "fpunch" command, as well as a "-p" flag to the "fallocate command. Both implement hole punching. Thanks to Josef Bacik - A number of other bug fixes thanks to Ajeet Yadav xfsprogs-3.1.4 (9 November 2010) - Add projid32bit handling to userspace, resolving type sizing issues when dealing with 32 bit project ids. - Make xfs_fsr use /proc/mounts if available. - Annotate that Debian packages are group maintained. - Fix a Debian packaging issue causing upgrade pain. xfsprogs-3.1.3 (26 August 2010) - Add xfs_io support for XFS_IOC_ZERO_RANGE - Fix depend targets. - Allow xfs_io resvsp command for foreign filesystems. - Fix configure --prefix. - Make xfs_db check for valid inode data pointer before dereferencing. - Validate btree block magic in the xfs_db freesp command, thanks to Peter Watkins. - Unbreak make update-po, permissions problem, thanks to Arkadiusz Miśkiewicz. - Fix linking of libxfs and librt detection (needs pthread), thanks to Arkadiusz Miśkiewicz. - Add a platform_discard_blocks stub for GNU/kFreebsd. xfsprogs-3.1.2 (6 May 2010) - Fix missing thread synchronization in xfs_repair duplicate extent tracking. - Fix handling of dynamic attribute fork roots in xfs_fsr. - Fix sb_bad_features2 manipulations when tweaking the lazy count flag. - Add support for building on Debian GNU/kFreeBSD, thanks to Petr Salinger. - Improvements to the mkfs.xfs manpage, thanks to Wengang Wang. - Various small blkid integration fixes in mkfs.xfs. - Fix build against stricter system headers. xfsprogs-3.1.1 (29 January 2010) - Fix various blkid topology support problems in mkfs.xfs. - Fix various build warnings. - Add automatic build dependency calculations. - Cleaner build system output. - Add missing aclocal m4 file to the package generation. - Arrange for release tags to be digitally signed. xfsprogs-3.1.0 (13 January 2010) - Reduce memory usage in xfs_repair by using better data structures. - Add additional checks in xfs_repair to detect freespace btree corruption instead of only rebuilding the btrees. Useful for the no-modify mode. - Fix libhandle to use the right path to issue by-handle ioctls for symbolic links and special files. - Use lazy superblock counters by default. At least kernel 2.6.22 is needed for this feature. - Use physical device sector size if available in mkfs.xfs, so 4K sector devices are handed more gracefully. - Add a German translation, thanks to Chris Leick. - Enable the madvise and mincor commands in xfs_io. - Fix unsafe temporary file creation in xfs_fsr. - Add support for discarding unused space on SSDs or thin provisioned arrays in mkfs.xfs. - Allow linking against libblkid for topology information. - Add symbol versioning for libhandle. - Remove the included RPM and binary tarball built infrastructure. - Various build system improvements. - Small fixes to xfs_db and xfs_io. xfsprogs-3.0.4 (17 September 2009) - Fix a memory leak in xfsprogs. - Increase hash chain length in xfsprogs when running out of memory. - Fix dmsetup invocation in libdisk to avoid warnings during mkfs on multipath devices. - Fix the -V option to various installed tools. - Small internal fixes to please the clang semantical analysis tool. - Debian packaging updates. - Rework Makepkgs and Makefiles to improve deb generation. xfsprogs-3.0.3 (30 August 2009) - Fix unaligned accesses in libxfs. - Various small fixes to xfs_db, xfs_repair and xfs_io. - Add fallocate command to xfs_io. - Enable readline support in xfs_io and xfs_quota. - Allow log sizes up to 2GiB (minus 1 byte) in xfs_mkfs. - Open the block device in xfs_repair exclusively, thanks to Nathaniel W. Turner. xfsprogs-3.0.2 (6 May 2009) - Updates to Debian build process after recent autoconf tweaks. - Fix a couple of minor man page syntax issues. xfsprogs-3.0.1 (4 May 2009) - Update the Makepkgs script to generate proper source tarballs. - New project(5) and projid(5) man pages. - Fix extent array reallocation in the xfs_io bmap command, thanks to Tomasz Majkowski. - Small specfile improvements, thanks to Jan Engelhardt. - Allow xfs_freeze to freeze non-XFS filesystems. - Fix the xfs_db bmbta command. - Fix parallel builds, thanks to Mike Frysinger. - Various autoconf/libtool fixes, thanks to Andreas Gruenbacher. xfsprogs-3.0.0 (4 February 2009) - Various smaller xfs_repair improvements. - Various gettext improvements, thanks to Jakub Bogusz. - Polish translation update, thanks to Jakub Bogusz. - Various xfs_quota fixes, thanks to Arkadiusz Miskiewicz. - Support parallel builds. - Detection of btrfs, gfs and gfs2 in libdisk. - Addition of the xfs_fsr and xfs_estimate tools previous found in the xfsdump package. - Resync libxfs to latest kernel implemenation. - Update all of xfsprogs to latest kernel interfaces. - Add sparse support to xfsprogs build. - Cleanup devel package for xfsctl, libhandle and libdisk only (remove libxfs interfaces). xfsprogs-2.10.1 (5 September 2008) - Improve xfs_repair -P option to disable xfs_buf_t locking. - Fix inode cluster I/O size for > 8KB block size filesystems. - Fix up ASCII CI output for mkfs.xfs and xfs_growfs. - Fix buffer handling in error cases in xfs_db (includes xfs_check and xfs_metadump). - Add packed on-disk shortform directory for ARM's old ABI, thanks to Eric Sandeen. - Increase default valid block count for a directory extent in xfs_metadump (from 20 to 1000). - Fix up mkfs.xfs -N option with "-d file" so it doesn't resize the target file (thanks to Michal Marek). - Improve libxfs cache handling with (un)referenced blocks. - Check that directory size is not too big in xfs_repair. - Improve xfs_repair to restore bad or missing ".." entries. xfsprogs-2.10.0 (26 May 2008) - Add ASCII case-insensitive support to xfsprogs. xfsprogs-2.9.8 (21 April 2008) - Add support for sb_features2 in wrong location in mkfs.xfs, xfs_repair and xfs_db. - Improve memory limits for libxfs cache in xfs_repair and added a -m option to manually limit usage of xfs_repair. - Add -c option to xfs_admin to turn lazy-counters on/off. - Added support for mdp in libdisk/mkfs.xfs, thanks to Hubert Verstraete. - Add -p option to fsck.xfs, thanks to Markus Rothe. - Cleanup sys v3 bzero/bcopy calls, thanks to Nigel Kukard. xfsprogs-2.9.7 (1 Mar 2008) - Lazy superblock counters not yet the default with mkfs.xfs. - Add -y (another no-op) fsck option. - Resolve mkfs allocation group count issue with small devices. - Fix mkfs to sector align the device size so zeroing the end of the device doesn't fail. xfsprogs-2.9.6 (7 Feb 2008) - Fix regression introduced by changing the mkfs.xfs defaults. - Made lazy superblock counters the default with mkfs.xfs. xfsprogs-2.9.5 (21 Jan 2008) - Updated mkfs.xfs defaults. - Make xfs_info handle mount points with spaces. - Improve xfs_repair's handling of invalid freespace btree extents. - Rebuild directories in xfs_repair if "." and ".." aren't the first two directory entries. This guarantees a directory is deletable. - Changed mkfs.xfs -f to wipe all old AG headers, not just the ones up to the end of the new filesystem size. - Purged the end of device whack buffer in mkfs.xfs to prevent a warning in certain device sizes. - Man page fixes. Thanks to Utako Kusaka for this. - Disable the ability to turn off unwritten extents in mkfs. xfsprogs-2.9.4 (7 Sep 2007) - Fixed xfs_repair segfaulting with directory block size different to the filesystem blocksize. - Fixed xfs_quota disable, enable, off and remove commands. Thanks to Utako Kusaka for this. - Improved the robustness of xfs_metadump. - Fix link issues with pthread library. xfsprogs-2.9.3 (23 July 2007) - Make xfs_repair support > 512 byte sector sizes. - Fixed include Makefile for new common header (xfs_metadump.h). - Fixed xfs_quota state command segfaulting with no mounted XFS filesystems. - Fixed xfs_quota printing out unusual message with "path n" command with no mounted XFS filesystems. - Fixed "quota -n" command with project IDs. - Improved "free" output when project quotas are defined, but haven't been enable on the filesystem. Thanks to Utako Kusaka for the above four fixes. xfsprogs-2.9.2 (18 July 2007) - Next major round of xfs_repair performance improvements: - Cache disk nlink values in Phase 3 for Phase 7. - Do multithreaded prefetch/processing based on AG stride option (ie. for concats). - Don't trash lost+found at the start of Phase 4, eliminates repeated "moving disconnected inode to lost+found" with successive xfs_repair runs. - Do multi-threaded sequential metadata prefetch. Method based on Agami patches posted for 2.7.18 xfsprogs. - Improve the libxfs cache with priority tagging to keep blocks around that have unfavourable I/O characteristics. - Make mkfs.xfs -f zero the old secondary superblocks before writing the new superblocks. - Fix up xfs_info and xfs_quota's -c handling with global commands. - Improve xfs_bmap -vp output to always show the FLAGS column. - Update man pages. xfsprogs-2.9.1 (28 June 2007) - Added filestreams support to xfs_io. - Fix up libattr Makefile to append to LTLDFLAGS. Thanks to Arfrever Frehtes Taifersar Arahesis for this. - Fix up build not to ignore LDFLAGS generated by configure. Thanks to SpanKY for this. xfsprogs-2.9.0 (5 June 2007) - Added new tools: xfs_metadump and xfs_mdrestore. - Fix up the HAVE___U32 fix from 2.8.20 Thanks to Eric Sandeen for pointing this out. xfsprogs-2.8.21 (28 May 2007) - Add support for lazy superblock counters in mkfs.xfs, xfs_db, xfs_repair, xfs_growfs and also libxfs. - Fix xfs_quota project command to stop it operating on special files. Thanks to Leo Baltus. xfsprogs-2.8.20 (23 February 2007) - Fix xfs_repair not detecting invalid btree root in inodes. - Fix xfs_repair restoring corrupted superblock after repairing it. - Fix xfs_repair crashing on invalid quota inode values. - Fix xfs_quota gracetime reporting. Thanks to Utako Kusaka for this. - Fix libxfs IO_DEBUG output. - Instead of using AC_CHECK_TYPES which isn't supported for older versions of autoconf, add our own type check in the m4/package_types.m4 file for __u32. Suggested by Nathan Scott and discovered by wookey@aleph1.co.uk. xfsprogs-2.8.19 (31 January 2007) - Fix pthread stack size setting in xfs_repair. - Fix xfs_bmap -n option displaying a truncated extent. - Fix xfs_io mwrite segfault. Thanks to Utako Kusaka for these two fixes. - Fix errors in xfs_quota(8) man page. xfsprogs-2.8.18 (8 December 2006) - is an installed file, we cannot simply rename it, as other applications using it (accidentally or not) may break. The xfs_list.h name was inconsistent with everything else too. - Fix "pointer targets in assignment differ in signedness" warnings - Update Debian packaging. - Fix up two issues with xfs_db and bmap. If the data/attr fork is local, it either infinite loops or crashes. If both are displayed, the attrs are wrong. - Fix up xfs_io mmap read that read from the wrong offset. - Updated xfs_io man page. Thanks to Utako Kusaka for the above three fixes. xfsprogs-2.8.17 (5 December 2006) - Fix up libxfs SEGV when attempting to mount a non-XFS filesystem. Thanks to Utako Kusaka for this. - Fix up xfs_repair aborting if it finds an inode with an invalid inode type. - Fix up default realtime extent size for large block sizes. - Rename include/list.h to xfs_list.h so that other applications do not accidentally use it. xfsprogs-2.8.16 (30 October 2006) - Fix up an endian problem for nlink setting in phase 7 for xfs_repair. xfsprogs-2.8.15 (19 October 2006) - Fix up nlink checks and repairs in phase 7 for xfs_repair. - Remove a bogus LEAFN warning for a single leaf node v2 dir. Thanks to Roger Willcocks for this. xfsprogs-2.8.14 (6 October 2006) - Fix up the ring command in xfs_db, Thanks to Utako Kusaka for this. - Set the blocksize on the device to the given sector size which is _not_ necessarily 512 bytes; idea suggested by Shailendra Tripathi. - Fix up xfs_copy and its variable argument handling around vfprintf; xfs_copy was seg faulting on x86_64. xfsprogs-2.8.13 (21 September 2006) - Fix v2 directory checking with holes and unreadable blocks. - Fix a memory leak in dir2 checking. - Update libdisk/md support to work out the stripe width based on (# raid-disks - # parity disks) which doesn't include any spare disks (which we mistakenly did before). Thanks to Shailendra Tripathi's suggestions. - Get the kernel int types of __u32 and friends from if we can, otherwise define them ourselves. xfsprogs-2.8.12 (29 August 2006) - Multi-thread modifications to xfs_repair. - Updated Polish translation, thanks to Jakub Bogusz. - Change default mkfs realtime extent size setting to perform better for buffered writes. xfsprogs-2.8.11 (08 August 2006) - xfs_repair prefetch optimisations. - Make many tools use direct I/O on Linux if the underlying device supports it. Mainly for speeding up xfs_repair as libxfs does its own internal metadata buffering now. - Fix warnings from mkfs.xfs on ramdisk devices. - Fix issues with symbolic link handling in Makefiles. xfsprogs-2.8.10 (02 August 2006) - Fix v2 directory rebuilds in phase6 of xfs_repair. - Fix buffer sizing issue for large pagesize systems, affecting mkfs auto-device-type-detection heuristics. xfsprogs-2.8.9 (18 July 2006) - Fix rpm issue with install targets as uid/gid zero (we now using symbolic names rather than the numeric versions). xfsprogs-2.8.8 (14 July 2006) - Fix issues with makedepend on libtool libraries. xfsprogs-2.8.7 (10 July 2006) - Fix build of xfs_logprint for different uuid_t definitions; thanks to Craig Rodrigues. xfsprogs-2.8.6 (07 July 2006) - Fixed xfs_repair handling of duplicate names in a directory. xfsprogs-2.8.5 (05 July 2006) - Update translation Makefile to work better with the Ubuntu translation system. Thanks to feedback from Martin Pitt. - Fix annoying "ignores datarootdir" warning from configure. - Fix issues with makedepend build infrastructure. - Add prefetch code for improved xfs_repair run times. xfsprogs-2.8.4 (23 June 2006) - Improve Debian udeb package handling, thanks to Frans Pop. - Fix a situation where xfs_growfs can fail to match a block device to a filesystem correctly; thanks to Bastian Kleineidam. - Minor corrections to the xfs_growfs man page. xfsprogs-2.8.3 (21 June 2006) - Fix a possible segv in xfs_growfs; thanks to Bastian Kleineidam. xfsprogs-2.8.2 (17 June 2006) - More updates to repair/libxfs for improving performance - Incorporate librt into the build process for lio_listio - Minor xfs_logprint tweaks and fixes. - Small updates to xfs_io manual page. - Several fixes from earler 2.8 releases with respect to inode/buffer cache refcounting. xfsprogs-2.8.1 (29 May 2006) - Fix endianness issues on FreeBSD. xfsprogs-2.8.0 (18 May 2006) - Initial pass at user space caching, ultimately provides a starting point for a faster, parallel version of repair. - Fix several inode/buffer reference counting issues. - Fix compiler warnings, and builds on certain glibc versions having issues with the device major() macro. - Added code to xfs_db and xfs_admin to allow conversion from version 1 to version 2 logs. xfsprogs-2.7.18 (16 May 2006) - Fixed a case where xfs_repair was reporting a valid used block as a duplicate during phase 4. - Fixed a case where xfs_repair could incorrectly flag extent b+tree nodes as corrupt. - Portability changes, get xfs_repair compiling on IRIX. - Parent pointer updates in xfs_io checker command. - Allow LDFLAGS to be overridden, for Gentoo punters. xfsprogs-2.7.17 (05 April 2006) - Fix libxfs access(2) check on /proc/mounts, which was causing issues when xfs_check/xfs_repair run on readonly root filesystem mounts. - Fix Debian packaging for libc-dev build dependency. - Fix up auto lib64 install detection for x86_64 platforms. xfsprogs-2.7.16 (22 March 2006) - Fix freespace accounting in xfs_quota(8) df command. - Fix a typo on the xfs_quota(8) man page. - Make -O2 (cc optimisation level) the default. xfsprogs-2.7.15 (03 March 2006) - Fix the way external log/realtime devices were handled in userspace with older kernels (subtely different in procfs) - Fix a corruption problem in xfs_copy(8) when attempting to zero the (old) log, a section was sometimes missed (depends on log and I/O buffer (mis)alignment). xfsprogs-2.7.14 (15 February 2006) - Debian packaging updates (debmake out, debhelper in). - Fix a header to work with additional compiler variants. xfsprogs-2.7.13 (08 February 2006) - Convert fsck into a shell script and make it provide a hint to run repair/check (in non-auto fsck modes). Thanks to Marian Jancar for this. - Fix compilation botch on non-Linux platforms (duplicate type definitions). xfsprogs-2.7.12 (31 January 2006) - Added initial Polish translation. Thanks to Jakub Bogusz for this. - Fixed rpm specfile with respect to INSTALL_{USER,GROUP}. xfsprogs-2.7.11 (16 January 2006) - Fix a problem with the generated source tarballs and a missing parent.h header file. xfsprogs-2.7.10 (16 December 2005) - Make xfs_db keep trying when root inode can't be read. - Make xfs_db check AGF BNO and CNT btree consistency. - Tweak a couple of libxfs headers so they can be used by C++ programs (removes nested struct declarations, which are used outside the scope they're declared in). - Fix a rounding issue in xfs_quota time reporting, making it more consistent with the standard quota utilities. - Fix dopey libxfs message "Unmount and run xfs_repair.", especially annoying when printed by xfs_repair itself. - Fix a dir2 xfs_repair bug, misdiagnosing a valid dir as corrupt. Thanks to Masanori Tsuda. xfsprogs-2.7.9 (08 December 2005) - Fix thinko in libxcmd cvtnum routine - Fix EFI/EFD printing in xfs_logprint xfsprogs-2.7.8 (05 December 2005) - Extend xfs_io to do aligned direct IO automatically - Report direct IO parameters (dioinfo) in xfs_io - Make xfs_mkfile a shell script wrapper around xfs_io xfsprogs-2.7.7 (16 November 2005) - Fix some gcc compiler warnings on 64 bit platforms. - Remove last reference to a (kernel) header. - Updated aclocal.m4 - Fix a bug in xfs_io lsproj/chproj recursive modes. - Add xfs_io recursive modes for the extsize command. - Add xfs_db version command modes for attr1 and attr2. xfsprogs-2.7.6 (31 October 2005) - Add support for the inode extent size hint for the regular data device (previously was realtime only), and allow the optional inheritance of this property. - Add support for additional read/write patterns in xfs_io (reverse and random, in addition to sequential forwards). - Add some mkfs debugging options to aid testing inheritance of realtime, project ID, and extsize inode attributes. - Add mkfs option for forcing use of ATTR2, and make growfs report its use. - Fix use of cursor in attr_list_by_handle() libhandle code. - Fix several compiler warnings when building on IRIX. xfsprogs-2.7.5 (26 October 2005) - Fix an endian bug in xfs_db "frag" command. - Fix some errors on the xfs_quota(8) man page. xfsprogs-2.7.4 (08 October 2005) - Fix read and write calls in xfs_io to allow buffers larger than 4GiB on 64 bit platforms. - FreeBSD build tweaks from Craig Rodrigues. - Fixed a few minor compiler warnings. xfsprogs-2.7.3 (29 September 2005) - Fix xfs_repair handling of the morebits bit. - Merge back several kernel changes related to attr2. - Extended xfs_db expert mode commands - Clean up some fsxattr uses to reduce number of syscalls, now that IRIX also supports project identifiers via this interface. xfsprogs-2.7.2 (28 September 2005) - Fix up xfs_repair segmentation fault due to wrong allocation size. xfsprogs-2.7.1 (20 September 2005) - Fix up reporting of devices in xfs_growfs - now uses /proc/mounts in preference to /etc/mtab. - Fix a strtok-related bug in the extraction of device names, also only affecting xfs_growfs. xfsprogs-2.7.0 (16 September 2005) - Support for updated extended attributes format (attr2) - Make xfs_quota tool issue a quota sync in all the needed places, before reporting, to counter affects of delayed allocation. - Quota-related ID signedness issue fixes. - Expert mode xfs_db commands to set/remove attributes. xfsprogs-2.6.37 (11 August 2005) - Fix FreeBSD builds (getmntinfo), thanks to Craig Rodrigues. xfsprogs-2.6.36 (28 July 2005) - Fix mkfs stripe unit alignment checks for external logs - Fix running xfs_db on non-XFS devices (was segfaulting) - Fix a 32 bit wrap in xfs_repair searching for secondary superblocks. xfsprogs-2.6.35 (01 July 2005) - Add back fd_to_handle() to libhandle. - Add handle call mappings to xfsctl() for IRIX. xfsprogs-2.6.34 (20 June 2005) - Switch to the fsxattr xfsctl for getting/setting project identifiers on inodes, remove the short-lived specialised ioctls for doing this. - Make the "blocktrash" xfs_db command available in expert- mode only. xfsprogs-2.6.33 (13 June 2005) - Another libhandle fix on 64bit, Big Endian systems. xfsprogs-2.6.32 (08 June 2005) - Minor endian cleanups in some tools. - Fix a couple of xfs_quota double-reporting issues when issuing commands via the -c (command line) 0option. xfsprogs-2.6.31 (06 June 2005) - Fix previous MD driver-specific change to correctly handle (i.e. not "stripe align") linear arrays. - Add MD RAID level 4, 6, and 10 support. - Make mkfs.xfs automatically adjiust the geometry to use a sector size that matches the block size when MD RAID level 4/5/6 are in use. - Couple of minor man page fixups, including patch botch on initial revision of xfs_quota(8). xfsprogs-2.6.30 (03 June 2005) - Add xfs_quota(8) command which knows how to do all things quota related, and can also do the XFS specific extensions like project quota, realtime device quota, etc. - Created a library of common code (libxcmd.a) shared by xfs_growfs, xfs_io and xfs_quota. - Fix use of regular files for realtime subvolumes (debugging only, really). - Fix bug in xfs_io command line option handling when commands where specified for multiple files at once. - Allow xfs_io to specify O_NONBLOCK for regular file IO. - Fix MD driver-specific code to not attempt stripe alignment for volumes that are not stripes (e.g. concat/mirror). xfsprogs-2.6.29 (19 April 2005) - Fix mkfs.xfs -dfile. - Fix libhandle on 64bit, Big Endian systems. xfsprogs-2.6.28 (30 March 2005) - Fix compiler warning in repair/dir.c size checks. - Fix more compilation problem with version 4 of gcc (thanks to Andreas Jochens). - Make xfs_db and xfs_repair cope with filesystems that have project quota enabled. xfsprogs-2.6.27 (23 March 2005) - Fix default mkfs allocation group size calculations for filesystem sizes in the range 32 - 64 terabytes. - Add noalign mkfs suboptions for -d/-r to disable the sunit/swidth auto-alignment (based on logical volume geometry, extracted from the driver). xfsprogs-2.6.26 (08 March 2005) - Fix compilation problem with version 4 of gcc (thanks to Andreas Jochens). - Added a streamlined for programs wanting to make use of the XFS-specific kernel interfaces (to address complaints that was "heavy"). - Add imap as an expert command in xfs_io, making it more easily accessible to those who need it. - Extended statistics reporting for xfs_io command. - Fixed readline support for current distributions. - Add an --enable-termcap=[yes/no] configure option, and changed --enable-readline=[yes/no] to not force linking with libtermcap. Builds on some platforms may need to use both options, but most distributions do not require --enable-termcap when linking against libreadline. - Minor man page updates. xfsprogs-2.6.25 (08 October 2004) - Fix build with really old glibc versions. xfsprogs-2.6.24 (29 September 2004) - Allow 'e' suffix in size arguments to mkfs. - Update mkfs man page description of maximum allocation group size. - Update mkfs and xfs_db man pages to use consistent, standard notations. - Sync up user/kernel source in libxfs and headers. xfsprogs-2.6.23 (17 September 2004) - Fix xfs_io pread/pwrite -b option, when used more than once we would use the largest of the previous values, instead of the (possibly smaller) value specified. - Add recursive modes to lsattr/chattr xfs_io commands. - Make xfs_io run any given command line commands (-c) on all files specified, not just the first. xfsprogs-2.6.22 (10 September 2004) - Update xfs_io to get a clean compile on IRIX with the MIPSPro compilers. - Add documentation about additional XFS inode flags. - Add xfs_io write options to include fsync/fdatasync in the timing results it displays. - Add xfs_fsop_counts output to the xfs_io statfs data, which also shows free realtime space, etc. - Add knowledge of additional inode flags for nosymlinks and project ID inheritance. xfsprogs-2.6.21 (09 August 2004) - Support realtime bit inheritance on directories. - Fix xfs_io build with unusual (old) glibc versions. - Fix tools to not issue the BLKFLSBUF ioctl to ramdisk devices. Thanks to Bo Yang for this fix. xfsprogs-2.6.20 (28 July 2004) - Fix a segfault on xfs_io open error path for non-XFS files. Thanks to Steinar H. Gunderson for this fix. xfsprogs-2.6.19 (16 July 2004) - Fix two byte count size wraps in xfs_copy. - Minor man page fixes from Eric Raymond. xfsprogs-2.6.18 (23 June 2004) - Fix libhandle from possibly returning an invalid handle length on systems where size_t is 64 bits. - Minor autoconf fixups to get rpm test working on all platforms again. - Minor man page updates fixing minus/hyphen usage. xfsprogs-2.6.17 (23 June 2004) - Fix use of isset macro, getting realtime devices to function correctly in xfs_db and xfs_repair. - Fix initialisation of realtime devices in libxfs. xfsprogs-2.6.16 (17 June 2004) - Add sendfile command into xfs_io(8) to exercise that functionality. - Remove maxtrres program that was used in the build to generate a header for mkfs' consumption. - This allows cross-compiles to be greatly simplified. - Portability tweaks for building on other platforms. - Fix obscure bug in log size lower boundary checks for auto-sized logs when stripe alignment is in effect; the enforced lower bound could have been set too low. xfsprogs-2.6.15 (09 June 2004) - Make xfs_check test for a dirty log before proceeding to check the filesystem. - Fix couple of minor bugs in xfs_io (readonly handling on writes, off-by-one error in open file error reporting). xfsprogs-2.6.14 (13 May 2004) - Allow logprint to copy a log to a file (-C) and to dump a log from beginning to end showing ondisk log record (-d). - Fix logprint handling of -f option - shouldn't be doing the UUID check in that case, since we don't have the SB. - Remove MD device superblock "clean" check, following Neil Brown's advice. - Small Debian packaging tweak to say xfsprogs has an fsck. xfsprogs-2.6.13 (03 May 2004) - Zero out more at beginning and end of device at mkfs time (get all old MD superblocks at the end, for mount by label). xfsprogs-2.6.12 (30 April 2004) - Extract stripe unit/width from device mapper devices (added libdisk infrastructure, used by mkfs.xfs). - Fix rounding in xfs_io(8) bytes read/written output. - Sync up user/kernel source in libxfs and headers. - Fix compiler warnings on 64 bit platforms. - Update i18n message catalog. xfsprogs-2.6.11 (15 April 2004) - Fix file descriptor leak in path_to_fshandle. A file was being opened but never closed, regardless of whether that descriptor was being cached. Now close the file on error or if it is not being cached. - Fix xfs_repair handling of a corrupt v2 directory with multiple entries having the same name. xfsprogs-2.6.10 (05 April 2004) - Fix botch in recent addition of new superblock field (features2) which could result in filesystems with v2 logs being created with invalid superblock fields. Thanks to Chris Pascoe for this fix. - Fix error when forcing a too-large v2 log stripe size back to 32K. Thanks to Chris Pascoe for this fix too. - Fix xfs_copy -d option so that it really does create a duplicate filesystem (the log is duplicated too now in that case, whereas previously a fresh log was created). xfsprogs-2.6.9 (26 March 2004) - Update HFILES in xfsprogs/io/Makefile to package io/io.h xfsprogs-2.6.8 (25 March 2004) - Fix xfs_db when dumping v2 dirs larger than the fsb size. - Several xfs_io additions - support for memory mapped areas, multiple open files, expert mode (freeze, shutdown, error injection, etc), fadvise (Linux-specific), allow user to specify a create mode to open(2). - Fix xfs_bmap verbose mode stripe alignment information. - Fix typo on xfs(5) man page. xfsprogs-2.6.7 (19 March 2004) - Fix up UUID library checks again, previous fix didn't work for older versions of autconf. - Allow for future extensions to the XFS ondisk structure by reserving an extra 32 bits in the superblock for feature bits (update xfs_db to dump them). - Fix xfs_repair handling of version 2 directories with a hole at the start. - Fix an endian bug in xfs_copy, when operating on allocation groups with multi-level freespace btrees. - Ensure xfs_repair "dangerous" mode does not attempt to set the device blocksize, this generates an error when target filesystem is mounted readonly. xfsprogs-2.6.6 (03 March 2004) - mkfs now opens the devices it's operating on with the O_EXCL flag set, which is used by the Linux 2.6 block layer to ensure concurrent access does not happen. - Allow xfs_io to operate on files from other filesystems, with the XFS-specific commands unavailable in this mode. - Fix configure scripts to also search for a UUID library in /usr/lib64 which is its home on AMD64/x86_64. xfsprogs-2.6.5 (20 February 2004) - Fix up mkfs to ensure that the log size is a multiple of the v2 log stripe size even if the log happens to be aligned on a log stripe boundary (always check it). xfsprogs-2.6.4 (17 February 2004) - Fix a few more libxfs/repair leaks. - Fix up some libhandle routines, add the open_by_fshandle routine required by recent versions of xfsdump. xfsprogs-2.6.3 (19 January 2004) - Merge Steve Langasek's work on the Debian installer support for xfsprogs. - Add knowledge to xfs_db about the security namespace in its extended attributes commands. - Sync up user/kernel source in libxfs and headers. - Fix a couple of compilation warnings. - Workaround for some versions of autoconf mishandling the AC_CHECK_SIZEOF macro. - Fix a memory leak in libxfs, most noticable in xfs_repair. xfsprogs-2.6.2 (17 December 2003) - Fix dev_t sizing issues in user tools - glibc uses a 64 bit number and XFS has a 32 device bit number, confusion reigns. Not much manipulates device numbers in the XFS user tools though, hence hasn't really been seen before. Thanks to Christoph for the patch. xfsprogs-2.6.1 (27 November 2003) - Human-friendly xfs_io read/write bsize specifications. - Dump throughput and IOPs values after xfs_io reads/writes. - Sync up user/kernel source in libxfs, libxlog and headers. xfsprogs-2.6.0 (28 October 2003) - Change to mkfs strategy for allocation group count and size default. Scales significantly better for large filesystems. xfsprogs-2.5.11 (10 October 2003) - Incorporate Jan Derfinaks change to the Linux block ioctls used in libxfs, allowing this code to compile cleanly with include files from Linux 2.6.0-test5 onward. xfsprogs-2.5.10 (30 September 2003) - Fix up xfs_logprint to handle version 2 logs for its operation output (previously core dumped on it). xfsprogs-2.5.9 (19 September 2003) - Sync up user/kernel source in libxfs, libxlog and headers. - Add new inode flags into xfs_db too. xfsprogs-2.5.8 (12 September 2003) - Add missing options to xfs_db frag command one-line summary. - Add xfs_io commands for setting and clearing new inode flags for immutable/append-only/sync/no-atime/no-dump. - Dump some other statfs fields in the xfs_io statfs commands. - Remove "test" mode from xfs_repair, only useful in xfs_check. - Fix problem in xfs_logprint where it was trying to continue in the presence of a corrupt log when it shouldn't have. - Fix an incorrect assertion in xfs_logprint in regards to the validity of the log start block. - Fix xfs_growfs (and hence xfs_info) to allow it to be given either a mount point or a device in the mount table - it'll figure it out and should do the right thing either way now. xfsprogs-2.5.7 (29 August 2003) - Sync up user/kernel source in libxfs and headers. - Make xfs_copy a tad more portable, although work remains. - Add a "test" mode to xfs_repair and xfs_check which allows for sparse (and hence extremely large) filesystem testing. xfsprogs-2.5.6 (19 August 2003) - Fix a mkfs problem where it could exit inappropriately when a large data volume stripe unit was either specified on the command line or via querying the underlying volume manager. xfsprogs-2.5.5 (07 August 2003) - Update xfs_io command to allow reading from non-XFS files. - Sync up user/kernel source in libxfs, libxlog and headers. - Update xfs_db and xfs_logprint commands to print new inode flush iteration field. xfsprogs-2.5.4 (23 July 2003) - Update xfs_io bmap command to report unwritten extent flag if it is set on an extent (in verbose mode only). - Introducing xfs_copy. - Fix shell quoting problem in xfs_bmap script. xfsprogs-2.5.3 (07 July 2003) - Update xfs_io commands which take user input in terms of byte counts to now also allow unit prefixes like mkfs.xfs. - Tweak build to avoid unnecessary rebuilds of international language files (if present), suggested by Steve Langasek. - Fix usage message in mkfs.xfs, it was out of date. - Fix some filesystem type detection code, in particular the bfs probe code was broken for 64 bit machines (found by QA test 032) and the hfs code was broken too (originally found by Ethan Benson). We now also detect hfs+ filesystems. xfsprogs-2.5.2 (25 June 2003) - Fix xvm stripe detection in libdisk - pass correctly sized structures to xvm ioctls. - Add pthread library checks into configure and build scripts for work-in-progress on xfs_repair and xfs_copy. - Fix missing initialisation of stripe unit/width alignment information during libxfs_mount. - Fix botched repair typecast for multi-terabyte filesystems. xfsprogs-2.5.1 (23 June 2003) - Fix libdisk device driver (volume managers) detection code used by mkfs, so that drivers with multiple majors are not incorrectly processed. xfsprogs-2.5.0 (18 June 2003) - Fix libdisk (and hence mkfs) code which warns on MD devices with the clean flag not set, apparently this is not so wise. - Fix libxfs_device_zero to work with smaller-than-requested write return values. - Fix error in xfs_io pwrite code with large request sizes. - Fix rounding-down-input problems in several xfs_io commands. - Changed mkfs.xfs default log size scaling algorithm slightly, to create larger logs at smaller filesystem sizes by default (thanks to Andi Kleen for the patch). - Enable support for sector sizes larger than 512 bytes. xfsprogs-2.4.12 (02 June 2003) - Fix xfs_logprint handling of any version 2 log device. - Remove calls to exit in libhandle, propogate errors to caller, and bumped libhandle version from 1.0.1 to 1.0.2. xfsprogs-2.4.11 (30 May 2003) - Extract device sector size at mkfs time and issue warnings if the requested filesystem sector size is too small. - Sync up user/kernel source in libxfs, libxlog and headers. - Skip realtime initialisation in libxfs mount path if the caller is xfs_db, otherwise we get nonsense warnings. - Update xfs_io with a couple of additional commands. - Fix xfs_logprint handling of corrupt v2 log devices. xfsprogs-2.4.10 (12 May 2003) - Fix a bug in mkfs - creating version 2 logs, an incorrect stripe unit value was being passed to libxfs_clear_log. All recent versions of xfs_repair will fix this, however, because xfs_repair uses the correct stripe unit value. - Fix a bug in xfs_logprint, when dumping a corrupt log. - FreeBSD updates from Alexander Kabaev. - Large sector size updates for mkfs (disabled at the moment). - Large sector size fixes for xfs_repair. - Sync up with aeb's mount source for filesystem detection. xfsprogs-2.4.9 (03 May 2003) - Allow xfs_repair to run on read-only filesystems. xfsprogs-2.4.8 (26 April 2003) - Rework configure.in to make use of shared macros. - Fix up #include lines to allow compilation of sources with installed headers rather than local headers. - Fix botches in xfs_bmap shell script which prevented any arguments being passed on to xfs_io (from Jan Derfinak). xfsprogs-2.4.7 (22 April 2003) - Clarify XFS system call interfaces, fix up documentation. xfsprogs-2.4.6 (11 April 2003) - Fix a bug in detection of "clean" and "error" states with MD devices. - Fix configure tests that used AC_PATH_PROG incorrectly. - Add support for libedit, if libreadline is unavailable. - Fix the libxfs build on big endian platforms. - Sync up user/kernel source in libxfs and headers. xfsprogs-2.4.5 (03 April 2003) - Sync up xfs_inode.c in libxfs. - Implement get_unaligned/put_unaligned in libxfs. xfsprogs-2.4.4 (30 March 2003) - Correct display of imaxpct in mkfs.xfs output. - Portability changes; including some code to support use of several tools on Mac OS X (for Russell), ditto for FreeBSD (from Russell); also did a simplistic backport to IRIX (for me), so that I can run purify on some of the tools. - See doc/INSTALL for more details on this. - Sync up user/kernel source in libxfs and headers. - Fix up some warnings when compiling libxfs on big endian platforms. - Fix a configure.in botch which resulted in libreadline always being used even when it was not asked for. - Fixed the configure.in script so that if gettext disabled, we don't check for the gettext tools (and no longer fails if they were not found). - Added the ability to specify a different user and/or group to install as (previously, and still by default, root/root were always used here). xfsprogs-2.4.3 (27 March 2003) - Cleanups to the build process, in particular the automatic rpm package generation Makefile and spec file template. - Makepkgs script can now propagate failures back from make. - Minor configure.in update to deal with readline libraries which have not been linked correctly. xfsprogs-2.4.2 (25 March 2003) - Added the xfs_io(8) command, an xfs_db(8) alike command for testing and debugging the XFS file IO path. - Added an optional dependency on the GNU readline library which is "off" by default and enabled with the configure option --enable-readline=yes; it affects the interactive tools only (xfs_db and now xfs_io). - Implemented xfs_bmap(8) as a shell script wrapper. - Documented the mkfs.xfs -f, -llogdev and -rrtdev options. - Corrected size check for realtime summary inode (not the same as the realtime bitmap inode) in xfs_repair. xfsprogs-2.4.1 (18 March 2003) - Fix error reporting when zeroing parts of the realtime device in phase6 of xfs_repair. - Add a mkfs.xfs check for Mac partitions before writing to the device. - Thanks to Ethan Benson for this. - Minor fix to the xfs_bmap(8) man page. - Sync up user/kernel source in libxfs and headers. xfsprogs-2.4.0 (06 March 2003) - Enable unwritten extents by default in mkfs.xfs. - Add a command to xfs_db to enable unwritten extents. - Add an option to xfs_admin to use the above command. - Add command to xfs_db to print out the currently enabled feature bits and version number. - Make xfs_db slightly more robust in the presense of bad ondisk data. - Rationalise some xfs_db superblock-related code and the uuid command now checks for a dirty log before zeroing. - Add stripe alignment information to xfs_bmap. - Sync up user/kernel source in libxfs and headers. - Update man pages, fix a typo in the xfs_admin man page relating to the UUID options. xfsprogs-2.3.11 (18 February 2003) - Missed a build dependency for the Debian build process. xfsprogs-2.3.10 (17 February 2003) - Fix a divide-by-zero error in mkfs with certain stripe unit and/or width options specified. - Sync up user/kernel source in libxfs and headers. xfsprogs-2.3.9 (31 December 2002) - Additional xfs_repair check in v2 directory handling for blks with no data entries (merged from IRIX), includes several handy comments sprinkled throughout this v2 dir code. - Fix an endian bug in the same area of code (v2 dirs, phase 6, longform_dir2_rebuild_setup) - xfs_repair has additional checks for bad sector values now. - xfs_repair I18N changes. - Fix detection of readonly mounts, slightly botched in 2.3.8. - Fix references to removed ioctl commands on xfs(5) man page. xfsprogs-2.3.8 (18 December 2002) - Initial support for I18N (still more to do here). - Initial changes for filesystems with greater than 512 byte sector sizes (still plenty more to do here too). - Tidy up libxfs functions which take a "flags" argument. - Sync up user/kernel source in lib{xfs,xlog} and headers. - Fixed incorrect use of XFS_FSB_TO_DADDR macro in xfs_db's faddr.c::fa_dirblock routine - now use XFS_FSB_TO_BB here, as set_cur() takes basic blocks as its third parameter. - Fixed obscure issue in mkfs where only the first AG would get its AGFL freelist "fixed" - not clear this caused any issues in practice (on Linux it's always been this way, we now match up with IRIX though). - Made xfs_growfs filesystem geometry output match up with that displayed by mkfs.xfs (xfs_growfs was missing a comma before the log version field). - Fixed an issue in xfs_repair where data past the end of the valid superblock fields was sometimes not cleared, when it really should have been (due to a libxfs problem). - Shell scripts (xfs_info, xfs_check, etc) now also report the xfsprogs version number via -V, like other commands. xfsprogs-2.3.7 (14 November 2002) - Fix an endian bug in xfs_db freesp command when descending into multi-level agf cnt/bno btrees. xfsprogs-2.3.6 (31 October 2002) - Sync up user/kernel source in lib{xfs,xlog} and headers. - Fix several warnings from newer (3.2) versions of gcc. - Minor header file shuffling. xfsprogs-2.3.5 (10 October 2002) - Sync up user/kernel source in lib{xfs,xlog} and headers. - Fix mkfs (libxfs) bug when using BLKFLSBUF ioctl - we passed in the device number instead of a file descriptor (and EBADF was the end result, which we ignored). - Thanks to Anton Blanchard for fixing this. xfsprogs-2.3.4 (04 October 2002) - Fix size calculation bug in xfs_repair's memory allocation, reduces memory usage by a factor of 4. xfsprogs-2.3.3 (16 September 2002) - Fix mkfs bug when optimizing AG size on striped devices, ASSERT(agcount != 0) tripped on single-ag filesystems. xfsprogs-2.3.2 (10 September 2002) - Use pread/pwrite instead of lseek + read/write. xfsprogs-2.3.1 (03 September 2002) - Allow xfs_db to accept negative numbers when writing values. xfsprogs-2.3.0 (03 September 2002) - Several changes to geometry ioctl callers which will make the tools useable on older kernel versions too. - Mainly affects xfs_bmap and xfs_growfs. - Do some additional cleanup after autoconf has run. xfsprogs-2.2.3 (28 August 2002) - Update libdisk for a few other filesystems. - Fix call to lvdisplay on LVM volumes so that lvdisplay always gets the full, real path to the volume, as required. xfsprogs-2.2.2 (19 August 2002) - Fix endian bug in xfs_db, was not flipping 16-bit numbers. - Make xfs_repair recognize a NULLFSINO and print that in addition to "18446744073709551615" for easy recognition. - Fix format string that xfs_repair uses when fixing inodes, so that the new inode numbers are printed correctly. xfsprogs-2.2.1 (09 August 2002) - Fix buglet in libdisk get_driver_block_major() routine which would result in incorrect majors being returned for not-found drivers. - Fix problem in install process with newer autoconf versions. xfsprogs-2.2.0 (08 August 2002) - mkfs.xfs defaults to a blocksize of 4096 bytes, and no longer uses getpagesize(2) to dynamically configure the default size. - Add EVMS stripe unit/width auto-detection support in mkfs.xfs (patch from Luciano Chavez). - Sync user/kernel headers (arch.h incorporated into xfs_arch.h, and several other minor changes). xfsprogs-2.1.2 (17 July 2002) - Fix up log stripe unit specification options, and update man page. Also fix suffix handling for data su/sw options (disallow unit suffixes on -d sunit,swidth,sw and -l sunit). Add "s" (512-byte sectors) as valid suffix. - Automatically select v2 logs if a log stripe unit is specified. xfsprogs-2.1.1 (04 July 2002) - Build infrastructure updates so that configure options can be used to specify paths rather than semi-hard-coded path names controlled by the ROOT/ROOT_PREFIX environment variables; eg. now allows /lib64 and /lib32 xfsprogs-2.1.0 (14 June 2002) - Support for XFS version 2 log format. - Fix for xfs_repair mangling i8count for dir2_sf directories - Minor mkfs.xfs man page update for blocksize limits on Linux - xfs_cred.h split into xfs_acl.h, xfs_cap.h and xfs_mac.h - Fix typo in mkfs realtime summary inode alloc failure message xfsprogs-2.0.6 (30 May 2002) - Fix error returns from log recovery (affects xfs_repair). - Fix the way mkfs.xfs round downs the device when the last AG is smaller than the minimum AG size. - Fix bug in xfs_repair da_write() routine, which affects filesystems where the data blocksize != naming blocksize (see xfs_info output). - Fix a use-after-free bug in xfs_repair code for checking version 1 btree-format directories. - Add checks of the ACL permissions field into xfs_repair. xfsprogs-2.0.5 (02 May 2002) - Size AGs so that they do not always start on the same part of a striped disk - Fix an off-by-one error on rounding down an AG that is too small to be an AG - Don't auto-grow the log to be larger than an AG - Change the error philosophy for -d su=,sw= away from forcing the XFS stripe size to match the volume manager stripe size and instead accept, with a warning, the stripe unit & width supplied on the commandline. - Update xfs_growfs man page - Don't build libxlog.a with DEBUG enabled - xfs_db fixes from ASANO Masahiro at NEC xfsprogs-2.0.4 (17 April 2002) - Minor update sync'ing with kernel changes (less endian swabbing in libxfs code) xfsprogs-2.0.3 (13 April 2002) - Important build system update, was causing libxfs to be built incorrectly, which can cause xfs_repair to fail by tripping asserts in additional libxfs debug code. xfsprogs-2.0.2 (04 April 2002) - Bumped version of libhandle to libhandle.so.1.0.1 This changes open_by_handle() and friends so that O_LARGEFILE is added to the open flags. This allows xfsdump to dump files greater than 2^31-1 bytes instead of not dumping the large files and giving warning messages. xfsprogs-2.0.1 (12 March 2002) - Fall back to BLKGETSIZE if BLKGETSIZE64 fails - Sync user/kernel headers and shared code xfsprogs-2.0.0 (26 February 2002) - Major release to coincide with switch to new extended attributes system call interfaces - bumped version of libhandle, added new symbols to use the reworked extended attributes handle ioctl interface - xfs_repair in no-modify mode opens the filesystem device read-only now (fix from Chris Pascoe) - sync up with recent (minor) changes to shared kernel code - switch to using the BLKGETSIZE64 ioctl in libxfs, instead of the (previously busted) BLKGETSIZE ioctl xfsprogs-1.3.19 (15 February 2002) - fix xfs_repair option parsing for external logs - add xfs_repair option parsing for realtime device - fix xfs_repair version (-V) option - should not require an argument - add -V option to usage string - document verbose (-v) and -r options in manpage xfsprogs-1.3.18 (17 January 2002) - fix mkfs.xfs buglet in overwriting signatures when run on a regular file xfsprogs-1.3.17 (14 January 2002) - mkfs.xfs overwrites pre-existing filesystem, swap, or md driver signatures. - xfs_repair fix to prevent double insertion into the uncertain_inode AVL trees ("avl_insert: duplicate range") - xfs_repair fix if the log is corrupted and we can't find the head, don't exit - just proceed on with zeroing it - use snprintf instead of sprintf throughout xfsprogs-1.3.16 (17 December 2001) - added text dump type to xfs_db (mkp) - removed use of a temporary file in xfs_db when processing commands on the command line - allows xfs_check to be run on read-only root filesystems xfsprogs-1.3.15 (12 December 2001) - reenable the use of the BLKBSZSET ioctl, it's baaack - sync recent XFS kernel source changes back into libxfs xfsprogs-1.3.14 (05 December 2001) - fix minor debian package version numbering issue - add documentation for xfs_db(8) label/uuid commands - automatic inode sizing code in mkfs.xfs has been removed (restricting inodes to 32 bits) - Steve's recent kernel changes mean this is no longer an issue - fix bug in mkfs.xfs size cross-check for realtime device xfsprogs-1.3.13 (25 October 2001) - fix bug in mkfs for 1Tbyte + filesystems - sync with recent kernel changes - this does not affect userspace (libxfs), all affected code is removed by cpp. xfsprogs-1.3.12 (17 October 2001) - implement the -f (file) option to xfs_logprint - rework the xlog code into libxlog for code sharing - xfs_repair now detects a dirty log and, without -L, will no longer blindly zero it (which prevents any recovery) xfsprogs-1.3.11 (17 October 2001) - tidy up some (benign) compiler warnings from libxfs - fixed 64-bit pointer alignment issues in xfs_check - fixed 64-bit pointer alignment issues in xfs_repair - verified these on IA64, also reported to fix sparc issues xfsprogs-1.3.10 (12 October 2001) - sync with XFS kernel header changes for EAs by-handle - ported xfs_imap command for dumping the inode map xfsprogs-1.3.9 (03 October 2001) - fix xfs_repair bug in handling a corrupt root directory inode with multiple "lost+found" entries - fix xfs_logprint bug in scanning for log head and tail - ensure xfs_bmap doesn't issue XFS ioctls to non-XFS files - numerous man page updates xfsprogs-1.3.8 (19 September 2001) - rewrote the LVM support used by mkfs.xfs to call external lvdisplay program to get volume geometry (mkp@mkp.net) - fix bug in LVM driver wrapper where it would not have been used at all, ever (since 1.3.0), due to idiot programmer error (*blush*) -- also thanks to mkp for the bug fix xfsprogs-1.3.7 (10 September 2001) - enable preallocation in xfs_mkfile [missed during port?] - fix xfs_db core dump when reporting freespace - allow libuuid to be linked dynamically if desired (based on a patch from Colin Walters , helps the folk working on the Debian installer for XFS) - licensing change for "libhandle" (was GPL, now LGPL-2.1) and some related header files xfsprogs-1.3.6 (31 August 2001) - make mkfs.xfs aware of geometries that might cause inode numbers to exceed 32 significant bits. - make xfs_growfs warn if new filesystem will have inode numbers that exceed 32 significant bits. - fix logprint bug in reporting extended attributes (thanks to Tang Lingbo for fixing this) - fix mkfs.xfs core dump when attemping to run on devices which are too small to hold a valid XFS filesystem xfsprogs-1.3.5 (13 August 2001) - fix bug in xfs_db bit handling on big endian platforms - fix mkfs bug related to too-small final allocation group - fix signedness bug in DMAPI ioctl structure definition xfsprogs-1.3.4 (04 August 2001) - fix endian bug in xfs_db "frag" command - small configure script changes to allow cross compilation - several man pages updated to document external log usage - install another shared library symlink for ld to find - switched on -fno-strict-aliasing for library object builds - fix several minor compiler warnings when building on IA64 xfsprogs-1.3.3 (27 July 2001) - fixes for (hopefully) the last few nits in libtool usage xfsprogs-1.3.2 (23 July 2001) - install static libs and libtool archives into /usr/lib - shared libraries are unchanged, however xfsprogs-1.3.1 (15 July 2001) - updated xfs_types.h file from the kernel changes needed for an xfsdump fix. - tidy up various aspects of the libtool rework - XVM stripe unit/width extraction - fix an endian bug in xfs_db "write" command - fix a build problem with liblvm.a installed - fix bug in xfs_growfs mount option parsing with external log - BLKSZSET ioctl now conditional via the Makefile (off by default) - rework some of the Debian packaging rules - fix sign of BLKGETSIZE ioctl argument in libxfs - updated xfs_fs.h with DMAPI setdm details for dump/restore xfsprogs-1.3.0 (11 July 2001) - reworked Makefiles to use libtool - new libdisk to allow sharing of generic mount/disk code and - also abstracts individual driver support (LVM, MD, XVM..) - partition table detection so mkfs.xfs doesn't blindly overwrite - small xfs_repair bug fix from Steve xfsprogs-1.2.8 (02 July 2001) - fixed a bug in libxfs /etc/mtab read-only mount detection - first try procfs, fall back to /etc/mtab, for read-only mounts - sync with recent mount code changes for reiserfs and ext3 probes - fix logprint build problem under gcc 3.0 xfsprogs-1.2.7 (22 May 2001) - new xfs_freeze(8) command - volume manager snapshot helper xfsprogs-1.2.6 (15 May 2001) - merge support for -d agsize=/su=/sw= (AG, stripe unit/width size) - merge support for dynamic configuration of default log size - document these and fix a couple of man page typos too xfsprogs-1.2.5 (07 May 2001) - fix missing Makefile include entries for LVM headers - configure script default man path now /usr/share/man - add experimental xfs_rtcp (realtime copy) command - powerpc build failure fixups - thanks to Robert Ramiega - cleanup arch-specific code, esp. the byteswab routines - as a result, move to -O1 as default for extern inlines xfsprogs-1.2.4 (01 May 2001) - added -L option to mkfs.xfs (filesystem label) xfsprogs-1.2.3 (27 April 2001) - add dquot and quotaoff log item support into xfs_logprint - fix logprint core dump reporting AGI in "continue"'d transactions xfsprogs-1.2.2 (09 April 2001) - fix problem in xfs_db (check) group quota logic - fixes to warnings from recent gcc and/or 64-bit builds xfsprogs-1.2.1 (04 April 2001) - sync up with recent changes to XFS kernel headers xfsprogs-1.2.0 (01 April 2001) - support for group quota added - some headers updated, in particular - now in late stages of beta xfsprogs-1.1.9 (26 March 2001) - added automagic stripe unit/stripe width extraction for MD devices xfsprogs-1.1.8 (23 March 2001) - mkfs heuristics to make a qualified guess of internal logsize xfsprogs-1.1.7 (20 March 2001) - upgraded LVM to 0.9beta6 - minor rpm spec file changes xfsprogs-1.1.6 (20 March 2001) - fix sparc build failure - fcntl.h missing O_DIRECT - added README.quota describing use of quota with XFS xfsprogs-1.1.5 (12 March 2001) - upgraded LVM support to 0.9beta2 (IOP 10) xfsprogs-1.1.4 (10 March 2001) - kernel now supports O_DIRECT - re-enable its use in xfs_mkfile - BLKSETSIZE ioctl replaced by BLKBSZSET ioctl in libxfs - libxfs_init extended so only mkfs and xfs_repair use BLKBSZSET - NOTE: this version requires an XFS kernel from March 9 or later xfsprogs-1.1.3 (02 March 2001) - minor Makefile-related cleanups xfsprogs-1.1.2 (10 February 2001) - added libhandle routines to simplify dump/restore EA support xfsprogs-1.1.1 (30 January 2001) - minor rpm and deb packaging work xfsprogs-1.1.0 (15 January 2001) - rework xfs-cmds package into base, devel and dump packages - completed Debian packaging - late beta code xfs-cmds-1.0.7 (02 January 2001) - added mkfs support for extracting LVM stripe unit/width - libattr (*experimental* extended attributes interface) added - removed xfs_fstab.5 man page (merged into mount.8) - install xfs_repair into /sbin, not /usr/sbin xfs-cmds-1.0.6 (04 October 2000) - reworked external log format to be IRIX compatible - mkfs, repair, db, logprint now work with new format - xfs_admin added for setting filesystem label xfs-cmds-1.0.5 (18 September 2000) - minor bug fixes - first beta release xfs-cmds-1.0.4 (18 August 2000) - minor bug fixes - xfs_growfs added - xfs_info added - late alpha code xfs-cmds-1.0.3 (16 August 2000) - numerous bug fixes - xfsdump and xfsrestore added - xfsstats added - fsck.xfs (symlink to /bin/true) added - demise of sim library complete, mkfs and repair reworked - no longer need to have an XFS kernel handy for building xfs-cmds - xfs_copy compiles on Linux - dump/restore README added - late alpha code xfs-cmds-1.0.2 (27 July 2000) - numerous bug fixes - xfs_attr (extended attributes) command added - fsr_xfs added (ported by jones@tacc.utexas.edu) - LVM+XFS README added - early alpha code xfs-cmds-1.0.1 (5 July 2000) - numerous bug fixes - reworked build environment - begun work on user/kernel separation - early alpha code xfs-cmds-1.0.0 (16 June 2000) - initial release for USENIX CDs - early alpha code xfsprogs-3.1.9ubuntu2/db/0000775000000000000000000000000012062211564012200 5ustar xfsprogs-3.1.9ubuntu2/db/hash.c0000664000000000000000000000275011146407622013277 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "addr.h" #include "command.h" #include "type.h" #include "io.h" #include "output.h" static int hash_f(int argc, char **argv); static void hash_help(void); static const cmdinfo_t hash_cmd = { "hash", NULL, hash_f, 1, 1, 0, N_("string"), N_("calculate hash value"), hash_help }; static void hash_help(void) { dbprintf(_( "\n" " 'hash' prints out the calculated hash value for a string using the\n" "directory/attribute code hash function.\n" "\n" " Usage: \"hash \"\n" "\n" )); } /* ARGSUSED */ static int hash_f( int argc, char **argv) { xfs_dahash_t hashval; hashval = libxfs_da_hashname((uchar_t *)argv[1], (int)strlen(argv[1])); dbprintf("0x%x\n", hashval); return 0; } void hash_init(void) { add_command(&hash_cmd); } xfsprogs-3.1.9ubuntu2/db/convert.c0000664000000000000000000002003611650373060014027 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "convert.h" #include "output.h" #include "init.h" #define M(A) (1 << CT_ ## A) #define agblock_to_bytes(x) \ ((__uint64_t)(x) << mp->m_sb.sb_blocklog) #define agino_to_bytes(x) \ ((__uint64_t)(x) << mp->m_sb.sb_inodelog) #define agnumber_to_bytes(x) \ agblock_to_bytes((__uint64_t)(x) * mp->m_sb.sb_agblocks) #define daddr_to_bytes(x) \ ((__uint64_t)(x) << BBSHIFT) #define fsblock_to_bytes(x) \ (agnumber_to_bytes(XFS_FSB_TO_AGNO(mp, (x))) + \ agblock_to_bytes(XFS_FSB_TO_AGBNO(mp, (x)))) #define ino_to_bytes(x) \ (agnumber_to_bytes(XFS_INO_TO_AGNO(mp, (x))) + \ agino_to_bytes(XFS_INO_TO_AGINO(mp, (x)))) #define inoidx_to_bytes(x) \ ((__uint64_t)(x) << mp->m_sb.sb_inodelog) typedef enum { CT_NONE = -1, CT_AGBLOCK, /* xfs_agblock_t */ CT_AGINO, /* xfs_agino_t */ CT_AGNUMBER, /* xfs_agno_t */ CT_BBOFF, /* byte offset in daddr */ CT_BLKOFF, /* byte offset in fsb/agb */ CT_BYTE, /* byte in filesystem */ CT_DADDR, /* daddr_t */ CT_FSBLOCK, /* xfs_fsblock_t */ CT_INO, /* xfs_ino_t */ CT_INOIDX, /* index of inode in fsblock */ CT_INOOFF, /* byte offset in inode */ NCTS } ctype_t; typedef struct ctydesc { ctype_t ctype; int allowed; const char **names; } ctydesc_t; typedef union { xfs_agblock_t agblock; xfs_agino_t agino; xfs_agnumber_t agnumber; int bboff; int blkoff; __uint64_t byte; xfs_daddr_t daddr; xfs_fsblock_t fsblock; xfs_ino_t ino; int inoidx; int inooff; } cval_t; static __uint64_t bytevalue(ctype_t ctype, cval_t *val); static int convert_f(int argc, char **argv); static int getvalue(char *s, ctype_t ctype, cval_t *val); static ctype_t lookupcty(char *ctyname); static const char *agblock_names[] = { "agblock", "agbno", NULL }; static const char *agino_names[] = { "agino", "aginode", NULL }; static const char *agnumber_names[] = { "agnumber", "agno", NULL }; static const char *bboff_names[] = { "bboff", "daddroff", NULL }; static const char *blkoff_names[] = { "blkoff", "fsboff", "agboff", NULL }; static const char *byte_names[] = { "byte", "fsbyte", NULL }; static const char *daddr_names[] = { "daddr", "bb", NULL }; static const char *fsblock_names[] = { "fsblock", "fsb", "fsbno", NULL }; static const char *ino_names[] = { "ino", "inode", NULL }; static const char *inoidx_names[] = { "inoidx", "offset", NULL }; static const char *inooff_names[] = { "inooff", "inodeoff", NULL }; static const ctydesc_t ctydescs[NCTS] = { { CT_AGBLOCK, M(AGNUMBER)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF), agblock_names }, { CT_AGINO, M(AGNUMBER)|M(INOOFF), agino_names }, { CT_AGNUMBER, M(AGBLOCK)|M(AGINO)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF), agnumber_names }, { CT_BBOFF, M(AGBLOCK)|M(AGNUMBER)|M(DADDR)|M(FSBLOCK), bboff_names }, { CT_BLKOFF, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK), blkoff_names }, { CT_BYTE, 0, byte_names }, { CT_DADDR, M(BBOFF), daddr_names }, { CT_FSBLOCK, M(BBOFF)|M(BLKOFF)|M(INOIDX), fsblock_names }, { CT_INO, M(INOOFF), ino_names }, { CT_INOIDX, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK)|M(INOOFF), inoidx_names }, { CT_INOOFF, M(AGBLOCK)|M(AGINO)|M(AGNUMBER)|M(FSBLOCK)|M(INO)|M(INOIDX), inooff_names }, }; static const cmdinfo_t convert_cmd = { "convert", NULL, convert_f, 3, 9, 0, "type num [type num]... type", "convert from one address form to another", NULL }; static __uint64_t bytevalue(ctype_t ctype, cval_t *val) { switch (ctype) { case CT_AGBLOCK: return agblock_to_bytes(val->agblock); case CT_AGINO: return agino_to_bytes(val->agino); case CT_AGNUMBER: return agnumber_to_bytes(val->agnumber); case CT_BBOFF: return (__uint64_t)val->bboff; case CT_BLKOFF: return (__uint64_t)val->blkoff; case CT_BYTE: return val->byte; case CT_DADDR: return daddr_to_bytes(val->daddr); case CT_FSBLOCK: return fsblock_to_bytes(val->fsblock); case CT_INO: return ino_to_bytes(val->ino); case CT_INOIDX: return inoidx_to_bytes(val->inoidx); case CT_INOOFF: return (__uint64_t)val->inooff; case CT_NONE: case NCTS: break; } /* NOTREACHED */ return 0; } static int convert_f(int argc, char **argv) { ctype_t c; int conmask; cval_t cvals[NCTS]; int i; int mask; __uint64_t v; ctype_t wtype; /* move past the "convert" command */ argc--; argv++; if ((argc % 2) != 1) { dbprintf(_("bad argument count %d to convert, expected 3,5,7,9 " "arguments\n"), argc); return 0; } if ((wtype = lookupcty(argv[argc - 1])) == CT_NONE) { dbprintf(_("unknown conversion type %s\n"), argv[argc - 1]); return 0; } for (i = mask = conmask = 0; i < (argc - 1) / 2; i++) { c = lookupcty(argv[i * 2]); if (c == CT_NONE) { dbprintf(_("unknown conversion type %s\n"), argv[i * 2]); return 0; } if (c == wtype) { dbprintf(_("result type same as argument\n")); return 0; } if (conmask & (1 << c)) { dbprintf(_("conflicting conversion type %s\n"), argv[i * 2]); return 0; } if (!getvalue(argv[i * 2 + 1], c, &cvals[c])) return 0; mask |= 1 << c; conmask |= ~ctydescs[c].allowed; } if (cur_agno != NULLAGNUMBER && (conmask & M(AGNUMBER)) == 0) { cvals[CT_AGNUMBER].agnumber = cur_agno; mask |= M(AGNUMBER); conmask |= ~ctydescs[CT_AGNUMBER].allowed; } v = 0; for (c = (ctype_t)0; c < NCTS; c++) { if (!(mask & (1 << c))) continue; v += bytevalue(c, &cvals[c]); } switch (wtype) { case CT_AGBLOCK: v = xfs_daddr_to_agbno(mp, v >> BBSHIFT); break; case CT_AGINO: v = (v >> mp->m_sb.sb_inodelog) % (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog); break; case CT_AGNUMBER: v = xfs_daddr_to_agno(mp, v >> BBSHIFT); break; case CT_BBOFF: v &= BBMASK; break; case CT_BLKOFF: v &= mp->m_blockmask; break; case CT_BYTE: break; case CT_DADDR: v >>= BBSHIFT; break; case CT_FSBLOCK: v = XFS_DADDR_TO_FSB(mp, v >> BBSHIFT); break; case CT_INO: v = XFS_AGINO_TO_INO(mp, xfs_daddr_to_agno(mp, v >> BBSHIFT), (v >> mp->m_sb.sb_inodelog) % (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog)); break; case CT_INOIDX: v = (v >> mp->m_sb.sb_inodelog) & (mp->m_sb.sb_inopblock - 1); break; case CT_INOOFF: v &= mp->m_sb.sb_inodesize - 1; break; case CT_NONE: case NCTS: /* NOTREACHED */ break; } dbprintf("0x%llx (%llu)\n", v, v); return 0; } void convert_init(void) { add_command(&convert_cmd); } static int getvalue(char *s, ctype_t ctype, cval_t *val) { char *p; __uint64_t v; v = strtoull(s, &p, 0); if (*p != '\0') { dbprintf(_("%s is not a number\n"), s); return 0; } switch (ctype) { case CT_AGBLOCK: val->agblock = (xfs_agblock_t)v; break; case CT_AGINO: val->agino = (xfs_agino_t)v; break; case CT_AGNUMBER: val->agnumber = (xfs_agnumber_t)v; break; case CT_BBOFF: val->bboff = (int)v; break; case CT_BLKOFF: val->blkoff = (int)v; break; case CT_BYTE: val->byte = (__uint64_t)v; break; case CT_DADDR: val->daddr = (xfs_daddr_t)v; break; case CT_FSBLOCK: val->fsblock = (xfs_fsblock_t)v; break; case CT_INO: val->ino = (xfs_ino_t)v; break; case CT_INOIDX: val->inoidx = (int)v; break; case CT_INOOFF: val->inooff = (int)v; break; case CT_NONE: case NCTS: /* NOTREACHED */ break; } return 1; } static ctype_t lookupcty(char *ctyname) { ctype_t cty; const char **name; for (cty = (ctype_t)0; cty < NCTS; cty++) { for (name = ctydescs[cty].names; *name; name++) { if (strcmp(ctyname, *name) == 0) return cty; } } return CT_NONE; } xfsprogs-3.1.9ubuntu2/db/io.c0000664000000000000000000003255711146407622012773 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "io.h" #include "output.h" #include "init.h" #include "malloc.h" static int pop_f(int argc, char **argv); static void pop_help(void); static int push_f(int argc, char **argv); static void push_help(void); static int stack_f(int argc, char **argv); static void stack_help(void); static int forward_f(int argc, char **argv); static void forward_help(void); static int back_f(int argc, char **argv); static void back_help(void); static int ring_f(int argc, char **argv); static void ring_help(void); static const cmdinfo_t pop_cmd = { "pop", NULL, pop_f, 0, 0, 0, NULL, N_("pop location from the stack"), pop_help }; static const cmdinfo_t push_cmd = { "push", NULL, push_f, 0, 2, 0, N_("[command]"), N_("push location to the stack"), push_help }; static const cmdinfo_t stack_cmd = { "stack", NULL, stack_f, 0, 0, 0, NULL, N_("view the location stack"), stack_help }; static const cmdinfo_t forward_cmd = { "forward", "f", forward_f, 0, 0, 0, NULL, N_("move forward to next entry in the position ring"), forward_help }; static const cmdinfo_t back_cmd = { "back", "b", back_f, 0, 0, 0, NULL, N_("move to the previous location in the position ring"), back_help }; static const cmdinfo_t ring_cmd = { "ring", NULL, ring_f, 0, 1, 0, NULL, N_("show position ring or move to a specific entry"), ring_help }; iocur_t *iocur_base; iocur_t *iocur_top; int iocur_sp = -1; int iocur_len; #define RING_ENTRIES 20 static iocur_t iocur_ring[RING_ENTRIES]; static int ring_head = -1; static int ring_tail = -1; static int ring_current = -1; void io_init(void) { add_command(&pop_cmd); add_command(&push_cmd); add_command(&stack_cmd); add_command(&forward_cmd); add_command(&back_cmd); add_command(&ring_cmd); } void off_cur( int off, int len) { if (iocur_top == NULL || off + len > BBTOB(iocur_top->blen)) dbprintf(_("can't set block offset to %d\n"), off); else { iocur_top->boff = off; iocur_top->off = ((xfs_off_t)iocur_top->bb << BBSHIFT) + off; iocur_top->len = len; iocur_top->data = (void *)((char *)iocur_top->buf + off); } } void pop_cur(void) { if (iocur_sp < 0) { dbprintf(_("can't pop anything from I/O stack\n")); return; } if (iocur_top->buf) xfree(iocur_top->buf); if (--iocur_sp >= 0) { iocur_top = iocur_base + iocur_sp; cur_typ = iocur_top->typ; } else { iocur_top = iocur_base; iocur_sp = 0; } } /*ARGSUSED*/ static int pop_f( int argc, char **argv) { pop_cur(); return 0; } static void pop_help(void) { dbprintf(_( "\n" " Changes the address and data type to the first entry on the stack.\n" "\n" )); } void print_iocur( char *tag, iocur_t *ioc) { int i; dbprintf("%s\n", tag); dbprintf(_("\tbyte offset %lld, length %d\n"), ioc->off, ioc->len); dbprintf(_("\tbuffer block %lld (fsbno %lld), %d bb%s\n"), ioc->bb, (xfs_dfsbno_t)XFS_DADDR_TO_FSB(mp, ioc->bb), ioc->blen, ioc->blen == 1 ? "" : "s"); if (ioc->use_bbmap) { dbprintf(_("\tblock map")); for (i = 0; i < ioc->blen; i++) dbprintf(" %d:%lld", i, ioc->bbmap.b[i]); dbprintf("\n"); } dbprintf(_("\tinode %lld, dir inode %lld, type %s\n"), ioc->ino, ioc->dirino, ioc->typ == NULL ? _("none") : ioc->typ->name); } void print_ring(void) { int i; iocur_t *ioc; if (ring_current == -1) { dbprintf(_("no entries in location ring.\n")); return; } dbprintf(_(" type bblock bblen fsbno inode\n")); i = ring_head; for (;;) { ioc = &iocur_ring[i]; if (i == ring_current) printf("*%2d: ", i); else printf(" %2d: ", i); dbprintf("%-7.7s %8lld %5d %8lld %9lld\n", ioc->typ == NULL ? "none" : ioc->typ->name, ioc->bb, ioc->blen, (xfs_dfsbno_t)XFS_DADDR_TO_FSB(mp, ioc->bb), ioc->ino ); if (i == ring_tail) break; i = (i+(RING_ENTRIES-1))%RING_ENTRIES; } } void push_cur(void) { if (iocur_sp + 1 >= iocur_len) { iocur_base = xrealloc(iocur_base, sizeof(*iocur_base) * (iocur_len + 1)); iocur_len++; } iocur_sp++; iocur_top = iocur_base + iocur_sp; memset(iocur_top, 0, sizeof(*iocur_base)); iocur_top->ino = iocur_sp > 0 ? iocur_top[-1].ino : NULLFSINO; iocur_top->dirino = iocur_sp > 0 ? iocur_top[-1].dirino : NULLFSINO; iocur_top->mode = iocur_sp > 0 ? iocur_top[-1].mode : 0; cur_typ = NULL; } static int push_f( int argc, char **argv) { const cmdinfo_t *ct; if (argc > 1) { /* check we can execute command */ ct = find_command(argv[1]); if (ct == NULL) { dbprintf(_("no such command %s\n"), argv[1]); return 0; } if (!ct->canpush) { dbprintf(_("no push form allowed for %s\n"), argv[1]); return 0; } } /* save current state */ push_cur(); if (iocur_top[-1].typ && iocur_top[-1].typ->typnm == TYP_INODE) set_cur_inode(iocur_top[-1].ino); else set_cur(iocur_top[-1].typ, iocur_top[-1].bb, iocur_top[-1].blen, DB_RING_IGN, iocur_top[-1].use_bbmap ? &iocur_top[-1].bbmap : NULL); /* run requested command */ if (argc>1) (void)command(argc-1, argv+1); return 0; } static void push_help(void) { dbprintf(_( "\n" " Allows you to push the current address and data type on the stack for\n" " later return. 'push' also accepts an additional command to execute after\n" " storing the current address (ex: 'push a rootino' from the superblock).\n" "\n" )); } /* move forward through the ring */ /* ARGSUSED */ static int forward_f( int argc, char **argv) { if (ring_current == -1) { dbprintf(_("ring is empty\n")); return 0; } if (ring_current == ring_head) { dbprintf(_("no further entries\n")); return 0; } ring_current = (ring_current+1)%RING_ENTRIES; set_cur(iocur_ring[ring_current].typ, iocur_ring[ring_current].bb, iocur_ring[ring_current].blen, DB_RING_IGN, iocur_ring[ring_current].use_bbmap ? &iocur_ring[ring_current].bbmap : NULL); return 0; } static void forward_help(void) { dbprintf(_( "\n" " The 'forward' ('f') command moves to the next location in the position\n" " ring, updating the current position and data type. If the current location\n" " is the top entry in the ring, then the 'forward' command will have\n" " no effect.\n" "\n" )); } /* move backwards through the ring */ /* ARGSUSED */ static int back_f( int argc, char **argv) { if (ring_current == -1) { dbprintf(_("ring is empty\n")); return 0; } if (ring_current == ring_tail) { dbprintf(_("no previous entries\n")); return 0; } ring_current = (ring_current+(RING_ENTRIES-1))%RING_ENTRIES; set_cur(iocur_ring[ring_current].typ, iocur_ring[ring_current].bb, iocur_ring[ring_current].blen, DB_RING_IGN, iocur_ring[ring_current].use_bbmap ? &iocur_ring[ring_current].bbmap : NULL); return 0; } static void back_help(void) { dbprintf(_( "\n" " The 'back' ('b') command moves to the previous location in the position\n" " ring, updating the current position and data type. If the current location\n" " is the last entry in the ring, then the 'back' command will have no effect.\n" "\n" )); } /* show or go to specific point in ring */ static int ring_f( int argc, char **argv) { int index; if (argc == 1) { print_ring(); return 0; } index = (int)strtoul(argv[1], NULL, 0); if (index < 0 || index >= RING_ENTRIES) dbprintf(_("invalid entry: %d\n"), index); ring_current = index; set_cur(iocur_ring[index].typ, iocur_ring[index].bb, iocur_ring[index].blen, DB_RING_IGN, iocur_ring[index].use_bbmap ? &iocur_ring[index].bbmap : NULL); return 0; } static void ring_help(void) { dbprintf(_( "\n" " The position ring automatically keeps track of each disk location and\n" " structure type for each change of position you make during your xfs_db\n" " session. The last %d most recent entries are kept in the ring.\n" "\n" " To display the current list of ring entries type 'ring' by itself on\n" " the command line. The entry highlighted by an asterisk ('*') is the\n" " current entry.\n" "\n" " To move to another entry in the ring type 'ring ' where is\n" " your desired entry from the ring position list.\n" "\n" " You may also use the 'forward' ('f') or 'back' ('b') commands to move\n" " to the previous or next entry in the ring, respectively.\n" "\n" " Note: Unlike the 'stack', 'push' and 'pop' commands, the ring tracks your\n" " location implicitly. Use the 'push' and 'pop' commands if you wish to\n" " store a specific location explicitly for later return.\n" "\n"), RING_ENTRIES); } void ring_add(void) { if (ring_head == -1) { /* only get here right after startup */ ring_head = 0; ring_tail = 0; ring_current = 0; iocur_ring[0] = *iocur_top; } else { if (ring_current == ring_head) { ring_head = (ring_head+1)%RING_ENTRIES; iocur_ring[ring_head] = *iocur_top; if (ring_head == ring_tail) ring_tail = (ring_tail+1)%RING_ENTRIES; ring_current = ring_head; } else { ring_current = (ring_current+1)%RING_ENTRIES; iocur_ring[ring_current] = *iocur_top; } } } int write_bbs( __int64_t bbno, int count, void *bufp, bbmap_t *bbmap) { int c; int i; int j; int rval = EINVAL; /* initialize for zero `count' case */ for (j = 0; j < count; j += bbmap ? 1 : count) { if (bbmap) bbno = bbmap->b[j]; if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { rval = errno; dbprintf(_("can't seek in filesystem at bb %lld\n"), bbno); return rval; } c = BBTOB(bbmap ? 1 : count); i = (int)write(x.dfd, (char *)bufp + BBTOB(j), c); if (i < 0) { rval = errno; } else if (i < c) { rval = -1; } else rval = 0; if (rval) break; } return rval; } int read_bbs( __int64_t bbno, int count, void **bufp, bbmap_t *bbmap) { void *buf; int c; int i; int j; int rval = EINVAL; if (count <= 0) count = 1; c = BBTOB(count); if (*bufp == NULL) buf = xmalloc(c); else buf = *bufp; for (j = 0; j < count; j += bbmap ? 1 : count) { if (bbmap) bbno = bbmap->b[j]; if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { rval = errno; dbprintf(_("can't seek in filesystem at bb %lld\n"), bbno); if (*bufp == NULL) xfree(buf); buf = NULL; } else { c = BBTOB(bbmap ? 1 : count); i = (int)read(x.dfd, (char *)buf + BBTOB(j), c); if (i < 0) { rval = errno; if (*bufp == NULL) xfree(buf); buf = NULL; } else if (i < c) { rval = -1; if (*bufp == NULL) xfree(buf); buf = NULL; } else rval = 0; } if (buf == NULL) break; } if (*bufp == NULL) *bufp = buf; return rval; } void write_cur(void) { int ret; if (iocur_sp < 0) { dbprintf(_("nothing to write\n")); return; } ret = write_bbs(iocur_top->bb, iocur_top->blen, iocur_top->buf, iocur_top->use_bbmap ? &iocur_top->bbmap : NULL); if (ret == -1) dbprintf(_("incomplete write, block: %lld\n"), (iocur_base + iocur_sp)->bb); else if (ret != 0) dbprintf(_("write error: %s\n"), strerror(ret)); /* re-read buffer from disk */ ret = read_bbs(iocur_top->bb, iocur_top->blen, &iocur_top->buf, iocur_top->use_bbmap ? &iocur_top->bbmap : NULL); if (ret == -1) dbprintf(_("incomplete read, block: %lld\n"), (iocur_base + iocur_sp)->bb); else if (ret != 0) dbprintf(_("read error: %s\n"), strerror(ret)); } void set_cur( const typ_t *t, __int64_t d, int c, int ring_flag, bbmap_t *bbmap) { xfs_ino_t dirino; xfs_ino_t ino; __uint16_t mode; if (iocur_sp < 0) { dbprintf(_("set_cur no stack element to set\n")); return; } #ifdef DEBUG if (bbmap) printf(_("xfs_db got a bbmap for %lld\n"), (long long)d); #endif ino = iocur_top->ino; dirino = iocur_top->dirino; mode = iocur_top->mode; pop_cur(); push_cur(); if (read_bbs(d, c, &iocur_top->buf, bbmap)) return; iocur_top->bb = d; iocur_top->blen = c; iocur_top->boff = 0; iocur_top->data = iocur_top->buf; iocur_top->len = BBTOB(c); iocur_top->off = d << BBSHIFT; iocur_top->typ = cur_typ = t; iocur_top->ino = ino; iocur_top->dirino = dirino; iocur_top->mode = mode; if ((iocur_top->use_bbmap = (bbmap != NULL))) iocur_top->bbmap = *bbmap; /* store location in ring */ if (ring_flag) ring_add(); } static void stack_help(void) { dbprintf(_( "\n" " The stack is used to explicitly store your location and data type\n" " for later return. The 'push' operation stores the current address\n" " and type on the stack, the 'pop' operation returns you to the\n" " position and datatype of the top entry on the stack.\n" "\n" " The 'stack' allows explicit location saves, see 'ring' for implicit\n" " position tracking.\n" "\n" )); } /*ARGSUSED*/ static int stack_f( int argc, char **argv) { int i; char tagbuf[8]; for (i = iocur_sp; i > 0; i--) { snprintf(tagbuf, sizeof(tagbuf), "%d: ", i); print_iocur(tagbuf, &iocur_base[i]); } return 0; } xfsprogs-3.1.9ubuntu2/db/Makefile0000664000000000000000000000254311330256617013651 0ustar # # Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_db HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ btblock.h bmroot.h check.h command.h convert.h debug.h \ dir.h dir2.h dir2sf.h dirshort.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ text.h type.h write.h attrset.h CFILES = $(HFILES:.h=.c) LSRCFILES = xfs_admin.sh xfs_check.sh xfs_ncheck.sh xfs_metadump.sh LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS += -static ifeq ($(ENABLE_READLINE),yes) LLDLIBS += $(LIBREADLINE) $(LIBTERMCAP) CFLAGS += -DENABLE_READLINE endif ifeq ($(ENABLE_EDITLINE),yes) LLDLIBS += $(LIBEDITLINE) $(LIBTERMCAP) CFLAGS += -DENABLE_EDITLINE endif default: depend $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) $(INSTALL) -m 755 xfs_admin.sh $(PKG_SBIN_DIR)/xfs_admin $(INSTALL) -m 755 xfs_check.sh $(PKG_SBIN_DIR)/xfs_check $(INSTALL) -m 755 xfs_ncheck.sh $(PKG_SBIN_DIR)/xfs_ncheck $(INSTALL) -m 755 xfs_metadump.sh $(PKG_SBIN_DIR)/xfs_metadump install-dev: -include .dep xfsprogs-3.1.9ubuntu2/db/freesp.c0000664000000000000000000002116311432652134013635 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "freesp.h" #include "io.h" #include "type.h" #include "output.h" #include "init.h" #include "malloc.h" typedef struct histent { int low; int high; long long count; long long blocks; } histent_t; static void addhistent(int h); static void addtohist(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len); static int freesp_f(int argc, char **argv); static void histinit(int maxlen); static int init(int argc, char **argv); static void printhist(void); static void scan_ag(xfs_agnumber_t agno); static void scanfunc_bno(struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf); static void scanfunc_cnt(struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf); static void scan_freelist(xfs_agf_t *agf); static void scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root, typnm_t typ, int nlevels, void (*func)(struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf)); static int usage(void); static int agcount; static xfs_agnumber_t *aglist; static int countflag; static int dumpflag; static int equalsize; static histent_t *hist; static int histcount; static int multsize; static int seen1; static int summaryflag; static long long totblocks; static long long totexts; static const cmdinfo_t freesp_cmd = { "freesp", NULL, freesp_f, 0, -1, 0, "[-bcdfs] [-a agno]... [-e binsize] [-h h1]... [-m binmult]", "summarize free space for filesystem", NULL }; static int inaglist( xfs_agnumber_t agno) { int i; if (agcount == 0) return 1; for (i = 0; i < agcount; i++) if (aglist[i] == agno) return 1; return 0; } /* * Report on freespace usage in xfs filesystem. */ static int freesp_f( int argc, char **argv) { xfs_agnumber_t agno; if (!init(argc, argv)) return 0; for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { if (inaglist(agno)) scan_ag(agno); } if (histcount) printhist(); if (summaryflag) { dbprintf(_("total free extents %lld\n"), totexts); dbprintf(_("total free blocks %lld\n"), totblocks); dbprintf(_("average free extent size %g\n"), (double)totblocks / (double)totexts); } if (aglist) xfree(aglist); if (hist) xfree(hist); return 0; } void freesp_init(void) { add_command(&freesp_cmd); } static void aglistadd( char *a) { aglist = xrealloc(aglist, (agcount + 1) * sizeof(*aglist)); aglist[agcount] = (xfs_agnumber_t)atoi(a); agcount++; } static int init( int argc, char **argv) { int c; int speced = 0; agcount = countflag = dumpflag = equalsize = multsize = optind = 0; histcount = seen1 = summaryflag = 0; totblocks = totexts = 0; aglist = NULL; hist = NULL; while ((c = getopt(argc, argv, "a:bcde:h:m:s")) != EOF) { switch (c) { case 'a': aglistadd(optarg); break; case 'b': if (speced) return usage(); multsize = 2; speced = 1; break; case 'c': countflag = 1; break; case 'd': dumpflag = 1; break; case 'e': if (speced) return usage(); equalsize = atoi(optarg); speced = 1; break; case 'h': if (speced && !histcount) return usage(); addhistent(atoi(optarg)); speced = 1; break; case 'm': if (speced) return usage(); multsize = atoi(optarg); speced = 1; break; case 's': summaryflag = 1; break; case '?': return usage(); } } if (optind != argc) return usage(); if (!speced) multsize = 2; histinit((int)mp->m_sb.sb_agblocks); return 1; } static int usage(void) { dbprintf(_("freesp arguments: [-bcds] [-a agno] [-e binsize] [-h h1]... " "[-m binmult]\n")); return 0; } static void scan_ag( xfs_agnumber_t agno) { xfs_agf_t *agf; push_cur(); set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agf = iocur_top->data; scan_freelist(agf); if (countflag) scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), TYP_CNTBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), scanfunc_cnt); else scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), TYP_BNOBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), scanfunc_bno); pop_cur(); } static void scan_freelist( xfs_agf_t *agf) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agfl_t *agfl; xfs_agblock_t bno; int i; if (be32_to_cpu(agf->agf_flcount) == 0) return; push_cur(); set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agfl = iocur_top->data; i = be32_to_cpu(agf->agf_flfirst); for (;;) { bno = be32_to_cpu(agfl->agfl_bno[i]); addtohist(seqno, bno, 1); if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; } pop_cur(); } static void scan_sbtree( xfs_agf_t *agf, xfs_agblock_t root, typnm_t typ, int nlevels, void (*func)(struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf)) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[typ], XFS_AGB_TO_DADDR(mp, seqno, root), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { dbprintf(_("can't read btree block %u/%u\n"), seqno, root); return; } (*func)(iocur_top->data, typ, nlevels - 1, agf); pop_cur(); } /*ARGSUSED*/ static void scanfunc_bno( struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf) { int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) return; if (level == 0) { rp = XFS_ALLOC_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) addtohist(be32_to_cpu(agf->agf_seqno), be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount)); return; } pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), typ, level, scanfunc_bno); } static void scanfunc_cnt( struct xfs_btree_block *block, typnm_t typ, int level, xfs_agf_t *agf) { int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) return; if (level == 0) { rp = XFS_ALLOC_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) addtohist(be32_to_cpu(agf->agf_seqno), be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount)); return; } pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), typ, level, scanfunc_cnt); } static void addhistent( int h) { hist = xrealloc(hist, (histcount + 1) * sizeof(*hist)); if (h == 0) h = 1; hist[histcount].low = h; hist[histcount].count = hist[histcount].blocks = 0; histcount++; if (h == 1) seen1 = 1; } static void addtohist( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len) { int i; if (dumpflag) dbprintf("%8d %8d %8d\n", agno, agbno, len); totexts++; totblocks += len; for (i = 0; i < histcount; i++) { if (hist[i].high >= len) { hist[i].count++; hist[i].blocks += len; break; } } } static int hcmp( const void *a, const void *b) { return ((histent_t *)a)->low - ((histent_t *)b)->low; } static void histinit( int maxlen) { int i; if (equalsize) { for (i = 1; i < maxlen; i += equalsize) addhistent(i); } else if (multsize) { for (i = 1; i < maxlen; i *= multsize) addhistent(i); } else { if (!seen1) addhistent(1); qsort(hist, histcount, sizeof(*hist), hcmp); } for (i = 0; i < histcount; i++) { if (i < histcount - 1) hist[i].high = hist[i + 1].low - 1; else hist[i].high = maxlen; } } static void printhist(void) { int i; dbprintf("%7s %7s %7s %7s %6s\n", _("from"), _("to"), _("extents"), _("blocks"), _("pct")); for (i = 0; i < histcount; i++) { if (hist[i].count) dbprintf("%7d %7d %7lld %7lld %6.2f\n", hist[i].low, hist[i].high, hist[i].count, hist[i].blocks, hist[i].blocks * 100.0 / totblocks); } } xfsprogs-3.1.9ubuntu2/db/quit.h0000664000000000000000000000136511140033220013323 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void quit_init(void); xfsprogs-3.1.9ubuntu2/db/echo.c0000664000000000000000000000224311146407622013267 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "echo.h" #include "output.h" static int echo_f(int argc, char **argv); static const cmdinfo_t echo_cmd = { "echo", NULL, echo_f, 0, -1, 0, N_("[args]..."), N_("echo arguments"), NULL }; /*ARGSUSED*/ static int echo_f( int argc, char **argv) { char *c; for (c = *(++argv); c; c = *(++argv)) dbprintf("%s ", c); dbprintf("\n"); return 0; } void echo_init(void) { add_command(&echo_cmd); } xfsprogs-3.1.9ubuntu2/db/text.c0000664000000000000000000000352111140033220013314 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "block.h" #include "bmap.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "io.h" #include "output.h" #include "init.h" static void print_rawtext(void *data, int len); void print_text( const field_t *fields, int argc, char **argv) { print_rawtext(iocur_top->data, iocur_top->len); } static void print_rawtext( void *data, int len) { int i; int j; int lastaddr; int offchars; unsigned char *p; lastaddr = (len - 1) & ~(16 - 1); if (lastaddr < 0x10) offchars = 1; else if (lastaddr < 0x100) offchars = 2; else if (lastaddr < 0x1000) offchars = 3; else offchars = 4; for (i = 0, p = data; i < len; i += 16) { unsigned char *s = p; dbprintf("%-0*.*x: ", offchars, offchars, i); for (j = 0; j < 16 && i + j < len; j++, p++) { dbprintf("%02x ", *p); } dbprintf(" "); for (j = 0; j < 16 && i + j < len; j++, s++) { if (isalnum(*s)) dbprintf("%c", *s); else dbprintf(".", *s); } dbprintf("\n"); } } xfsprogs-3.1.9ubuntu2/db/write.h0000664000000000000000000000173411140033220013473 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct field; extern void write_init(void); extern void write_block(const field_t *fields, int argc, char **argv); extern void write_string(const field_t *fields, int argc, char **argv); extern void write_struct(const field_t *fields, int argc, char **argv); xfsprogs-3.1.9ubuntu2/db/attrset.c0000664000000000000000000001334511650373060014042 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "attrset.h" #include "io.h" #include "output.h" #include "type.h" #include "init.h" #include "fprint.h" #include "faddr.h" #include "field.h" #include "inode.h" #include "malloc.h" static int attr_set_f(int argc, char **argv); static int attr_remove_f(int argc, char **argv); static void attrset_help(void); static const cmdinfo_t attr_set_cmd = { "attr_set", "aset", attr_set_f, 1, -1, 0, N_("[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name"), N_("set the named attribute on the current inode"), attrset_help }; static const cmdinfo_t attr_remove_cmd = { "attr_remove", "aremove", attr_remove_f, 1, -1, 0, N_("[-r|-s|-p|-u] [-n] name"), N_("remove the named attribute from the current inode"), attrset_help }; static void attrset_help(void) { dbprintf(_( "\n" " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n" " the extended attribute allocation and removal code.\n" " Both commands require an attribute name to be specified, and the attr_set\n" " command allows an optional value length (-v) to be provided as well.\n" " There are 4 namespace flags:\n" " -r -- 'root'\n" " -u -- 'user' (default)\n" " -s -- 'secure'\n" "\n" " For attr_set, these options further define the type of set operation:\n" " -C -- 'create' - create attribute, fail if it already exists\n" " -R -- 'replace' - replace attribute, fail if it does not exist\n" " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n" "\n")); } void attrset_init(void) { if (!expert_mode) return; add_command(&attr_set_cmd); add_command(&attr_remove_cmd); } static int attr_set_f( int argc, char **argv) { xfs_inode_t *ip = NULL; char *name, *value, *sp; int c, valuelen = 0, flags = 0; if (cur_typ == NULL) { dbprintf(_("no current type\n")); return 0; } if (cur_typ->typnm != TYP_INODE) { dbprintf(_("current type is not inode\n")); return 0; } while ((c = getopt(argc, argv, "rusCRnv:")) != EOF) { switch (c) { /* namespaces */ case 'r': flags |= LIBXFS_ATTR_ROOT; flags &= ~LIBXFS_ATTR_SECURE; break; case 'u': flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE); break; case 's': flags |= LIBXFS_ATTR_SECURE; flags &= ~LIBXFS_ATTR_ROOT; break; /* modifiers */ case 'C': flags |= LIBXFS_ATTR_CREATE; break; case 'R': flags |= LIBXFS_ATTR_REPLACE; break; case 'n': mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR; break; /* value length */ case 'v': valuelen = (int)strtol(optarg, &sp, 0); if (*sp != '\0' || valuelen < 0 || valuelen > 64*1024) { dbprintf(_("bad attr_set valuelen %s\n"), optarg); return 0; } break; default: dbprintf(_("bad option for attr_set command\n")); return 0; } } if (optind != argc - 1) { dbprintf(_("too few options for attr_set (no name given)\n")); return 0; } name = argv[optind]; if (valuelen) { value = (char *)memalign(getpagesize(), valuelen); if (!value) { dbprintf(_("cannot allocate buffer (%d)\n"), valuelen); goto out; } memset(value, 0xfeedface, valuelen); } else { value = NULL; } if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) { dbprintf(_("failed to iget inode %llu\n"), (unsigned long long)iocur_top->ino); goto out; } if (libxfs_attr_set(ip, (unsigned char *)name, (unsigned char *)value, valuelen, flags)) { dbprintf(_("failed to set attr %s on inode %llu\n"), name, (unsigned long long)iocur_top->ino); goto out; } /* refresh with updated inode contents */ set_cur_inode(iocur_top->ino); out: mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR; if (ip) libxfs_iput(ip, 0); if (value) free(value); return 0; } static int attr_remove_f( int argc, char **argv) { xfs_inode_t *ip = NULL; char *name; int c, flags = 0; if (cur_typ == NULL) { dbprintf(_("no current type\n")); return 0; } if (cur_typ->typnm != TYP_INODE) { dbprintf(_("current type is not inode\n")); return 0; } while ((c = getopt(argc, argv, "rusn")) != EOF) { switch (c) { /* namespaces */ case 'r': flags |= LIBXFS_ATTR_ROOT; flags &= ~LIBXFS_ATTR_SECURE; break; case 'u': flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE); break; case 's': flags |= LIBXFS_ATTR_SECURE; flags &= ~LIBXFS_ATTR_ROOT; break; case 'n': mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR; break; default: dbprintf(_("bad option for attr_remove command\n")); return 0; } } if (optind != argc - 1) { dbprintf(_("too few options for attr_remove (no name given)\n")); return 0; } name = argv[optind]; if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) { dbprintf(_("failed to iget inode %llu\n"), (unsigned long long)iocur_top->ino); goto out; } if (libxfs_attr_remove(ip, (unsigned char *)name, flags)) { dbprintf(_("failed to remove attr %s from inode %llu\n"), name, (unsigned long long)iocur_top->ino); goto out; } /* refresh with updated inode contents */ set_cur_inode(iocur_top->ino); out: mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR; if (ip) libxfs_iput(ip, 0); return 0; } xfsprogs-3.1.9ubuntu2/db/dir2sf.c0000664000000000000000000001237011650373060013542 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "bit.h" #include "dir2sf.h" static int dir2_inou_i4_count(void *obj, int startoff); static int dir2_inou_i8_count(void *obj, int startoff); static int dir2_sf_entry_inumber_offset(void *obj, int startoff, int idx); static int dir2_sf_entry_name_count(void *obj, int startoff); static int dir2_sf_list_count(void *obj, int startoff); static int dir2_sf_list_offset(void *obj, int startoff, int idx); #define OFF(f) bitize(offsetof(xfs_dir2_sf_t, f)) const field_t dir2sf_flds[] = { { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(hdr)), C1, 0, TYP_NONE }, { "list", FLDT_DIR2_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count, FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; #define UOFF(f) bitize(offsetof(xfs_dir2_inou_t, f)) const field_t dir2_inou_flds[] = { { "i8", FLDT_DIR2_INO8, OI(UOFF(i8)), dir2_inou_i8_count, FLD_COUNT, TYP_INODE }, { "i4", FLDT_DIR2_INO4, OI(UOFF(i4)), dir2_inou_i4_count, FLD_COUNT, TYP_INODE }, { NULL } }; #define HOFF(f) bitize(offsetof(xfs_dir2_sf_hdr_t, f)) const field_t dir2_sf_hdr_flds[] = { { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE }, { "i8count", FLDT_UINT8D, OI(HOFF(i8count)), C1, 0, TYP_NONE }, { "parent", FLDT_DIR2_INOU, OI(HOFF(parent)), C1, 0, TYP_NONE }, { NULL } }; #define EOFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f)) const field_t dir2_sf_entry_flds[] = { { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE }, { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count, FLD_COUNT, TYP_NONE }, { "inumber", FLDT_DIR2_INOU, dir2_sf_entry_inumber_offset, C1, FLD_OFFSET, TYP_NONE }, { NULL } }; /*ARGSUSED*/ static int dir2_inou_i4_count( void *obj, int startoff) { xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); return sf->hdr.i8count == 0; } /*ARGSUSED*/ static int dir2_inou_i8_count( void *obj, int startoff) { xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); return sf->hdr.i8count != 0; } /*ARGSUSED*/ int dir2_inou_size( void *obj, int startoff, int idx) { xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(obj); return bitize(sf->hdr.i8count ? (uint)sizeof(xfs_dir2_ino8_t) : (uint)sizeof(xfs_dir2_ino4_t)); } static int dir2_sf_entry_name_count( void *obj, int startoff) { xfs_dir2_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); return e->namelen; } /*ARGSUSED*/ static int dir2_sf_entry_inumber_offset( void *obj, int startoff, int idx) { xfs_dir2_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e)); } int dir2_sf_entry_size( void *obj, int startoff, int idx) { xfs_dir2_sf_entry_t *e; int i; xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) e = xfs_dir2_sf_nextentry(sf, e); return bitize((int)xfs_dir2_sf_entsize_byentry(sf, e)); } /*ARGSUSED*/ int dir2_sf_hdr_size( void *obj, int startoff, int idx) { xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); return bitize(xfs_dir2_sf_hdr_size(sf->hdr.i8count)); } static int dir2_sf_list_count( void *obj, int startoff) { xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); return sf->hdr.count; } static int dir2_sf_list_offset( void *obj, int startoff, int idx) { xfs_dir2_sf_entry_t *e; int i; xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < idx; i++) e = xfs_dir2_sf_nextentry(sf, e); return bitize((int)((char *)e - (char *)sf)); } /*ARGSUSED*/ int dir2sf_size( void *obj, int startoff, int idx) { xfs_dir2_sf_entry_t *e; int i; xfs_dir2_sf_t *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir2_sf_t *)((char *)obj + byteize(startoff)); e = xfs_dir2_sf_firstentry(sf); for (i = 0; i < sf->hdr.count; i++) e = xfs_dir2_sf_nextentry(sf, e); return bitize((int)((char *)e - (char *)sf)); } xfsprogs-3.1.9ubuntu2/db/type.h0000664000000000000000000000352311140033220013320 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct field; #define szof(x,y) sizeof(((x *)0)->y) #define szcount(x,y) (szof(x,y) / szof(x,y[0])) typedef enum typnm { TYP_AGF, TYP_AGFL, TYP_AGI, TYP_ATTR, TYP_BMAPBTA, TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_DATA, TYP_DIR, TYP_DIR2, TYP_DQBLK, TYP_INOBT, TYP_INODATA, TYP_INODE, TYP_LOG, TYP_RTBITMAP, TYP_RTSUMMARY, TYP_SB, TYP_SYMLINK, TYP_TEXT, TYP_NONE } typnm_t; #define DB_WRITE 1 #define DB_READ 0 typedef void (*opfunc_t)(const struct field *fld, int argc, char **argv); typedef void (*pfunc_t)(int action, const struct field *fld, int argc, char **argv); typedef struct typ { typnm_t typnm; char *name; pfunc_t pfunc; const struct field *fields; } typ_t; extern const typ_t typtab[], *cur_typ; extern void type_init(void); extern void handle_block(int action, const struct field *fields, int argc, char **argv); extern void handle_string(int action, const struct field *fields, int argc, char **argv); extern void handle_struct(int action, const struct field *fields, int argc, char **argv); extern void handle_text(int action, const struct field *fields, int argc, char **argv); xfsprogs-3.1.9ubuntu2/db/block.h0000664000000000000000000000152111140033220013425 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct field; extern void block_init(void); extern void print_block(const struct field *fields, int argc, char **argv); xfsprogs-3.1.9ubuntu2/db/inode.c0000664000000000000000000004046111650373060013451 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "io.h" #include "print.h" #include "block.h" #include "bit.h" #include "output.h" #include "init.h" static int inode_a_bmbt_count(void *obj, int startoff); static int inode_a_bmx_count(void *obj, int startoff); static int inode_a_count(void *obj, int startoff); static int inode_a_offset(void *obj, int startoff, int idx); static int inode_a_sfattr_count(void *obj, int startoff); static int inode_core_nlinkv2_count(void *obj, int startoff); static int inode_core_onlink_count(void *obj, int startoff); static int inode_core_projid_count(void *obj, int startoff); static int inode_core_nlinkv1_count(void *obj, int startoff); static int inode_f(int argc, char **argv); static int inode_u_offset(void *obj, int startoff, int idx); static int inode_u_bmbt_count(void *obj, int startoff); static int inode_u_bmx_count(void *obj, int startoff); static int inode_u_c_count(void *obj, int startoff); static int inode_u_dev_count(void *obj, int startoff); static int inode_u_muuid_count(void *obj, int startoff); static int inode_u_sfdir_count(void *obj, int startoff); static int inode_u_sfdir2_count(void *obj, int startoff); static int inode_u_symlink_count(void *obj, int startoff); static const cmdinfo_t inode_cmd = { "inode", NULL, inode_f, 0, 1, 1, "[inode#]", "set current inode", NULL }; const field_t inode_hfld[] = { { "", FLDT_INODE, OI(0), C1, 0, TYP_NONE }, { NULL } }; /* XXX: fix this up! */ #define OFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f)) const field_t inode_flds[] = { { "core", FLDT_DINODE_CORE, OI(OFF(magic)), C1, 0, TYP_NONE }, { "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0, TYP_INODE }, { "u", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE }, { "a", FLDT_DINODE_A, inode_a_offset, inode_a_count, FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; #define COFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f)) const field_t inode_core_flds[] = { { "magic", FLDT_UINT16X, OI(COFF(magic)), C1, 0, TYP_NONE }, { "mode", FLDT_UINT16O, OI(COFF(mode)), C1, 0, TYP_NONE }, { "version", FLDT_INT8D, OI(COFF(version)), C1, 0, TYP_NONE }, { "format", FLDT_DINODE_FMT, OI(COFF(format)), C1, 0, TYP_NONE }, { "nlinkv1", FLDT_UINT16D, OI(COFF(onlink)), inode_core_nlinkv1_count, FLD_COUNT, TYP_NONE }, { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count, FLD_COUNT, TYP_NONE }, { "onlink", FLDT_UINT16D, OI(COFF(onlink)), inode_core_onlink_count, FLD_COUNT, TYP_NONE }, { "projid_lo", FLDT_UINT16D, OI(COFF(projid_lo)), inode_core_projid_count, FLD_COUNT, TYP_NONE }, { "projid_hi", FLDT_UINT16D, OI(COFF(projid_hi)), inode_core_projid_count, FLD_COUNT, TYP_NONE }, { "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE }, { "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE }, { "flushiter", FLDT_UINT16D, OI(COFF(flushiter)), C1, 0, TYP_NONE }, { "atime", FLDT_TIMESTAMP, OI(COFF(atime)), C1, 0, TYP_NONE }, { "mtime", FLDT_TIMESTAMP, OI(COFF(mtime)), C1, 0, TYP_NONE }, { "ctime", FLDT_TIMESTAMP, OI(COFF(ctime)), C1, 0, TYP_NONE }, { "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE }, { "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE }, { "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE }, { "nextents", FLDT_EXTNUM, OI(COFF(nextents)), C1, 0, TYP_NONE }, { "naextents", FLDT_AEXTNUM, OI(COFF(anextents)), C1, 0, TYP_NONE }, { "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE }, { "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE }, { "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE }, { "dmstate", FLDT_UINT16D, OI(COFF(dmstate)), C1, 0, TYP_NONE }, { "flags", FLDT_UINT16X, OI(COFF(flags)), C1, FLD_SKIPALL, TYP_NONE }, { "newrtbm", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NEWRTBM_BIT - 1), C1, 0, TYP_NONE }, { "prealloc", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_PREALLOC_BIT - 1), C1, 0, TYP_NONE }, { "realtime", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_REALTIME_BIT - 1), C1, 0, TYP_NONE }, { "immutable", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_IMMUTABLE_BIT-1), C1, 0, TYP_NONE }, { "append", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_APPEND_BIT - 1), C1, 0, TYP_NONE }, { "sync", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_SYNC_BIT - 1), C1, 0, TYP_NONE }, { "noatime", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NOATIME_BIT - 1), C1, 0, TYP_NONE }, { "nodump", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NODUMP_BIT - 1), C1, 0, TYP_NONE }, { "rtinherit", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_RTINHERIT_BIT-1), C1, 0, TYP_NONE }, { "projinherit", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_PROJINHERIT_BIT-1),C1, 0, TYP_NONE }, { "nosymlinks", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NOSYMLINKS_BIT-1), C1, 0, TYP_NONE }, { "extsz", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_EXTSIZE_BIT-1),C1, 0, TYP_NONE }, { "extszinherit", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_EXTSZINHERIT_BIT-1),C1, 0, TYP_NONE }, { "nodefrag", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NODEFRAG_BIT-1),C1, 0, TYP_NONE }, { "filestream", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_FILESTREAM_BIT-1),C1, 0, TYP_NONE }, { "gen", FLDT_UINT32D, OI(COFF(gen)), C1, 0, TYP_NONE }, { NULL } }; #define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f)) const field_t timestamp_flds[] = { { "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE }, { "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE }, { NULL } }; const field_t inode_u_flds[] = { { "bmbt", FLDT_BMROOTD, NULL, inode_u_bmbt_count, FLD_COUNT, TYP_NONE }, { "bmx", FLDT_BMAPBTDREC, NULL, inode_u_bmx_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "c", FLDT_CHARNS, NULL, inode_u_c_count, FLD_COUNT, TYP_NONE }, { "dev", FLDT_DEV, NULL, inode_u_dev_count, FLD_COUNT, TYP_NONE }, { "muuid", FLDT_UUID, NULL, inode_u_muuid_count, FLD_COUNT, TYP_NONE }, { "sfdir", FLDT_DIRSHORT, NULL, inode_u_sfdir_count, FLD_COUNT, TYP_NONE }, { "sfdir2", FLDT_DIR2SF, NULL, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE }, { "symlink", FLDT_CHARNS, NULL, inode_u_symlink_count, FLD_COUNT, TYP_NONE }, { NULL } }; const field_t inode_a_flds[] = { { "bmbt", FLDT_BMROOTA, NULL, inode_a_bmbt_count, FLD_COUNT, TYP_NONE }, { "bmx", FLDT_BMAPBTAREC, NULL, inode_a_bmx_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "sfattr", FLDT_ATTRSHORT, NULL, inode_a_sfattr_count, FLD_COUNT, TYP_NONE }, { NULL } }; static const char *dinode_fmt_name[] = { "dev", "local", "extents", "btree", "uuid" }; static const int dinode_fmt_name_size = sizeof(dinode_fmt_name) / sizeof(dinode_fmt_name[0]); /*ARGSUSED*/ int fp_dinode_fmt( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { int bitpos; xfs_dinode_fmt_t f; int i; for (i = 0, bitpos = bit; i < count; i++, bitpos += size) { f = (xfs_dinode_fmt_t)getbitval(obj, bitpos, size, BVSIGNED); if (array) dbprintf("%d:", i + base); if (f < 0 || f >= dinode_fmt_name_size) dbprintf("%d", (int)f); else dbprintf("%d (%s)", (int)f, dinode_fmt_name[(int)f]); if (i < count - 1) dbprintf(" "); } return 1; } static int inode_a_bmbt_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); return dip->di_aformat == XFS_DINODE_FMT_BTREE; } static int inode_a_bmx_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ? be16_to_cpu(dip->di_anextents) : 0; } static int inode_a_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(startoff == 0); dip = obj; return XFS_DFORK_Q(dip); } static int inode_a_offset( void *obj, int startoff, int idx) { xfs_dinode_t *dip; ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; ASSERT(XFS_DFORK_Q(dip)); return bitize((int)((char *)XFS_DFORK_APTR(dip) - (char *)dip)); } static int inode_a_sfattr_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; if (!XFS_DFORK_Q(dip)) return 0; ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff)); return dip->di_aformat == XFS_DINODE_FMT_LOCAL; } int inode_a_size( void *obj, int startoff, int idx) { xfs_attr_shortform_t *asf; xfs_dinode_t *dip; ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); return bitize(be16_to_cpu(asf->hdr.totsize)); case XFS_DINODE_FMT_EXTENTS: return (int)be16_to_cpu(dip->di_anextents) * bitsz(xfs_bmbt_rec_t); case XFS_DINODE_FMT_BTREE: return bitize((int)XFS_DFORK_ASIZE(dip, mp)); default: return 0; } } static int inode_core_nlinkv1_count( void *obj, int startoff) { xfs_dinode_t *dic; ASSERT(startoff == 0); ASSERT(obj == iocur_top->data); dic = obj; return dic->di_version == 1; } static int inode_core_nlinkv2_count( void *obj, int startoff) { xfs_dinode_t *dic; ASSERT(startoff == 0); ASSERT(obj == iocur_top->data); dic = obj; return dic->di_version == 2; } static int inode_core_onlink_count( void *obj, int startoff) { xfs_dinode_t *dic; ASSERT(startoff == 0); ASSERT(obj == iocur_top->data); dic = obj; return dic->di_version == 2; } static int inode_core_projid_count( void *obj, int startoff) { xfs_dinode_t *dic; ASSERT(startoff == 0); ASSERT(obj == iocur_top->data); dic = obj; return dic->di_version == 2; } static int inode_f( int argc, char **argv) { xfs_ino_t ino; char *p; if (argc > 1) { ino = strtoull(argv[1], &p, 0); if (*p != '\0') { dbprintf(_("bad value for inode number %s\n"), argv[1]); return 0; } set_cur_inode(ino); } else if (iocur_top->ino == NULLFSINO) dbprintf(_("no current inode\n")); else dbprintf(_("current inode number is %lld\n"), iocur_top->ino); return 0; } void inode_init(void) { add_command(&inode_cmd); } typnm_t inode_next_type(void) { switch (iocur_top->mode & S_IFMT) { case S_IFDIR: return xfs_sb_version_hasdirv2(&mp->m_sb) ? TYP_DIR2 : TYP_DIR; case S_IFLNK: return TYP_SYMLINK; case S_IFREG: if (iocur_top->ino == mp->m_sb.sb_rbmino) return TYP_RTBITMAP; else if (iocur_top->ino == mp->m_sb.sb_rsumino) return TYP_RTSUMMARY; else if (iocur_top->ino == mp->m_sb.sb_uquotino || iocur_top->ino == mp->m_sb.sb_gquotino) return TYP_DQBLK; else return TYP_DATA; default: return TYP_NONE; } } int inode_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_inodesize); } static int inode_u_offset( void *obj, int startoff, int idx) { xfs_dinode_t *dip; ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; return bitize((int)((char *)XFS_DFORK_DPTR(dip) - (char *)dip)); } static int inode_u_bmbt_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_BTREE; } static int inode_u_bmx_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_EXTENTS ? be32_to_cpu(dip->di_nextents) : 0; } static int inode_u_c_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG ? (int)be64_to_cpu(dip->di_size) : 0; } static int inode_u_dev_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_DEV; } static int inode_u_muuid_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_UUID; } static int inode_u_sfdir_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR && !xfs_sb_version_hasdirv2(&mp->m_sb); } static int inode_u_sfdir2_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR && xfs_sb_version_hasdirv2(&mp->m_sb); } int inode_u_size( void *obj, int startoff, int idx) { xfs_dinode_t *dip; ASSERT(startoff == 0); ASSERT(idx == 0); dip = obj; switch (dip->di_format) { case XFS_DINODE_FMT_DEV: return bitsz(xfs_dev_t); case XFS_DINODE_FMT_LOCAL: return bitize((int)be64_to_cpu(dip->di_size)); case XFS_DINODE_FMT_EXTENTS: return (int)be32_to_cpu(dip->di_nextents) * bitsz(xfs_bmbt_rec_t); case XFS_DINODE_FMT_BTREE: return bitize((int)XFS_DFORK_DSIZE(dip, mp)); case XFS_DINODE_FMT_UUID: return bitsz(uuid_t); default: return 0; } } static int inode_u_symlink_count( void *obj, int startoff) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff)); return dip->di_format == XFS_DINODE_FMT_LOCAL && (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFLNK ? (int)be64_to_cpu(dip->di_size) : 0; } void set_cur_inode( xfs_ino_t ino) { xfs_agblock_t agbno; xfs_agino_t agino; xfs_agnumber_t agno; xfs_dinode_t *dip; int offset; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); offset = XFS_AGINO_TO_OFFSET(mp, agino); if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || offset >= mp->m_sb.sb_inopblock || XFS_AGINO_TO_INO(mp, agno, agino) != ino) { dbprintf(_("bad inode number %lld\n"), ino); return; } cur_agno = agno; /* * First set_cur to the block with the inode * then use off_cur to get the right part of the buffer. */ ASSERT(typtab[TYP_INODE].typnm == TYP_INODE); /* ingore ring update here, do it explicitly below */ set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); dip = iocur_top->data; iocur_top->ino = ino; iocur_top->mode = be16_to_cpu(dip->di_mode); if ((iocur_top->mode & S_IFMT) == S_IFDIR) iocur_top->dirino = ino; /* track updated info in ring */ ring_add(); } xfsprogs-3.1.9ubuntu2/db/dir2.c0000664000000000000000000004475211140033220013203 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bit.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "dir.h" #include "dir2.h" #include "init.h" static int dir2_block_hdr_count(void *obj, int startoff); static int dir2_block_leaf_count(void *obj, int startoff); static int dir2_block_leaf_offset(void *obj, int startoff, int idx); static int dir2_block_tail_count(void *obj, int startoff); static int dir2_block_tail_offset(void *obj, int startoff, int idx); static int dir2_block_u_count(void *obj, int startoff); static int dir2_block_u_offset(void *obj, int startoff, int idx); static int dir2_data_union_freetag_count(void *obj, int startoff); static int dir2_data_union_inumber_count(void *obj, int startoff); static int dir2_data_union_length_count(void *obj, int startoff); static int dir2_data_union_name_count(void *obj, int startoff); static int dir2_data_union_namelen_count(void *obj, int startoff); static int dir2_data_union_tag_count(void *obj, int startoff); static int dir2_data_union_tag_offset(void *obj, int startoff, int idx); static int dir2_data_hdr_count(void *obj, int startoff); static int dir2_data_u_count(void *obj, int startoff); static int dir2_data_u_offset(void *obj, int startoff, int idx); static int dir2_free_bests_count(void *obj, int startoff); static int dir2_free_hdr_count(void *obj, int startoff); static int dir2_leaf_bests_count(void *obj, int startoff); static int dir2_leaf_bests_offset(void *obj, int startoff, int idx); static int dir2_leaf_ents_count(void *obj, int startoff); static int dir2_leaf_hdr_count(void *obj, int startoff); static int dir2_leaf_tail_count(void *obj, int startoff); static int dir2_leaf_tail_offset(void *obj, int startoff, int idx); static int dir2_node_btree_count(void *obj, int startoff); static int dir2_node_hdr_count(void *obj, int startoff); const field_t dir2_hfld[] = { { "", FLDT_DIR2, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define BOFF(f) bitize(offsetof(xfs_dir2_block_t, f)) #define DOFF(f) bitize(offsetof(xfs_dir2_data_t, f)) #define FOFF(f) bitize(offsetof(xfs_dir2_free_t, f)) #define LOFF(f) bitize(offsetof(xfs_dir2_leaf_t, f)) #define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f)) const field_t dir2_flds[] = { { "bhdr", FLDT_DIR2_DATA_HDR, OI(BOFF(hdr)), dir2_block_hdr_count, FLD_COUNT, TYP_NONE }, { "bu", FLDT_DIR2_DATA_UNION, dir2_block_u_offset, dir2_block_u_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "bleaf", FLDT_DIR2_LEAF_ENTRY, dir2_block_leaf_offset, dir2_block_leaf_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "btail", FLDT_DIR2_BLOCK_TAIL, dir2_block_tail_offset, dir2_block_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "dhdr", FLDT_DIR2_DATA_HDR, OI(DOFF(hdr)), dir2_data_hdr_count, FLD_COUNT, TYP_NONE }, { "du", FLDT_DIR2_DATA_UNION, dir2_data_u_offset, dir2_data_u_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "lhdr", FLDT_DIR2_LEAF_HDR, OI(LOFF(hdr)), dir2_leaf_hdr_count, FLD_COUNT, TYP_NONE }, { "lbests", FLDT_DIR2_DATA_OFF, dir2_leaf_bests_offset, dir2_leaf_bests_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "lents", FLDT_DIR2_LEAF_ENTRY, OI(LOFF(ents)), dir2_leaf_ents_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "ltail", FLDT_DIR2_LEAF_TAIL, dir2_leaf_tail_offset, dir2_leaf_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, { "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir2_node_hdr_count, FLD_COUNT, TYP_NONE }, { "nbtree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)), dir2_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "fhdr", FLDT_DIR2_FREE_HDR, OI(FOFF(hdr)), dir2_free_hdr_count, FLD_COUNT, TYP_NONE }, { "fbests", FLDT_DIR2_DATA_OFFNZ, OI(FOFF(bests)), dir2_free_bests_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { NULL } }; #define BTOFF(f) bitize(offsetof(xfs_dir2_block_tail_t, f)) const field_t dir2_block_tail_flds[] = { { "count", FLDT_UINT32D, OI(BTOFF(count)), C1, 0, TYP_NONE }, { "stale", FLDT_UINT32D, OI(BTOFF(stale)), C1, 0, TYP_NONE }, { NULL } }; #define DFOFF(f) bitize(offsetof(xfs_dir2_data_free_t, f)) const field_t dir2_data_free_flds[] = { { "offset", FLDT_DIR2_DATA_OFF, OI(DFOFF(offset)), C1, 0, TYP_NONE }, { "length", FLDT_DIR2_DATA_OFF, OI(DFOFF(length)), C1, 0, TYP_NONE }, { NULL } }; #define DHOFF(f) bitize(offsetof(xfs_dir2_data_hdr_t, f)) const field_t dir2_data_hdr_flds[] = { { "magic", FLDT_UINT32X, OI(DHOFF(magic)), C1, 0, TYP_NONE }, { "bestfree", FLDT_DIR2_DATA_FREE, OI(DHOFF(bestfree)), CI(XFS_DIR2_DATA_FD_COUNT), FLD_ARRAY, TYP_NONE }, { NULL } }; #define DEOFF(f) bitize(offsetof(xfs_dir2_data_entry_t, f)) #define DUOFF(f) bitize(offsetof(xfs_dir2_data_unused_t, f)) const field_t dir2_data_union_flds[] = { { "freetag", FLDT_UINT16X, OI(DUOFF(freetag)), dir2_data_union_freetag_count, FLD_COUNT, TYP_NONE }, { "inumber", FLDT_INO, OI(DEOFF(inumber)), dir2_data_union_inumber_count, FLD_COUNT, TYP_INODE }, { "length", FLDT_DIR2_DATA_OFF, OI(DUOFF(length)), dir2_data_union_length_count, FLD_COUNT, TYP_NONE }, { "namelen", FLDT_UINT8D, OI(DEOFF(namelen)), dir2_data_union_namelen_count, FLD_COUNT, TYP_NONE }, { "name", FLDT_CHARNS, OI(DEOFF(name)), dir2_data_union_name_count, FLD_COUNT, TYP_NONE }, { "tag", FLDT_DIR2_DATA_OFF, dir2_data_union_tag_offset, dir2_data_union_tag_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, { NULL } }; #define LEOFF(f) bitize(offsetof(xfs_dir2_leaf_entry_t, f)) const field_t dir2_leaf_entry_flds[] = { { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE }, { "address", FLDT_UINT32X, OI(LEOFF(address)), C1, 0, TYP_NONE }, { NULL } }; #define LHOFF(f) bitize(offsetof(xfs_dir2_leaf_hdr_t, f)) const field_t dir2_leaf_hdr_flds[] = { { "info", FLDT_DIR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE }, { "stale", FLDT_UINT16D, OI(LHOFF(stale)), C1, 0, TYP_NONE }, { NULL } }; #define LTOFF(f) bitize(offsetof(xfs_dir2_leaf_tail_t, f)) const field_t dir2_leaf_tail_flds[] = { { "bestcount", FLDT_UINT32D, OI(LTOFF(bestcount)), C1, 0, TYP_NONE }, { NULL } }; #define FHOFF(f) bitize(offsetof(xfs_dir2_free_hdr_t, f)) const field_t dir2_free_hdr_flds[] = { { "magic", FLDT_UINT32X, OI(FHOFF(magic)), C1, 0, TYP_NONE }, { "firstdb", FLDT_INT32D, OI(FHOFF(firstdb)), C1, 0, TYP_NONE }, { "nvalid", FLDT_INT32D, OI(FHOFF(nvalid)), C1, 0, TYP_NONE }, { "nused", FLDT_INT32D, OI(FHOFF(nused)), C1, 0, TYP_NONE }, { NULL } }; /*ARGSUSED*/ static int dir2_block_hdr_count( void *obj, int startoff) { xfs_dir2_block_t *block; ASSERT(startoff == 0); block = obj; return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; } /*ARGSUSED*/ static int dir2_block_leaf_count( void *obj, int startoff) { xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp; ASSERT(startoff == 0); block = obj; if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) return 0; btp = xfs_dir2_block_tail_p(mp, block); return be32_to_cpu(btp->count); } /*ARGSUSED*/ static int dir2_block_leaf_offset( void *obj, int startoff, int idx) { xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp; xfs_dir2_leaf_entry_t *lep; ASSERT(startoff == 0); block = obj; ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, block); lep = xfs_dir2_block_leaf_p(btp) + idx; return bitize((int)((char *)lep - (char *)block)); } /*ARGSUSED*/ static int dir2_block_tail_count( void *obj, int startoff) { xfs_dir2_block_t *block; ASSERT(startoff == 0); block = obj; return be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC; } /*ARGSUSED*/ static int dir2_block_tail_offset( void *obj, int startoff, int idx) { xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp; ASSERT(startoff == 0); ASSERT(idx == 0); block = obj; ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, block); return bitize((int)((char *)btp - (char *)block)); } /*ARGSUSED*/ static int dir2_block_u_count( void *obj, int startoff) { xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *endptr; int i; char *ptr; ASSERT(startoff == 0); block = obj; if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC) return 0; btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; endptr = (char *)xfs_dir2_block_leaf_p(btp); for (i = 0; ptr < endptr; i++) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; ptr += xfs_dir2_data_entsize(dep->namelen); } } return i; } /*ARGSUSED*/ static int dir2_block_u_offset( void *obj, int startoff, int idx) { xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *endptr; int i; char *ptr; ASSERT(startoff == 0); block = obj; ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); btp = xfs_dir2_block_tail_p(mp, block); ptr = (char *)block->u; endptr = (char *)xfs_dir2_block_leaf_p(btp); for (i = 0; i < idx; i++) { ASSERT(ptr < endptr); dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; ptr += xfs_dir2_data_entsize(dep->namelen); } } return bitize((int)(ptr - (char *)block)); } static int dir2_data_union_freetag_count( void *obj, int startoff) { xfs_dir2_data_unused_t *dup; char *end; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); end = (char *)&dup->freetag + sizeof(dup->freetag); return end <= (char *)obj + mp->m_dirblksize && be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG; } static int dir2_data_union_inumber_count( void *obj, int startoff) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *end; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->inumber + sizeof(dep->inumber); return end <= (char *)obj + mp->m_dirblksize && be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG; } static int dir2_data_union_length_count( void *obj, int startoff) { xfs_dir2_data_unused_t *dup; char *end; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); end = (char *)&dup->length + sizeof(dup->length); return end <= (char *)obj + mp->m_dirblksize && be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG; } static int dir2_data_union_name_count( void *obj, int startoff) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *end; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->namelen + sizeof(dep->namelen); if (end >= (char *)obj + mp->m_dirblksize || be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) return 0; end = (char *)&dep->name[0] + dep->namelen; return end <= (char *)obj + mp->m_dirblksize ? dep->namelen : 0; } static int dir2_data_union_namelen_count( void *obj, int startoff) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *end; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dep->namelen + sizeof(dep->namelen); return end <= (char *)obj + mp->m_dirblksize && be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG; } static int dir2_data_union_tag_count( void *obj, int startoff) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *end; __be16 *tagp; ASSERT(bitoffs(startoff) == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); dep = (xfs_dir2_data_entry_t *)dup; end = (char *)&dup->freetag + sizeof(dup->freetag); if (end > (char *)obj + mp->m_dirblksize) return 0; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { end = (char *)&dup->length + sizeof(dup->length); if (end > (char *)obj + mp->m_dirblksize) return 0; tagp = xfs_dir2_data_unused_tag_p(dup); } else { end = (char *)&dep->namelen + sizeof(dep->namelen); if (end > (char *)obj + mp->m_dirblksize) return 0; tagp = xfs_dir2_data_entry_tag_p(dep); } end = (char *)tagp + sizeof(*tagp); return end <= (char *)obj + mp->m_dirblksize; } /*ARGSUSED*/ static int dir2_data_union_tag_offset( void *obj, int startoff, int idx) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) return bitize((int)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)dup)); dep = (xfs_dir2_data_entry_t *)dup; return bitize((int)((char *)xfs_dir2_data_entry_tag_p(dep) - (char *)dep)); } /*ARGSUSED*/ static int dir2_data_hdr_count( void *obj, int startoff) { xfs_dir2_data_t *data; ASSERT(startoff == 0); data = obj; return be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC; } /*ARGSUSED*/ static int dir2_data_u_count( void *obj, int startoff) { xfs_dir2_data_t *data; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; char *endptr; int i; char *ptr; ASSERT(startoff == 0); data = obj; if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) return 0; ptr = (char *)data->u; endptr = (char *)data + mp->m_dirblksize; for (i = 0; ptr < endptr; i++) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; ptr += xfs_dir2_data_entsize(dep->namelen); } } return i; } /*ARGSUSED*/ static int dir2_data_u_offset( void *obj, int startoff, int idx) { xfs_dir2_data_t *data; xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; /*REFERENCED*/ char *endptr; int i; char *ptr; ASSERT(startoff == 0); data = obj; ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); ptr = (char *)data->u; endptr = (char *)data + mp->m_dirblksize; for (i = 0; i < idx; i++) { ASSERT(ptr < endptr); dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) ptr += be16_to_cpu(dup->length); else { dep = (xfs_dir2_data_entry_t *)ptr; ptr += xfs_dir2_data_entsize(dep->namelen); } } return bitize((int)(ptr - (char *)data)); } /*ARGSUSED*/ int dir2_data_union_size( void *obj, int startoff, int idx) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff)); if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) return bitize(be16_to_cpu(dup->length)); else { dep = (xfs_dir2_data_entry_t *)dup; return bitize(xfs_dir2_data_entsize(dep->namelen)); } } /*ARGSUSED*/ static int dir2_free_bests_count( void *obj, int startoff) { xfs_dir2_free_t *free; ASSERT(startoff == 0); free = obj; if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) return 0; return be32_to_cpu(free->hdr.nvalid); } /*ARGSUSED*/ static int dir2_free_hdr_count( void *obj, int startoff) { xfs_dir2_free_t *free; ASSERT(startoff == 0); free = obj; return be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC; } /*ARGSUSED*/ static int dir2_leaf_bests_count( void *obj, int startoff) { xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; ASSERT(startoff == 0); leaf = obj; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) return 0; ltp = xfs_dir2_leaf_tail_p(mp, leaf); return be32_to_cpu(ltp->bestcount); } /*ARGSUSED*/ static int dir2_leaf_bests_offset( void *obj, int startoff, int idx) { __be16 *lbp; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; ASSERT(startoff == 0); leaf = obj; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); lbp = xfs_dir2_leaf_bests_p(ltp) + idx; return bitize((int)((char *)lbp - (char *)leaf)); } /*ARGSUSED*/ static int dir2_leaf_ents_count( void *obj, int startoff) { xfs_dir2_leaf_t *leaf; ASSERT(startoff == 0); leaf = obj; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) return 0; return be16_to_cpu(leaf->hdr.count); } /*ARGSUSED*/ static int dir2_leaf_hdr_count( void *obj, int startoff) { xfs_dir2_leaf_t *leaf; ASSERT(startoff == 0); leaf = obj; return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC; } /*ARGSUSED*/ static int dir2_leaf_tail_count( void *obj, int startoff) { xfs_dir2_leaf_t *leaf; ASSERT(startoff == 0); leaf = obj; return be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC; } /*ARGSUSED*/ static int dir2_leaf_tail_offset( void *obj, int startoff, int idx) { xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_tail_t *ltp; ASSERT(startoff == 0); ASSERT(idx == 0); leaf = obj; ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); ltp = xfs_dir2_leaf_tail_p(mp, leaf); return bitize((int)((char *)ltp - (char *)leaf)); } /*ARGSUSED*/ static int dir2_node_btree_count( void *obj, int startoff) { xfs_da_intnode_t *node; ASSERT(startoff == 0); node = obj; if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; return be16_to_cpu(node->hdr.count); } /*ARGSUSED*/ static int dir2_node_hdr_count( void *obj, int startoff) { xfs_da_intnode_t *node; ASSERT(startoff == 0); node = obj; return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ int dir2_size( void *obj, int startoff, int idx) { return bitize(mp->m_dirblksize); } xfsprogs-3.1.9ubuntu2/db/field.c0000664000000000000000000004020311650373060013430 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "btblock.h" #include "bmroot.h" #include "bit.h" #include "agf.h" #include "agfl.h" #include "agi.h" #include "sb.h" #include "dir.h" #include "dirshort.h" #include "attr.h" #include "attrshort.h" #include "dquot.h" #include "dir2.h" #include "dir2sf.h" const ftattr_t ftattrtab[] = { { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_AGBLOCK, "agblock", fp_num, "%u", SI(bitsz(xfs_agblock_t)), FTARG_DONULL, fa_agblock, NULL }, { FLDT_AGBLOCKNZ, "agblocknz", fp_num, "%u", SI(bitsz(xfs_agblock_t)), FTARG_SKIPZERO|FTARG_DONULL, fa_agblock, NULL }, { FLDT_AGF, "agf", NULL, (char *)agf_flds, agf_size, FTARG_SIZE, NULL, agf_flds }, { FLDT_AGFL, "agfl", NULL, (char *)agfl_flds, agfl_size, FTARG_SIZE, NULL, agfl_flds }, { FLDT_AGI, "agi", NULL, (char *)agi_flds, agi_size, FTARG_SIZE, NULL, agi_flds }, { FLDT_AGINO, "agino", fp_num, "%u", SI(bitsz(xfs_agino_t)), FTARG_DONULL, fa_agino, NULL }, { FLDT_AGINONN, "aginonn", fp_num, "%u", SI(bitsz(xfs_agino_t)), FTARG_SKIPNULL, fa_agino, NULL }, { FLDT_AGNUMBER, "agnumber", fp_num, "%u", SI(bitsz(xfs_agnumber_t)), FTARG_DONULL, NULL, NULL }, { FLDT_ATTR, "attr", NULL, (char *)attr_flds, attr_size, FTARG_SIZE, NULL, attr_flds }, { FLDT_ATTR_BLKINFO, "attr_blkinfo", NULL, (char *)attr_blkinfo_flds, SI(bitsz(struct xfs_da_blkinfo)), 0, NULL, attr_blkinfo_flds }, { FLDT_ATTR_LEAF_ENTRY, "attr_leaf_entry", fp_sarray, (char *)attr_leaf_entry_flds, SI(bitsz(struct xfs_attr_leaf_entry)), 0, NULL, attr_leaf_entry_flds }, { FLDT_ATTR_LEAF_HDR, "attr_leaf_hdr", NULL, (char *)attr_leaf_hdr_flds, SI(bitsz(struct xfs_attr_leaf_hdr)), 0, NULL, attr_leaf_hdr_flds }, { FLDT_ATTR_LEAF_MAP, "attr_leaf_map", fp_sarray, (char *)attr_leaf_map_flds, SI(bitsz(struct xfs_attr_leaf_map)), 0, NULL, attr_leaf_map_flds }, { FLDT_ATTR_LEAF_NAME, "attr_leaf_name", NULL, (char *)attr_leaf_name_flds, attr_leaf_name_size, FTARG_SIZE, NULL, attr_leaf_name_flds }, { FLDT_ATTR_NODE_ENTRY, "attr_node_entry", fp_sarray, (char *)attr_node_entry_flds, SI(bitsz(struct xfs_da_node_entry)), 0, NULL, attr_node_entry_flds }, { FLDT_ATTR_NODE_HDR, "attr_node_hdr", NULL, (char *)attr_node_hdr_flds, SI(bitsz(struct xfs_da_node_hdr)), 0, NULL, attr_node_hdr_flds }, { FLDT_ATTR_SF_ENTRY, "attr_sf_entry", NULL, (char *)attr_sf_entry_flds, attr_sf_entry_size, FTARG_SIZE, NULL, attr_sf_entry_flds }, { FLDT_ATTR_SF_HDR, "attr_sf_hdr", NULL, (char *)attr_sf_hdr_flds, SI(bitsz(struct xfs_attr_sf_hdr)), 0, NULL, attr_sf_hdr_flds }, { FLDT_ATTRBLOCK, "attrblock", fp_num, "%u", SI(bitsz(__uint32_t)), 0, fa_attrblock, NULL }, { FLDT_ATTRSHORT, "attrshort", NULL, (char *)attr_shortform_flds, attrshort_size, FTARG_SIZE, NULL, attr_shortform_flds }, { FLDT_BMAPBTA, "bmapbta", NULL, (char *)bmapbta_flds, btblock_size, FTARG_SIZE, NULL, bmapbta_flds }, { FLDT_BMAPBTAKEY, "bmapbtakey", fp_sarray, (char *)bmapbta_key_flds, SI(bitsz(xfs_bmbt_key_t)), 0, NULL, bmapbta_key_flds }, { FLDT_BMAPBTAPTR, "bmapbtaptr", fp_num, "%llu", SI(bitsz(xfs_bmbt_ptr_t)), 0, fa_dfsbno, NULL }, { FLDT_BMAPBTAREC, "bmapbtarec", fp_sarray, (char *)bmapbta_rec_flds, SI(bitsz(xfs_bmbt_rec_t)), 0, NULL, bmapbta_rec_flds }, { FLDT_BMAPBTD, "bmapbtd", NULL, (char *)bmapbtd_flds, btblock_size, FTARG_SIZE, NULL, bmapbtd_flds }, { FLDT_BMAPBTDKEY, "bmapbtdkey", fp_sarray, (char *)bmapbtd_key_flds, SI(bitsz(xfs_bmbt_key_t)), 0, NULL, bmapbtd_key_flds }, { FLDT_BMAPBTDPTR, "bmapbtdptr", fp_num, "%llu", SI(bitsz(xfs_bmbt_ptr_t)), 0, fa_dfsbno, NULL }, { FLDT_BMAPBTDREC, "bmapbtdrec", fp_sarray, (char *)bmapbtd_rec_flds, SI(bitsz(xfs_bmbt_rec_t)), 0, NULL, bmapbtd_rec_flds }, { FLDT_BMROOTA, "bmroota", NULL, (char *)bmroota_flds, bmroota_size, FTARG_SIZE, NULL, bmroota_flds }, { FLDT_BMROOTAKEY, "bmrootakey", fp_sarray, (char *)bmroota_key_flds, SI(bitsz(xfs_bmdr_key_t)), 0, NULL, bmroota_key_flds }, { FLDT_BMROOTAPTR, "bmrootaptr", fp_num, "%llu", SI(bitsz(xfs_bmdr_ptr_t)), 0, fa_dfsbno, NULL }, { FLDT_BMROOTD, "bmrootd", NULL, (char *)bmrootd_flds, bmrootd_size, FTARG_SIZE, NULL, bmrootd_flds }, { FLDT_BMROOTDKEY, "bmrootdkey", fp_sarray, (char *)bmrootd_key_flds, SI(bitsz(xfs_bmdr_key_t)), 0, NULL, bmrootd_key_flds }, { FLDT_BMROOTDPTR, "bmrootdptr", fp_num, "%llu", SI(bitsz(xfs_bmdr_ptr_t)), 0, fa_dfsbno, NULL }, { FLDT_BNOBT, "bnobt", NULL, (char *)bnobt_flds, btblock_size, FTARG_SIZE, NULL, bnobt_flds }, { FLDT_BNOBTKEY, "bnobtkey", fp_sarray, (char *)bnobt_key_flds, SI(bitsz(xfs_alloc_key_t)), 0, NULL, bnobt_key_flds }, { FLDT_BNOBTPTR, "bnobtptr", fp_num, "%u", SI(bitsz(xfs_alloc_ptr_t)), 0, fa_agblock, NULL }, { FLDT_BNOBTREC, "bnobtrec", fp_sarray, (char *)bnobt_rec_flds, SI(bitsz(xfs_alloc_rec_t)), 0, NULL, bnobt_rec_flds }, { FLDT_CEXTFLG, "cextflag", fp_num, "%u", SI(BMBT_EXNTFLAG_BITLEN), 0, NULL, NULL }, { FLDT_CEXTLEN, "cextlen", fp_num, "%u", SI(BMBT_BLOCKCOUNT_BITLEN), 0, NULL, NULL }, { FLDT_CFILEOFFA, "cfileoffa", fp_num, "%llu", SI(BMBT_STARTOFF_BITLEN), 0, fa_cfileoffa, NULL }, { FLDT_CFILEOFFD, "cfileoffd", fp_num, "%llu", SI(BMBT_STARTOFF_BITLEN), 0, fa_cfileoffd, NULL }, { FLDT_CFSBLOCK, "cfsblock", fp_num, "%llu", SI(BMBT_STARTBLOCK_BITLEN), 0, fa_cfsblock, NULL }, { FLDT_CHARNS, "charns", fp_charns, NULL, SI(bitsz(char)), 0, NULL, NULL }, { FLDT_CHARS, "chars", fp_num, "%c", SI(bitsz(char)), 0, NULL, NULL }, { FLDT_CNTBT, "cntbt", NULL, (char *)cntbt_flds, btblock_size, FTARG_SIZE, NULL, cntbt_flds }, { FLDT_CNTBTKEY, "cntbtkey", fp_sarray, (char *)cntbt_key_flds, SI(bitsz(xfs_alloc_key_t)), 0, NULL, cntbt_key_flds }, { FLDT_CNTBTPTR, "cntbtptr", fp_num, "%u", SI(bitsz(xfs_alloc_ptr_t)), 0, fa_agblock, NULL }, { FLDT_CNTBTREC, "cntbtrec", fp_sarray, (char *)cntbt_rec_flds, SI(bitsz(xfs_alloc_rec_t)), 0, NULL, cntbt_rec_flds }, { FLDT_DEV, "dev", fp_num, "%#x", SI(bitsz(xfs_dev_t)), 0, NULL, NULL }, { FLDT_DFILOFFA, "dfiloffa", fp_num, "%llu", SI(bitsz(xfs_dfiloff_t)), 0, fa_dfiloffa, NULL }, { FLDT_DFILOFFD, "dfiloffd", fp_num, "%llu", SI(bitsz(xfs_dfiloff_t)), 0, fa_dfiloffd, NULL }, { FLDT_DFSBNO, "dfsbno", fp_num, "%llu", SI(bitsz(xfs_dfsbno_t)), FTARG_DONULL, fa_dfsbno, NULL }, { FLDT_DINODE_A, "dinode_a", NULL, (char *)inode_a_flds, inode_a_size, FTARG_SIZE|FTARG_OKEMPTY, NULL, inode_a_flds }, { FLDT_DINODE_CORE, "dinode_core", NULL, (char *)inode_core_flds, SI(bitsz(xfs_dinode_t)), 0, NULL, inode_core_flds }, { FLDT_DINODE_FMT, "dinode_fmt", fp_dinode_fmt, NULL, SI(bitsz(__int8_t)), 0, NULL, NULL }, { FLDT_DINODE_U, "dinode_u", NULL, (char *)inode_u_flds, inode_u_size, FTARG_SIZE|FTARG_OKEMPTY, NULL, inode_u_flds }, { FLDT_DIR, "dir", NULL, (char *)dir_flds, dir_size, FTARG_SIZE, NULL, dir_flds }, { FLDT_DIR2, "dir2", NULL, (char *)dir2_flds, dir2_size, FTARG_SIZE, NULL, dir2_flds }, { FLDT_DIR2_BLOCK_TAIL, "dir2_block_tail", NULL, (char *)dir2_block_tail_flds, SI(bitsz(xfs_dir2_block_tail_t)), 0, NULL, dir2_block_tail_flds }, { FLDT_DIR2_DATA_FREE, "dir2_data_free", NULL, (char *)dir2_data_free_flds, SI(bitsz(xfs_dir2_data_free_t)), 0, NULL, dir2_data_free_flds }, { FLDT_DIR2_DATA_HDR, "dir2_data_hdr", NULL, (char *)dir2_data_hdr_flds, SI(bitsz(xfs_dir2_data_hdr_t)), 0, NULL, dir2_data_hdr_flds }, { FLDT_DIR2_DATA_OFF, "dir2_data_off", fp_num, "%#x", SI(bitsz(xfs_dir2_data_off_t)), 0, NULL, NULL }, { FLDT_DIR2_DATA_OFFNZ, "dir2_data_offnz", fp_num, "%#x", SI(bitsz(xfs_dir2_data_off_t)), FTARG_SKIPZERO, NULL, NULL }, { FLDT_DIR2_DATA_UNION, "dir2_data_union", NULL, (char *)dir2_data_union_flds, dir2_data_union_size, FTARG_SIZE, NULL, dir2_data_union_flds }, { FLDT_DIR2_FREE_HDR, "dir2_free_hdr", NULL, (char *)dir2_free_hdr_flds, SI(bitsz(xfs_dir2_free_hdr_t)), 0, NULL, dir2_free_hdr_flds }, { FLDT_DIR2_INO4, "dir2_ino4", fp_num, "%u", SI(bitsz(xfs_dir2_ino4_t)), 0, fa_ino4, NULL }, { FLDT_DIR2_INO8, "dir2_ino8", fp_num, "%llu", SI(bitsz(xfs_dir2_ino8_t)), 0, fa_ino8, NULL }, { FLDT_DIR2_INOU, "dir2_inou", NULL, (char *)dir2_inou_flds, dir2_inou_size, FTARG_SIZE, NULL, dir2_inou_flds }, { FLDT_DIR2_LEAF_ENTRY, "dir2_leaf_entry", NULL, (char *)dir2_leaf_entry_flds, SI(bitsz(xfs_dir2_leaf_entry_t)), 0, NULL, dir2_leaf_entry_flds }, { FLDT_DIR2_LEAF_HDR, "dir2_leaf_hdr", NULL, (char *)dir2_leaf_hdr_flds, SI(bitsz(xfs_dir2_leaf_hdr_t)), 0, NULL, dir2_leaf_hdr_flds }, { FLDT_DIR2_LEAF_TAIL, "dir2_leaf_tail", NULL, (char *)dir2_leaf_tail_flds, SI(bitsz(xfs_dir2_leaf_tail_t)), 0, NULL, dir2_leaf_tail_flds }, { FLDT_DIR2_SF_ENTRY, "dir2_sf_entry", NULL, (char *)dir2_sf_entry_flds, dir2_sf_entry_size, FTARG_SIZE, NULL, dir2_sf_entry_flds }, { FLDT_DIR2_SF_HDR, "dir2_sf_hdr", NULL, (char *)dir2_sf_hdr_flds, dir2_sf_hdr_size, FTARG_SIZE, NULL, dir2_sf_hdr_flds }, { FLDT_DIR2_SF_OFF, "dir2_sf_off", fp_num, "%#x", SI(bitsz(xfs_dir2_sf_off_t)), 0, NULL, NULL }, { FLDT_DIR2SF, "dir2sf", NULL, (char *)dir2sf_flds, dir2sf_size, FTARG_SIZE, NULL, dir2sf_flds }, { FLDT_DIR_BLKINFO, "dir_blkinfo", NULL, (char *)dir_blkinfo_flds, SI(bitsz(struct xfs_da_blkinfo)), 0, NULL, dir_blkinfo_flds }, { FLDT_DIR_INO, "dir_ino", fp_num, "%llu", SI(bitsz(xfs_dir_ino_t)), 0, fa_ino, NULL }, { FLDT_DIR_LEAF_ENTRY, "dir_leaf_entry", fp_sarray, (char *)dir_leaf_entry_flds, SI(bitsz(struct xfs_dir_leaf_entry)), 0, NULL, dir_leaf_entry_flds }, { FLDT_DIR_LEAF_HDR, "dir_leaf_hdr", NULL, (char *)dir_leaf_hdr_flds, SI(bitsz(struct xfs_dir_leaf_hdr)), 0, NULL, dir_leaf_hdr_flds }, { FLDT_DIR_LEAF_MAP, "dir_leaf_map", fp_sarray, (char *)dir_leaf_map_flds, SI(bitsz(struct xfs_dir_leaf_map)), 0, NULL, dir_leaf_map_flds }, { FLDT_DIR_LEAF_NAME, "dir_leaf_name", NULL, (char *)dir_leaf_name_flds, dir_leaf_name_size, FTARG_SIZE, NULL, dir_leaf_name_flds }, { FLDT_DIR_NODE_ENTRY, "dir_node_entry", fp_sarray, (char *)dir_node_entry_flds, SI(bitsz(struct xfs_da_node_entry)), 0, NULL, dir_node_entry_flds }, { FLDT_DIR_NODE_HDR, "dir_node_hdr", NULL, (char *)dir_node_hdr_flds, SI(bitsz(struct xfs_da_node_hdr)), 0, NULL, dir_node_hdr_flds }, { FLDT_DIR_SF_ENTRY, "dir_sf_entry", NULL, (char *)dir_sf_entry_flds, dir_sf_entry_size, FTARG_SIZE, NULL, dir_sf_entry_flds }, { FLDT_DIR_SF_HDR, "dir_sf_hdr", NULL, (char *)dir_sf_hdr_flds, SI(bitsz(struct xfs_dir_sf_hdr)), 0, NULL, dir_sf_hdr_flds }, { FLDT_DIRBLOCK, "dirblock", fp_num, "%u", SI(bitsz(__uint32_t)), 0, fa_dirblock, NULL }, { FLDT_DIRSHORT, "dirshort", NULL, (char *)dir_shortform_flds, dirshort_size, FTARG_SIZE, NULL, dir_shortform_flds }, { FLDT_DISK_DQUOT, "disk_dquot", NULL, (char *)disk_dquot_flds, SI(bitsz(xfs_disk_dquot_t)), 0, NULL, disk_dquot_flds }, { FLDT_DQBLK, "dqblk", NULL, (char *)dqblk_flds, SI(bitsz(xfs_dqblk_t)), 0, NULL, dqblk_flds }, { FLDT_DQID, "dqid", fp_num, "%d", SI(bitsz(xfs_dqid_t)), 0, NULL, NULL }, { FLDT_DRFSBNO, "drfsbno", fp_num, "%llu", SI(bitsz(xfs_drfsbno_t)), FTARG_DONULL, fa_drfsbno, NULL }, { FLDT_DRTBNO, "drtbno", fp_num, "%llu", SI(bitsz(xfs_drtbno_t)), FTARG_DONULL, fa_drtbno, NULL }, { FLDT_EXTLEN, "extlen", fp_num, "%u", SI(bitsz(xfs_extlen_t)), 0, NULL, NULL }, { FLDT_EXTNUM, "extnum", fp_num, "%d", SI(bitsz(xfs_extnum_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_FSIZE, "fsize", fp_num, "%lld", SI(bitsz(xfs_fsize_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_INO, "ino", fp_num, "%llu", SI(bitsz(xfs_ino_t)), FTARG_DONULL, fa_ino, NULL }, { FLDT_INOBT, "inobt", NULL, (char *)inobt_flds, btblock_size, FTARG_SIZE, NULL, inobt_flds }, { FLDT_INOBTKEY, "inobtkey", fp_sarray, (char *)inobt_key_flds, SI(bitsz(xfs_inobt_key_t)), 0, NULL, inobt_key_flds }, { FLDT_INOBTPTR, "inobtptr", fp_num, "%u", SI(bitsz(xfs_inobt_ptr_t)), 0, fa_agblock, NULL }, { FLDT_INOBTREC, "inobtrec", fp_sarray, (char *)inobt_rec_flds, SI(bitsz(xfs_inobt_rec_t)), 0, NULL, inobt_rec_flds }, { FLDT_INODE, "inode", NULL, (char *)inode_flds, inode_size, FTARG_SIZE, NULL, inode_flds }, { FLDT_INOFREE, "inofree", fp_num, "%#llx", SI(bitsz(xfs_inofree_t)), 0, NULL, NULL }, { FLDT_INT16D, "int16d", fp_num, "%d", SI(bitsz(__int16_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_INT32D, "int32d", fp_num, "%d", SI(bitsz(__int32_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_INT64D, "int64d", fp_num, "%lld", SI(bitsz(__int64_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_INT8D, "int8d", fp_num, "%d", SI(bitsz(__int8_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_NSEC, "nsec", fp_num, "%09d", SI(bitsz(__int32_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_QCNT, "qcnt", fp_num, "%llu", SI(bitsz(xfs_qcnt_t)), 0, NULL, NULL }, { FLDT_QWARNCNT, "qwarncnt", fp_num, "%u", SI(bitsz(xfs_qwarncnt_t)), 0, NULL, NULL }, { FLDT_SB, "sb", NULL, (char *)sb_flds, sb_size, FTARG_SIZE, NULL, sb_flds }, { FLDT_TIME, "time", fp_time, NULL, SI(bitsz(__int32_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds, SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds }, { FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL }, { FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(__uint16_t)), 0, NULL, NULL }, { FLDT_UINT16O, "uint16o", fp_num, "%#o", SI(bitsz(__uint16_t)), 0, NULL, NULL }, { FLDT_UINT16X, "uint16x", fp_num, "%#x", SI(bitsz(__uint16_t)), 0, NULL, NULL }, { FLDT_UINT32D, "uint32d", fp_num, "%u", SI(bitsz(__uint32_t)), 0, NULL, NULL }, { FLDT_UINT32O, "uint32o", fp_num, "%#o", SI(bitsz(__uint32_t)), 0, NULL, NULL }, { FLDT_UINT32X, "uint32x", fp_num, "%#x", SI(bitsz(__uint32_t)), 0, NULL, NULL }, { FLDT_UINT64D, "uint64d", fp_num, "%llu", SI(bitsz(__uint64_t)), 0, NULL, NULL }, { FLDT_UINT64O, "uint64o", fp_num, "%#llo", SI(bitsz(__uint64_t)), 0, NULL, NULL }, { FLDT_UINT64X, "uint64x", fp_num, "%#llx", SI(bitsz(__uint64_t)), 0, NULL, NULL }, { FLDT_UINT8D, "uint8d", fp_num, "%u", SI(bitsz(__uint8_t)), 0, NULL, NULL }, { FLDT_UINT8O, "uint8o", fp_num, "%#o", SI(bitsz(__uint8_t)), 0, NULL, NULL }, { FLDT_UINT8X, "uint8x", fp_num, "%#x", SI(bitsz(__uint8_t)), 0, NULL, NULL }, { FLDT_UUID, "uuid", fp_uuid, NULL, SI(bitsz(uuid_t)), 0, NULL, NULL }, { FLDT_ZZZ, NULL } }; int bitoffset( const field_t *f, void *obj, int startoff, int idx) { if (!(f->flags & FLD_OFFSET)) { if (f->flags & FLD_ARRAY) { int abase; #ifdef DEBUG const ftattr_t *fa = &ftattrtab[f->ftyp]; #endif abase = (f->flags & FLD_ABASE1) != 0; ASSERT(fa->ftyp == f->ftyp); ASSERT((fa->arg & FTARG_SIZE) == 0); return (int)(__psint_t)f->offset + (idx - abase) * fsize(f, obj, startoff, idx); } else return (int)(__psint_t)f->offset; } else return (*f->offset)(obj, startoff, idx); } int fcount( const field_t *f, void *obj, int startoff) { if (!(f->flags & FLD_COUNT)) return (int)(__psint_t)f->count; else return (*f->count)(obj, startoff); } const field_t * findfield( char *name, const field_t *fields, void *obj, int startoff) { const field_t *f; /* we only match if this field name matches and has a non-zero count */ for (f = fields; f->name; f++) if (strcmp(f->name, name) == 0 && fcount(f, obj, startoff)) return f; return NULL; } int fsize( const field_t *f, void *obj, int startoff, int idx) { const ftattr_t *fa; fa = &ftattrtab[f->ftyp]; ASSERT(fa->ftyp == f->ftyp); if (!(fa->arg & FTARG_SIZE)) return (int)(__psint_t)fa->size; else return (*fa->size)(obj, startoff, idx); } xfsprogs-3.1.9ubuntu2/db/sig.h0000664000000000000000000000154411140033220013122 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void blockint(void); extern void clearint(void); extern void init_sig(void); extern int seenint(void); extern void unblockint(void); xfsprogs-3.1.9ubuntu2/db/sig.c0000664000000000000000000000244711140033220013120 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "sig.h" static int gotintr; static sigset_t intrset; static void interrupt(int sig, siginfo_t *info, void *uc) { gotintr = 1; } void blockint(void) { sigprocmask(SIG_BLOCK, &intrset, NULL); } void clearint(void) { gotintr = 0; } void init_sig(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = interrupt; sigaction(SIGINT, &sa, NULL); sigemptyset(&intrset); sigaddset(&intrset, SIGINT); } int seenint(void) { return gotintr; } void unblockint(void) { sigprocmask(SIG_UNBLOCK, &intrset, NULL); } xfsprogs-3.1.9ubuntu2/db/text.h0000664000000000000000000000144711140033220013326 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void print_text(const struct field *fields, int argc, char **argv); xfsprogs-3.1.9ubuntu2/db/fprint.c0000664000000000000000000000716711146407622013665 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "btblock.h" #include "bit.h" #include "print.h" #include "output.h" #include "sig.h" #include "malloc.h" int fp_charns( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { int i; char *p; ASSERT(bitoffs(bit) == 0); ASSERT(size == bitsz(char)); dbprintf("\""); for (i = 0, p = (char *)obj + byteize(bit); i < count && !seenint(); i++, p++) { if (*p == '\\' || *p == '\'' || *p == '"' || *p == '\?') dbprintf("\\%c", *p); else if (isgraph((int)*p) || *p == ' ') dbprintf("%c", *p); else if (*p == '\a' || *p == '\b' || *p == '\f' || *p == '\n' || *p == '\r' || *p == '\t' || *p == '\v') dbprintf("\\%c", *p + ('a' - '\a')); else dbprintf("\\%03o", *p & 0xff); } dbprintf("\""); return 1; } int fp_num( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { int bitpos; int i; int isnull; __int64_t val; for (i = 0, bitpos = bit; i < count && !seenint(); i++, bitpos += size) { val = getbitval(obj, bitpos, size, (arg & FTARG_SIGNED) ? BVSIGNED : BVUNSIGNED); if ((arg & FTARG_SKIPZERO) && val == 0) continue; isnull = (arg & FTARG_SIGNED) || size == 64 ? val == -1LL : val == ((1LL << size) - 1LL); if ((arg & FTARG_SKIPNULL) && isnull) continue; if (array) dbprintf("%d:", i + base); if ((arg & FTARG_DONULL) && isnull) dbprintf(_("null")); else if (size > 32) dbprintf(fmtstr, val); else dbprintf(fmtstr, (__int32_t)val); if (i < count - 1) dbprintf(" "); } return 1; } /*ARGSUSED*/ int fp_sarray( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { print_sarray(obj, bit, count, size, base, array, (const field_t *)fmtstr, (arg & FTARG_SKIPNMS) != 0); return 1; } /*ARGSUSED*/ int fp_time( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { int bitpos; char *c; int i; time_t t; ASSERT(bitoffs(bit) == 0); for (i = 0, bitpos = bit; i < count && !seenint(); i++, bitpos += size) { if (array) dbprintf("%d:", i + base); t=(time_t)getbitval((char *)obj + byteize(bitpos), 0, sizeof(int32_t)*8, 0); c = ctime(&t); dbprintf("%24.24s", c); if (i < count - 1) dbprintf(" "); } return 1; } /*ARGSUSED*/ int fp_uuid( void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array) { char bp[40]; /* UUID string is 36 chars + trailing '\0' */ int i; uuid_t *p; ASSERT(bitoffs(bit) == 0); for (p = (uuid_t *)((char *)obj + byteize(bit)), i = 0; i < count && !seenint(); i++, p++) { if (array) dbprintf("%d:", i + base); platform_uuid_unparse(p, bp); dbprintf("%s", bp); if (i < count - 1) dbprintf(" "); } return 1; } xfsprogs-3.1.9ubuntu2/db/xfs_check.sh0000775000000000000000000000127211256276416014511 0ustar #!/bin/sh -f # # Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. # OPTS=" " DBOPTS=" " USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" while getopts "b:fi:l:stvV" c do case $c in s) OPTS=$OPTS"-s ";; t) OPTS=$OPTS"-t ";; v) OPTS=$OPTS"-v ";; i) OPTS=$OPTS"-i "$OPTARG" ";; b) OPTS=$OPTS"-b "$OPTARG" ";; f) DBOPTS=$DBOPTS" -f";; l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; V) xfs_db -p xfs_check -V status=$? exit $status ;; \?) echo $USAGE 1>&2 exit 2 ;; esac done set -- extra $@ shift $OPTIND case $# in 1) xfs_db$DBOPTS -F -i -p xfs_check -c "check$OPTS" $1 status=$? ;; *) echo $USAGE 1>&2 exit 2 ;; esac exit $status xfsprogs-3.1.9ubuntu2/db/agfl.c0000664000000000000000000000515211146407622013264 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "bit.h" #include "output.h" #include "init.h" #include "agfl.h" static int agfl_bno_size(void *obj, int startoff); static int agfl_f(int argc, char **argv); static void agfl_help(void); static const cmdinfo_t agfl_cmd = { "agfl", NULL, agfl_f, 0, 1, 1, N_("[agno]"), N_("set address to agfl block"), agfl_help }; const field_t agfl_hfld[] = { { "", FLDT_AGFL, OI(0), C1, 0, TYP_NONE, }, { NULL } }; #define OFF(f) bitize(offsetof(xfs_agfl_t, agfl_ ## f)) const field_t agfl_flds[] = { { "bno", FLDT_AGBLOCKNZ, OI(OFF(bno)), agfl_bno_size, FLD_ARRAY|FLD_COUNT, TYP_DATA }, { NULL } }; static int agfl_bno_size( void *obj, int startoff) { return XFS_AGFL_SIZE(mp); } static void agfl_help(void) { dbprintf(_( "\n" " set allocation group freelist\n" "\n" " Example:\n" "\n" " agfl 5" "\n" " Located in the fourth sector of each allocation group,\n" " the agfl freelist for internal btree space allocation is maintained\n" " for each allocation group. This acts as a reserved pool of space\n" " separate from the general filesystem freespace (not used for user data).\n" "\n" )); } static int agfl_f( int argc, char **argv) { xfs_agnumber_t agno; char *p; if (argc > 1) { agno = (xfs_agnumber_t)strtoul(argv[1], &p, 0); if (*p != '\0' || agno >= mp->m_sb.sb_agcount) { dbprintf(_("bad allocation group number %s\n"), argv[1]); return 0; } cur_agno = agno; } else if (cur_agno == NULLAGNUMBER) cur_agno = 0; ASSERT(typtab[TYP_AGFL].typnm == TYP_AGFL); set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, cur_agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_ADD, NULL); return 0; } void agfl_init(void) { add_command(&agfl_cmd); } /*ARGSUSED*/ int agfl_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_sectsize); } xfsprogs-3.1.9ubuntu2/db/addr.h0000664000000000000000000000136511140033220013253 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void addr_init(void); xfsprogs-3.1.9ubuntu2/db/sb.c0000664000000000000000000005072311466226660012771 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "sb.h" #include "bit.h" #include "output.h" #include "init.h" static int sb_f(int argc, char **argv); static void sb_help(void); static int uuid_f(int argc, char **argv); static void uuid_help(void); static int label_f(int argc, char **argv); static void label_help(void); static int version_f(int argc, char **argv); static void version_help(void); static const cmdinfo_t sb_cmd = { "sb", NULL, sb_f, 0, 1, 1, N_("[agno]"), N_("set current address to sb header"), sb_help }; static const cmdinfo_t uuid_cmd = { "uuid", NULL, uuid_f, 0, 1, 1, N_("[uuid]"), N_("write/print FS uuid"), uuid_help }; static const cmdinfo_t label_cmd = { "label", NULL, label_f, 0, 1, 1, N_("[label]"), N_("write/print FS label"), label_help }; static const cmdinfo_t version_cmd = { "version", NULL, version_f, 0, -1, 1, N_("[feature | [vnum fnum]]"), N_("set feature bit(s) in the sb version field"), version_help }; void sb_init(void) { add_command(&sb_cmd); add_command(&uuid_cmd); add_command(&label_cmd); add_command(&version_cmd); } #define OFF(f) bitize(offsetof(xfs_sb_t, sb_ ## f)) #define SZC(f) szcount(xfs_sb_t, sb_ ## f) const field_t sb_flds[] = { { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, { "blocksize", FLDT_UINT32D, OI(OFF(blocksize)), C1, 0, TYP_NONE }, { "dblocks", FLDT_DRFSBNO, OI(OFF(dblocks)), C1, 0, TYP_NONE }, { "rblocks", FLDT_DRFSBNO, OI(OFF(rblocks)), C1, 0, TYP_NONE }, { "rextents", FLDT_DRTBNO, OI(OFF(rextents)), C1, 0, TYP_NONE }, { "uuid", FLDT_UUID, OI(OFF(uuid)), C1, 0, TYP_NONE }, { "logstart", FLDT_DFSBNO, OI(OFF(logstart)), C1, 0, TYP_LOG }, { "rootino", FLDT_INO, OI(OFF(rootino)), C1, 0, TYP_INODE }, { "rbmino", FLDT_INO, OI(OFF(rbmino)), C1, 0, TYP_INODE }, { "rsumino", FLDT_INO, OI(OFF(rsumino)), C1, 0, TYP_INODE }, { "rextsize", FLDT_AGBLOCK, OI(OFF(rextsize)), C1, 0, TYP_NONE }, { "agblocks", FLDT_AGBLOCK, OI(OFF(agblocks)), C1, 0, TYP_NONE }, { "agcount", FLDT_AGNUMBER, OI(OFF(agcount)), C1, 0, TYP_NONE }, { "rbmblocks", FLDT_EXTLEN, OI(OFF(rbmblocks)), C1, 0, TYP_NONE }, { "logblocks", FLDT_EXTLEN, OI(OFF(logblocks)), C1, 0, TYP_NONE }, { "versionnum", FLDT_UINT16X, OI(OFF(versionnum)), C1, 0, TYP_NONE }, { "sectsize", FLDT_UINT16D, OI(OFF(sectsize)), C1, 0, TYP_NONE }, { "inodesize", FLDT_UINT16D, OI(OFF(inodesize)), C1, 0, TYP_NONE }, { "inopblock", FLDT_UINT16D, OI(OFF(inopblock)), C1, 0, TYP_NONE }, { "fname", FLDT_CHARNS, OI(OFF(fname)), CI(SZC(fname)), 0, TYP_NONE }, { "blocklog", FLDT_UINT8D, OI(OFF(blocklog)), C1, 0, TYP_NONE }, { "sectlog", FLDT_UINT8D, OI(OFF(sectlog)), C1, 0, TYP_NONE }, { "inodelog", FLDT_UINT8D, OI(OFF(inodelog)), C1, 0, TYP_NONE }, { "inopblog", FLDT_UINT8D, OI(OFF(inopblog)), C1, 0, TYP_NONE }, { "agblklog", FLDT_UINT8D, OI(OFF(agblklog)), C1, 0, TYP_NONE }, { "rextslog", FLDT_UINT8D, OI(OFF(rextslog)), C1, 0, TYP_NONE }, { "inprogress", FLDT_UINT8D, OI(OFF(inprogress)), C1, 0, TYP_NONE }, { "imax_pct", FLDT_UINT8D, OI(OFF(imax_pct)), C1, 0, TYP_NONE }, { "icount", FLDT_UINT64D, OI(OFF(icount)), C1, 0, TYP_NONE }, { "ifree", FLDT_UINT64D, OI(OFF(ifree)), C1, 0, TYP_NONE }, { "fdblocks", FLDT_UINT64D, OI(OFF(fdblocks)), C1, 0, TYP_NONE }, { "frextents", FLDT_UINT64D, OI(OFF(frextents)), C1, 0, TYP_NONE }, { "uquotino", FLDT_INO, OI(OFF(uquotino)), C1, 0, TYP_INODE }, { "gquotino", FLDT_INO, OI(OFF(gquotino)), C1, 0, TYP_INODE }, { "qflags", FLDT_UINT16X, OI(OFF(qflags)), C1, 0, TYP_NONE }, { "flags", FLDT_UINT8X, OI(OFF(flags)), C1, 0, TYP_NONE }, { "shared_vn", FLDT_UINT8D, OI(OFF(shared_vn)), C1, 0, TYP_NONE }, { "inoalignmt", FLDT_EXTLEN, OI(OFF(inoalignmt)), C1, 0, TYP_NONE }, { "unit", FLDT_UINT32D, OI(OFF(unit)), C1, 0, TYP_NONE }, { "width", FLDT_UINT32D, OI(OFF(width)), C1, 0, TYP_NONE }, { "dirblklog", FLDT_UINT8D, OI(OFF(dirblklog)), C1, 0, TYP_NONE }, { "logsectlog", FLDT_UINT8D, OI(OFF(logsectlog)), C1, 0, TYP_NONE }, { "logsectsize", FLDT_UINT16D, OI(OFF(logsectsize)), C1, 0, TYP_NONE }, { "logsunit", FLDT_UINT32D, OI(OFF(logsunit)), C1, 0, TYP_NONE }, { "features2", FLDT_UINT32X, OI(OFF(features2)), C1, 0, TYP_NONE }, { "bad_features2", FLDT_UINT32X, OI(OFF(bad_features2)), C1, 0, TYP_NONE }, { NULL } }; const field_t sb_hfld[] = { { "", FLDT_SB, OI(0), C1, 0, TYP_NONE }, { NULL } }; static void sb_help(void) { dbprintf(_( "\n" " set allocation group superblock\n" "\n" " Example:\n" "\n" " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n" "\n" " Located in the first sector of each allocation group, the superblock\n" " contains the base information for the filesystem.\n" " The superblock in allocation group 0 is the primary. The copies in the\n" " remaining allocation groups only serve as backup for filesystem recovery.\n" " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n" "\n" )); } static int sb_f( int argc, char **argv) { xfs_agnumber_t agno; char *p; if (argc > 1) { agno = (xfs_agnumber_t)strtoul(argv[1], &p, 0); if (*p != '\0' || agno >= mp->m_sb.sb_agcount) { dbprintf(_("bad allocation group number %s\n"), argv[1]); return 0; } cur_agno = agno; } else if (cur_agno == NULLAGNUMBER) cur_agno = 0; ASSERT(typtab[TYP_SB].typnm == TYP_SB); set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, cur_agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_ADD, NULL); return 0; } /*ARGSUSED*/ int sb_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_sectsize); } static int get_sb(xfs_agnumber_t agno, xfs_sb_t *sb) { push_cur(); set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (!iocur_top->data) { dbprintf(_("can't read superblock for AG %u\n"), agno); pop_cur(); return 0; } libxfs_sb_from_disk(sb, iocur_top->data); if (sb->sb_magicnum != XFS_SB_MAGIC) { dbprintf(_("bad sb magic # %#x in AG %u\n"), sb->sb_magicnum, agno); return 0; } if (!xfs_sb_good_version(sb)) { dbprintf(_("bad sb version # %#x in AG %u\n"), sb->sb_versionnum, agno); return 0; } if (agno == 0 && sb->sb_inprogress != 0) { dbprintf(_("mkfs not completed successfully\n")); return 0; } return 1; } /* workaround craziness in the xlog routines */ int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } int sb_logcheck(void) { xlog_t log; xfs_daddr_t head_blk, tail_blk; if (mp->m_sb.sb_logstart) { if (x.logdev && x.logdev != x.ddev) { dbprintf(_("aborting - external log specified for FS " "with an internal log\n")); return 0; } } else { if (!x.logdev || (x.logdev == x.ddev)) { dbprintf(_("aborting - no external log specified for FS " "with an external log\n")); return 0; } } memset(&log, 0, sizeof(log)); if (!x.logdev) x.logdev = x.ddev; x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); log.l_dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; log.l_logsize = BBTOB(log.l_logBBsize); log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; log.l_mp = mp; if (xlog_find_tail(&log, &head_blk, &tail_blk)) { dbprintf(_("ERROR: cannot find log head/tail, run xfs_repair\n")); return 0; } if (head_blk != tail_blk) { dbprintf(_( "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running %s. If you are unable to mount the filesystem, then use\n" "the xfs_repair -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n"), progname); return 0; } return 1; } static int sb_logzero(uuid_t *uuidp) { if (!sb_logcheck()) return 0; dbprintf(_("Clearing log and setting UUID\n")); if (libxfs_log_clear( (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT)) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; } return 1; } static void uuid_help(void) { dbprintf(_( "\n" " write/print FS uuid\n" "\n" " Example:\n" "\n" " 'uuid' - print UUID\n" " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" " 'uuid generate' - generate and write\n" " 'uuid rewrite' - copy UUID from SB 0\n" "\n" "The print function checks the UUID in each SB and will warn if the UUIDs\n" "differ between AGs (the log is not checked). The write commands will\n" "set the uuid in all AGs to either a specified value, a newly generated\n" "value or the value found in the first superblock (SB 0) respectively.\n" "As a side effect of writing the UUID, the log is cleared (which is fine\n" "on a CLEANLY unmounted FS).\n" "\n" )); } static uuid_t * do_uuid(xfs_agnumber_t agno, uuid_t *uuid) { xfs_sb_t tsb; static uuid_t uu; if (!get_sb(agno, &tsb)) return NULL; if (!uuid) { /* get uuid */ memcpy(&uu, &tsb.sb_uuid, sizeof(uuid_t)); pop_cur(); return &uu; } /* set uuid */ memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t)); libxfs_sb_to_disk(iocur_top->data, &tsb, XFS_SB_UUID); write_cur(); return uuid; } static int uuid_f( int argc, char **argv) { char bp[40]; xfs_agnumber_t agno; uuid_t uu; uuid_t *uup = NULL; if (argc != 1 && argc != 2) { dbprintf(_("invalid parameters\n")); return 0; } if (argc == 2) { /* WRITE UUID */ if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { dbprintf(_("%s: not in expert mode, writing disabled\n"), progname); return 0; } if (!strcasecmp(argv[1], "generate")) { platform_uuid_generate(&uu); } else if (!strcasecmp(argv[1], "nil")) { platform_uuid_clear(&uu); } else if (!strcasecmp(argv[1], "rewrite")) { uup = do_uuid(0, NULL); if (!uup) { dbprintf(_("failed to read UUID from AG 0\n")); return 0; } memcpy(&uu, uup, sizeof(uuid_t)); platform_uuid_unparse(&uu, bp); dbprintf(_("old UUID = %s\n"), bp); } else { if (platform_uuid_parse(argv[1], &uu)) { dbprintf(_("invalid UUID\n")); return 0; } } /* clear the log (setting uuid) if it's not dirty */ if (!sb_logzero(&uu)) return 0; dbprintf(_("writing all SBs\n")); for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) if (!do_uuid(agno, &uu)) { dbprintf(_("failed to set UUID in AG %d\n"), agno); break; } platform_uuid_unparse(&uu, bp); dbprintf(_("new UUID = %s\n"), bp); return 0; } else { /* READ+CHECK UUID */ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { uup = do_uuid(agno, NULL); if (!uup) { dbprintf(_("failed to read UUID from AG %d\n"), agno); return 0; } if (agno) { if (memcmp(&uu, uup, sizeof(uuid_t))) { dbprintf(_("warning: UUID in AG %d " "differs to the primary SB\n"), agno); break; } } else { memcpy(&uu, uup, sizeof(uuid_t)); } } if (mp->m_sb.sb_logstart) { if (x.logdev && x.logdev != x.ddev) dbprintf(_("warning - external log specified " "for FS with an internal log\n")); } else if (!x.logdev || (x.logdev == x.ddev)) { dbprintf(_("warning - no external log specified " "for FS with an external log\n")); } platform_uuid_unparse(&uu, bp); dbprintf(_("UUID = %s\n"), bp); } return 0; } static void label_help(void) { dbprintf(_( "\n" " write/print FS label\n" "\n" " Example:\n" "\n" " 'label' - print label\n" " 'label 123456789012' - write label\n" " 'label --' - write an empty label\n" "\n" "The print function checks the label in each SB and will warn if the labels\n" "differ between AGs. The write commands will set the label in all AGs to the\n" "specified value. The maximum length of a label is 12 characters - use of a\n" "longer label will result in truncation and a warning will be issued.\n" "\n" )); } static char * do_label(xfs_agnumber_t agno, char *label) { size_t len; xfs_sb_t tsb; static char lbl[sizeof(tsb.sb_fname) + 1]; if (!get_sb(agno, &tsb)) return NULL; memset(&lbl[0], 0, sizeof(lbl)); if (!label) { /* get label */ pop_cur(); memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); return &lbl[0]; } /* set label */ if ((len = strlen(label)) > sizeof(tsb.sb_fname)) { if (agno == 0) dbprintf(_("%s: truncating label length from %d to %d\n"), progname, (int)len, (int)sizeof(tsb.sb_fname)); len = sizeof(tsb.sb_fname); } if ( len == 2 && (strcmp(label, "\"\"") == 0 || strcmp(label, "''") == 0 || strcmp(label, "--") == 0) ) label[0] = label[1] = '\0'; memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname)); memcpy(&tsb.sb_fname, label, len); memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); libxfs_sb_to_disk(iocur_top->data, &tsb, XFS_SB_FNAME); write_cur(); return &lbl[0]; } static int label_f( int argc, char **argv) { char *p = NULL; xfs_sb_t sb; xfs_agnumber_t ag; if (argc != 1 && argc != 2) { dbprintf(_("invalid parameters\n")); return 0; } if (argc == 2) { /* WRITE LABEL */ if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { dbprintf(_("%s: not in expert mode, writing disabled\n"), progname); return 0; } dbprintf(_("writing all SBs\n")); for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) if ((p = do_label(ag, argv[1])) == NULL) { dbprintf(_("failed to set label in AG %d\n"), ag); break; } dbprintf(_("new label = \"%s\"\n"), p); } else { /* READ LABEL */ for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { p = do_label(ag, NULL); if (!p) { dbprintf(_("failed to read label in AG %d\n"), ag); return 0; } if (!ag) memcpy(&sb.sb_fname, p, sizeof(sb.sb_fname)); else if (memcmp(&sb.sb_fname, p, sizeof(sb.sb_fname))) dbprintf(_("warning: AG %d label differs\n"), ag); } dbprintf(_("label = \"%s\"\n"), p); } return 0; } static void version_help(void) { dbprintf(_( "\n" " set/print feature bits in sb version\n" "\n" " Example:\n" "\n" " 'version' - print current feature bits\n" " 'version extflg' - enable unwritten extents\n" " 'version attr1' - enable v1 inline extended attributes\n" " 'version attr2' - enable v2 inline extended attributes\n" " 'version log2' - enable v2 log format\n" "\n" "The version function prints currently enabled features for a filesystem\n" "according to the version field of its primary superblock.\n" "It can also be used to enable selected features, such as support for\n" "unwritten extents. The updated version is written into all AGs.\n" "\n" )); } static int do_version(xfs_agnumber_t agno, __uint16_t version, __uint32_t features) { xfs_sb_t tsb; __int64_t fields = 0; if (!get_sb(agno, &tsb)) return 0; if (xfs_sb_has_mismatched_features2(&tsb)) { dbprintf(_("Superblock has mismatched features2 fields, " "skipping modification\n")); return 0; } if ((version & XFS_SB_VERSION_LOGV2BIT) && !xfs_sb_version_haslogv2(&tsb)) { tsb.sb_logsunit = 1; fields |= (1LL << XFS_SBS_LOGSUNIT); } tsb.sb_versionnum = version; tsb.sb_features2 = features; tsb.sb_bad_features2 = features; fields |= XFS_SB_VERSIONNUM | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; libxfs_sb_to_disk(iocur_top->data, &tsb, fields); write_cur(); return 1; } static char * version_string( xfs_sb_t *sbp) { static char s[1024]; if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_1) strcpy(s, "V1"); else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_2) strcpy(s, "V2"); else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_3) strcpy(s, "V3"); else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) strcpy(s, "V4"); if (xfs_sb_version_hasattr(sbp)) strcat(s, ",ATTR"); if (xfs_sb_version_hasnlink(sbp)) strcat(s, ",NLINK"); if (xfs_sb_version_hasquota(sbp)) strcat(s, ",QUOTA"); if (xfs_sb_version_hasalign(sbp)) strcat(s, ",ALIGN"); if (xfs_sb_version_hasdalign(sbp)) strcat(s, ",DALIGN"); if (xfs_sb_version_hasshared(sbp)) strcat(s, ",SHARED"); if (xfs_sb_version_hasdirv2(sbp)) strcat(s, ",DIRV2"); if (xfs_sb_version_haslogv2(sbp)) strcat(s, ",LOGV2"); if (xfs_sb_version_hasextflgbit(sbp)) strcat(s, ",EXTFLG"); if (xfs_sb_version_hassector(sbp)) strcat(s, ",SECTOR"); if (xfs_sb_version_hasasciici(sbp)) strcat(s, ",ASCII_CI"); if (xfs_sb_version_hasmorebits(sbp)) strcat(s, ",MOREBITS"); if (xfs_sb_version_hasattr2(sbp)) strcat(s, ",ATTR2"); if (xfs_sb_version_haslazysbcount(sbp)) strcat(s, ",LAZYSBCOUNT"); if (xfs_sb_version_hasprojid32bit(sbp)) strcat(s, ",PROJID32BIT"); return s; } static int version_f( int argc, char **argv) { __uint16_t version = 0; __uint32_t features = 0; xfs_agnumber_t ag; if (argc == 2) { /* WRITE VERSION */ if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { dbprintf(_("%s: not in expert mode, writing disabled\n"), progname); return 0; } /* Logic here derived from the IRIX xfs_chver(1M) script. */ if (!strcasecmp(argv[1], "extflg")) { switch (XFS_SB_VERSION_NUM(&mp->m_sb)) { case XFS_SB_VERSION_1: version = 0x0004 | XFS_SB_VERSION_EXTFLGBIT; break; case XFS_SB_VERSION_2: version = 0x0014 | XFS_SB_VERSION_EXTFLGBIT; break; case XFS_SB_VERSION_3: version = 0x0034 | XFS_SB_VERSION_EXTFLGBIT; break; case XFS_SB_VERSION_4: if (xfs_sb_version_hasextflgbit(&mp->m_sb)) dbprintf(_("unwritten extents flag" " is already enabled\n")); else version = mp->m_sb.sb_versionnum | XFS_SB_VERSION_EXTFLGBIT; break; } } else if (!strcasecmp(argv[1], "log2")) { switch (XFS_SB_VERSION_NUM(&mp->m_sb)) { case XFS_SB_VERSION_1: version = 0x0004 | XFS_SB_VERSION_LOGV2BIT; break; case XFS_SB_VERSION_2: version = 0x0014 | XFS_SB_VERSION_LOGV2BIT; break; case XFS_SB_VERSION_3: version = 0x0034 | XFS_SB_VERSION_LOGV2BIT; break; case XFS_SB_VERSION_4: if (xfs_sb_version_haslogv2(&mp->m_sb)) dbprintf(_("version 2 log format" " is already in use\n")); else version = mp->m_sb.sb_versionnum | XFS_SB_VERSION_LOGV2BIT; break; } } else if (!strcasecmp(argv[1], "attr1")) { if (xfs_sb_version_hasattr2(&mp->m_sb)) { if (!(mp->m_sb.sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT)) mp->m_sb.sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; } xfs_sb_version_addattr(&mp->m_sb); version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; } else if (!strcasecmp(argv[1], "attr2")) { xfs_sb_version_addattr(&mp->m_sb); xfs_sb_version_addattr2(&mp->m_sb); version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; } else if (!strcasecmp(argv[1], "projid32bit")) { xfs_sb_version_addprojid32bit(&mp->m_sb); version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; } else { dbprintf(_("%s: invalid version change command \"%s\"\n"), progname, argv[1]); return 0; } if (version) { dbprintf(_("writing all SBs\n")); for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) if (!do_version(ag, version, features)) { dbprintf(_("failed to set versionnum " "in AG %d\n"), ag); break; } mp->m_sb.sb_versionnum = version; mp->m_sb.sb_features2 = features; } } if (argc == 3) { /* VERSIONNUM + FEATURES2 */ char *sp; version = mp->m_sb.sb_versionnum; features = mp->m_sb.sb_features2; mp->m_sb.sb_versionnum = strtoul(argv[1], &sp, 0); mp->m_sb.sb_features2 = strtoul(argv[2], &sp, 0); } dbprintf(_("versionnum [0x%x+0x%x] = %s\n"), mp->m_sb.sb_versionnum, mp->m_sb.sb_features2, version_string(&mp->m_sb)); if (argc == 3) { /* now reset... */ mp->m_sb.sb_versionnum = version; mp->m_sb.sb_features2 = features; return 0; } return 0; } xfsprogs-3.1.9ubuntu2/db/check.h0000664000000000000000000000136611140033220013417 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void check_init(void); xfsprogs-3.1.9ubuntu2/db/attrset.h0000664000000000000000000000135611140033220014027 0ustar /* * Copyright (c) 2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void attrset_init(void); xfsprogs-3.1.9ubuntu2/db/dir2.h0000664000000000000000000000237011140033220013176 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t dir2_flds[]; extern const field_t dir2_hfld[]; extern const field_t dir2_block_tail_flds[]; extern const field_t dir2_data_free_flds[]; extern const field_t dir2_data_hdr_flds[]; extern const field_t dir2_data_union_flds[]; extern const field_t dir2_free_hdr_flds[]; extern const field_t dir2_leaf_entry_flds[]; extern const field_t dir2_leaf_hdr_flds[]; extern const field_t dir2_leaf_tail_flds[]; extern int dir2_data_union_size(void *obj, int startoff, int idx); extern int dir2_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/agf.h0000664000000000000000000000157011140033220013074 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field agf_flds[]; extern const struct field agf_hfld[]; extern void agf_init(void); extern int agf_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/field.h0000664000000000000000000001076311140033220013426 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef enum fldt { FLDT_AEXTNUM, FLDT_AGBLOCK, FLDT_AGBLOCKNZ, FLDT_AGF, FLDT_AGFL, FLDT_AGI, FLDT_AGINO, FLDT_AGINONN, FLDT_AGNUMBER, FLDT_ATTR, FLDT_ATTR_BLKINFO, FLDT_ATTR_LEAF_ENTRY, FLDT_ATTR_LEAF_HDR, FLDT_ATTR_LEAF_MAP, FLDT_ATTR_LEAF_NAME, FLDT_ATTR_NODE_ENTRY, FLDT_ATTR_NODE_HDR, FLDT_ATTR_SF_ENTRY, FLDT_ATTR_SF_HDR, FLDT_ATTRBLOCK, FLDT_ATTRSHORT, FLDT_BMAPBTA, FLDT_BMAPBTAKEY, FLDT_BMAPBTAPTR, FLDT_BMAPBTAREC, FLDT_BMAPBTD, FLDT_BMAPBTDKEY, FLDT_BMAPBTDPTR, FLDT_BMAPBTDREC, FLDT_BMROOTA, FLDT_BMROOTAKEY, FLDT_BMROOTAPTR, FLDT_BMROOTD, FLDT_BMROOTDKEY, FLDT_BMROOTDPTR, FLDT_BNOBT, FLDT_BNOBTKEY, FLDT_BNOBTPTR, FLDT_BNOBTREC, FLDT_CEXTFLG, FLDT_CEXTLEN, FLDT_CFILEOFFA, FLDT_CFILEOFFD, FLDT_CFSBLOCK, FLDT_CHARNS, FLDT_CHARS, FLDT_CNTBT, FLDT_CNTBTKEY, FLDT_CNTBTPTR, FLDT_CNTBTREC, FLDT_DEV, FLDT_DFILOFFA, FLDT_DFILOFFD, FLDT_DFSBNO, FLDT_DINODE_A, FLDT_DINODE_CORE, FLDT_DINODE_FMT, FLDT_DINODE_U, FLDT_DIR, FLDT_DIR2, FLDT_DIR2_BLOCK_TAIL, FLDT_DIR2_DATA_FREE, FLDT_DIR2_DATA_HDR, FLDT_DIR2_DATA_OFF, FLDT_DIR2_DATA_OFFNZ, FLDT_DIR2_DATA_UNION, FLDT_DIR2_FREE_HDR, FLDT_DIR2_INO4, FLDT_DIR2_INO8, FLDT_DIR2_INOU, FLDT_DIR2_LEAF_ENTRY, FLDT_DIR2_LEAF_HDR, FLDT_DIR2_LEAF_TAIL, FLDT_DIR2_SF_ENTRY, FLDT_DIR2_SF_HDR, FLDT_DIR2_SF_OFF, FLDT_DIR2SF, FLDT_DIR_BLKINFO, FLDT_DIR_INO, FLDT_DIR_LEAF_ENTRY, FLDT_DIR_LEAF_HDR, FLDT_DIR_LEAF_MAP, FLDT_DIR_LEAF_NAME, FLDT_DIR_NODE_ENTRY, FLDT_DIR_NODE_HDR, FLDT_DIR_SF_ENTRY, FLDT_DIR_SF_HDR, FLDT_DIRBLOCK, FLDT_DIRSHORT, FLDT_DISK_DQUOT, FLDT_DQBLK, FLDT_DQID, FLDT_DRFSBNO, FLDT_DRTBNO, FLDT_EXTLEN, FLDT_EXTNUM, FLDT_FSIZE, FLDT_INO, FLDT_INOBT, FLDT_INOBTKEY, FLDT_INOBTPTR, FLDT_INOBTREC, FLDT_INODE, FLDT_INOFREE, FLDT_INT16D, FLDT_INT32D, FLDT_INT64D, FLDT_INT8D, FLDT_NSEC, FLDT_QCNT, FLDT_QWARNCNT, FLDT_SB, FLDT_TIME, FLDT_TIMESTAMP, FLDT_UINT1, FLDT_UINT16D, FLDT_UINT16O, FLDT_UINT16X, FLDT_UINT32D, FLDT_UINT32O, FLDT_UINT32X, FLDT_UINT64D, FLDT_UINT64O, FLDT_UINT64X, FLDT_UINT8D, FLDT_UINT8O, FLDT_UINT8X, FLDT_UUID, FLDT_ZZZ /* mark last entry */ } fldt_t; typedef int (*offset_fnc_t)(void *obj, int startoff, int idx); #define OI(o) ((offset_fnc_t)(__psint_t)(o)) typedef int (*count_fnc_t)(void *obj, int startoff); #define CI(c) ((count_fnc_t)(__psint_t)(c)) #define C1 CI(1) typedef struct field { char *name; fldt_t ftyp; offset_fnc_t offset; count_fnc_t count; int flags; typnm_t next; } field_t; /* * flag values */ #define FLD_ABASE1 1 /* field array base is 1 not 0 */ #define FLD_SKIPALL 2 /* skip this field in an all-fields print */ #define FLD_ARRAY 4 /* this field is an array */ #define FLD_OFFSET 8 /* offset value is a function pointer */ #define FLD_COUNT 16 /* count value is a function pointer */ typedef int (*size_fnc_t)(void *obj, int startoff, int idx); #define SI(s) ((size_fnc_t)(__psint_t)(s)) typedef struct ftattr { fldt_t ftyp; char *name; prfnc_t prfunc; char *fmtstr; size_fnc_t size; int arg; adfnc_t adfunc; const field_t *subfld; } ftattr_t; extern const ftattr_t ftattrtab[]; /* * arg values */ #define FTARG_SKIPZERO 1 /* skip 0 words */ #define FTARG_DONULL 2 /* make -1 words be "null" */ #define FTARG_SKIPNULL 4 /* skip -1 words */ #define FTARG_SIGNED 8 /* field value is signed */ #define FTARG_SIZE 16 /* size field is a function */ #define FTARG_SKIPNMS 32 /* skip printing names this time */ #define FTARG_OKEMPTY 64 /* ok if this (union type) is empty */ extern int bitoffset(const field_t *f, void *obj, int startoff, int idx); extern int fcount(const field_t *f, void *obj, int startoff); extern const field_t *findfield(char *name, const field_t *fields, void *obj, int startoff); extern int fsize(const field_t *f, void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/attrshort.h0000664000000000000000000000177611140033220014401 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t attr_sf_entry_flds[]; extern const field_t attr_sf_hdr_flds[]; extern const field_t attr_shortform_flds[]; extern const field_t attrshort_hfld[]; extern int attr_sf_entry_size(void *obj, int startoff, int idx); extern int attrshort_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/print.c0000664000000000000000000001337011146407622013510 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "print.h" #include "bit.h" #include "flist.h" #include "strvec.h" #include "output.h" #include "sig.h" #include "write.h" static void print_allfields(const struct field *fields); static int print_f(int argc, char **argv); static void print_flist_1(struct flist *flist, char **pfx, int parentoff); static void print_somefields(const struct field *fields, int argc, char **argv); static const cmdinfo_t print_cmd = { "print", "p", print_f, 0, -1, 0, N_("[value]..."), N_("print field values"), NULL }; static void print_allfields( const field_t *fields) { flist_t *flist; #ifdef DEBUG int i; #endif flist = flist_make(""); flist->fld = fields; #ifndef DEBUG (void)flist_parse(fields, flist, iocur_top->data, 0); #else i = flist_parse(fields, flist, iocur_top->data, 0); ASSERT(i == 1); #endif flist_print(flist); print_flist(flist); flist_free(flist); } static int print_f( int argc, char **argv) { pfunc_t pf; if (cur_typ == NULL) { dbprintf(_("no current type\n")); return 0; } pf = cur_typ->pfunc; if (pf == NULL) { dbprintf(_("no print function for type %s\n"), cur_typ->name); return 0; } argc--; argv++; (*pf)(DB_READ, cur_typ->fields, argc, argv); return 0; } void print_flist( flist_t *flist) { char **pfx; pfx = new_strvec(0); print_flist_1(flist, pfx, 0); free_strvec(pfx); } static void print_flist_1( flist_t *flist, char **ppfx, int parentoff) { char buf[16]; const field_t *f; const ftattr_t *fa; flist_t *fl; int low; int neednl; char **pfx; for (fl = flist; fl && !seenint(); fl = fl->sibling) { pfx = copy_strvec(ppfx); if (fl->name[0]) add_strvec(&pfx, fl->name); if (fl->flags & FL_OKLOW) { add_strvec(&pfx, "["); snprintf(buf, sizeof(buf), "%d", fl->low); add_strvec(&pfx, buf); if (fl->low != fl->high) { add_strvec(&pfx, "-"); snprintf(buf, sizeof(buf), "%d", fl->high); add_strvec(&pfx, buf); } add_strvec(&pfx, "]"); } if (fl->child) { if (fl->name[0]) add_strvec(&pfx, "."); print_flist_1(fl->child, pfx, fl->offset); } else { f = fl->fld; fa = &ftattrtab[f->ftyp]; ASSERT(fa->ftyp == f->ftyp); print_strvec(pfx); dbprintf(" = "); if (fl->flags & FL_OKLOW) low = fl->low; else low = 0; if (fa->prfunc) { neednl = fa->prfunc(iocur_top->data, fl->offset, fcount(f, iocur_top->data, parentoff), fa->fmtstr, fsize(f, iocur_top->data, parentoff, 0), fa->arg, low, (f->flags & FLD_ARRAY) != 0); if (neednl) dbprintf("\n"); } else { ASSERT(fa->arg & FTARG_OKEMPTY); dbprintf(_("(empty)\n")); } } free_strvec(pfx); } } void print_init(void) { add_command(&print_cmd); } void print_sarray( void *obj, int bit, int count, int size, int base, int array, const field_t *flds, int skipnms) { int bitoff; const field_t *f; const ftattr_t *fa; int first; int i; ASSERT(bitoffs(bit) == 0); if (skipnms == 0) { for (f = flds, first = 1; f->name; f++) { if (f->flags & FLD_SKIPALL) continue; dbprintf("%c%s", first ? '[' : ',', f->name); first = 0; } dbprintf("] "); } for (i = 0, bitoff = bit; i < count && !seenint(); i++, bitoff += size) { if (array) dbprintf("%d:", i + base); for (f = flds, first = 1; f->name; f++) { if (f->flags & FLD_SKIPALL) continue; fa = &ftattrtab[f->ftyp]; ASSERT(fa->ftyp == f->ftyp); dbprintf("%c", first ? '[' : ','); first = 0; if (fa->prfunc) fa->prfunc(obj, bitoff + bitoffset(f, obj, bitoff, i + base), fcount(f, obj, bitoff), fa->fmtstr, fsize(f, obj, bitoff, i + base), fa->arg, (f->flags & FLD_ABASE1) != 0, f->flags & FLD_ARRAY); else { ASSERT(fa->arg & FTARG_OKEMPTY); dbprintf(_("(empty)")); } } dbprintf("]"); if (i < count - 1) dbprintf(" "); } } static void print_somefields( const field_t *fields, int argc, char **argv) { const ftattr_t *fa; flist_t *fl; flist_t *lfl; flist_t *nfl; fl = lfl = NULL; while (argc > 0) { nfl = flist_scan(*argv); if (!nfl) { if (fl) flist_free(fl); return; } if (lfl) lfl->sibling = nfl; else fl = nfl; lfl = nfl; argc--; argv++; } if (fields->name[0] == '\0') { fa = &ftattrtab[fields->ftyp]; ASSERT(fa->ftyp == fields->ftyp); fields = fa->subfld; } if (!flist_parse(fields, fl, iocur_top->data, 0)) { flist_free(fl); return; } flist_print(fl); print_flist(fl); flist_free(fl); } /*ARGSUSED*/ void print_string( const field_t *fields, int argc, char **argv) { char *cp; if (argc != 0) dbprintf(_("no arguments allowed\n")); dbprintf("\""); for (cp = iocur_top->data; cp < (char *)iocur_top->data + iocur_top->len && *cp && !seenint(); cp++) dbprintf("%c", *cp); dbprintf("\"\n"); } void print_struct( const field_t *fields, int argc, char **argv) { if (argc == 0) print_allfields(fields); else print_somefields(fields, argc, argv); } xfsprogs-3.1.9ubuntu2/db/xfs_admin.sh0000775000000000000000000000254411466226660014526 0ustar #!/bin/sh -f # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # status=0 DB_OPTS="" REPAIR_OPTS="" USAGE="Usage: xfs_admin [-efjlpuV] [-c 0|1] [-L label] [-U uuid] device" while getopts "efjlpuc:L:U:V" c do case $c in c) REPAIR_OPTS=$REPAIR_OPTS" -c lazycount="$OPTARG;; e) DB_OPTS=$DB_OPTS" -c 'version extflg'";; f) DB_OPTS=$DB_OPTS" -f";; j) DB_OPTS=$DB_OPTS" -c 'version log2'";; l) DB_OPTS=$DB_OPTS" -r -c label";; L) DB_OPTS=$DB_OPTS" -c 'label "$OPTARG"'";; p) DB_OPTS=$DB_OPTS" -c 'version projid32bit'";; u) DB_OPTS=$DB_OPTS" -r -c uuid";; U) DB_OPTS=$DB_OPTS" -c 'uuid "$OPTARG"'";; V) xfs_db -p xfs_admin -V status=$? exit $status ;; \?) echo $USAGE 1>&2 exit 2 ;; esac done set -- extra $@ shift $OPTIND case $# in 1) if [ -n "$DB_OPTS" ] then eval xfs_db -x -p xfs_admin $DB_OPTS $1 status=$? fi if [ -n "$REPAIR_OPTS" ] then # Hide normal repair output which is sent to stderr # assuming the filesystem is fine when a user is # running xfs_admin. # Ideally, we need to improve the output behaviour # of repair for this purpose (say a "quiet" mode). eval xfs_repair $REPAIR_OPTS $1 2> /dev/null status=`expr $? + $status` if [ $status -ne 0 ] then echo "Conversion failed, is the filesystem unmounted?" fi fi ;; *) echo $USAGE 1>&2 exit 2 ;; esac exit $status xfsprogs-3.1.9ubuntu2/db/malloc.c0000664000000000000000000000277411146407622013631 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "init.h" #include "malloc.h" #include "output.h" static void badmalloc(void) { dbprintf(_("%s: out of memory\n"), progname); exit(4); } void * xcalloc( size_t nelem, size_t elsize) { void *ptr; ptr = calloc(nelem, elsize); if (ptr) return ptr; badmalloc(); /* NOTREACHED */ return NULL; } void xfree( void *ptr) { free(ptr); } void * xmalloc( size_t size) { void *ptr; ptr = valloc(size); if (ptr) return ptr; badmalloc(); /* NOTREACHED */ return NULL; } void * xrealloc( void *ptr, size_t size) { ptr = realloc(ptr, size); if (ptr || !size) return ptr; badmalloc(); /* NOTREACHED */ return NULL; } char * xstrdup( const char *s1) { char *s; s = strdup(s1); if (s) return s; badmalloc(); /* NOTREACHED */ return NULL; } xfsprogs-3.1.9ubuntu2/db/print.h0000664000000000000000000000213511140033220013471 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct field; struct flist; extern void print_flist(struct flist *flist); extern void print_init(void); extern void print_sarray(void *obj, int bit, int count, int size, int base, int array, const field_t *flds, int skipnms); extern void print_struct(const struct field *fields, int argc, char **argv); extern void print_string(const struct field *fields, int argc, char **argv); xfsprogs-3.1.9ubuntu2/db/dir2sf.h0000664000000000000000000000215711140033220013532 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t dir2sf_flds[]; extern const field_t dir2_inou_flds[]; extern const field_t dir2_sf_hdr_flds[]; extern const field_t dir2_sf_entry_flds[]; extern int dir2sf_size(void *obj, int startoff, int idx); extern int dir2_inou_size(void *obj, int startoff, int idx); extern int dir2_sf_entry_size(void *obj, int startoff, int idx); extern int dir2_sf_hdr_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/attrshort.c0000664000000000000000000001074411140033220014367 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "bit.h" #include "attrshort.h" static int attr_sf_entry_name_count(void *obj, int startoff); static int attr_sf_entry_value_count(void *obj, int startoff); static int attr_sf_entry_value_offset(void *obj, int startoff, int idx); static int attr_shortform_list_count(void *obj, int startoff); static int attr_shortform_list_offset(void *obj, int startoff, int idx); #define OFF(f) bitize(offsetof(xfs_attr_shortform_t, f)) const field_t attr_shortform_flds[] = { { "hdr", FLDT_ATTR_SF_HDR, OI(OFF(hdr)), C1, 0, TYP_NONE }, { "list", FLDT_ATTR_SF_ENTRY, attr_shortform_list_offset, attr_shortform_list_count, FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; #define HOFF(f) bitize(offsetof(xfs_attr_sf_hdr_t, f)) const field_t attr_sf_hdr_flds[] = { { "totsize", FLDT_UINT16D, OI(HOFF(totsize)), C1, 0, TYP_NONE }, { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE }, { NULL } }; #define EOFF(f) bitize(offsetof(xfs_attr_sf_entry_t, f)) const field_t attr_sf_entry_flds[] = { { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, { "valuelen", FLDT_UINT8D, OI(EOFF(valuelen)), C1, 0, TYP_NONE }, { "flags", FLDT_UINT8X, OI(EOFF(flags)), C1, FLD_SKIPALL, TYP_NONE }, { "root", FLDT_UINT1, OI(EOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_ROOT_BIT - 1), C1, 0, TYP_NONE }, { "secure", FLDT_UINT1, OI(EOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_SECURE_BIT - 1), C1, 0, TYP_NONE }, { "name", FLDT_CHARNS, OI(EOFF(nameval)), attr_sf_entry_name_count, FLD_COUNT, TYP_NONE }, { "value", FLDT_CHARNS, attr_sf_entry_value_offset, attr_sf_entry_value_count, FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; static int attr_sf_entry_name_count( void *obj, int startoff) { xfs_attr_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); e = (xfs_attr_sf_entry_t *)((char *)obj + byteize(startoff)); return e->namelen; } int attr_sf_entry_size( void *obj, int startoff, int idx) { xfs_attr_sf_entry_t *e; int i; xfs_attr_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_attr_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) e = XFS_ATTR_SF_NEXTENTRY(e); return bitize((int)XFS_ATTR_SF_ENTSIZE(e)); } static int attr_sf_entry_value_count( void *obj, int startoff) { xfs_attr_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); e = (xfs_attr_sf_entry_t *)((char *)obj + byteize(startoff)); return e->valuelen; } /*ARGSUSED*/ static int attr_sf_entry_value_offset( void *obj, int startoff, int idx) { xfs_attr_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); e = (xfs_attr_sf_entry_t *)((char *)obj + byteize(startoff)); return bitize((int)((char *)&e->nameval[e->namelen] - (char *)e)); } static int attr_shortform_list_count( void *obj, int startoff) { xfs_attr_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_attr_shortform_t *)((char *)obj + byteize(startoff)); return sf->hdr.count; } static int attr_shortform_list_offset( void *obj, int startoff, int idx) { xfs_attr_sf_entry_t *e; int i; xfs_attr_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_attr_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) e = XFS_ATTR_SF_NEXTENTRY(e); return bitize((int)((char *)e - (char *)sf)); } /*ARGSUSED*/ int attrshort_size( void *obj, int startoff, int idx) { xfs_attr_sf_entry_t *e; int i; xfs_attr_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_attr_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < sf->hdr.count; i++) e = XFS_ATTR_SF_NEXTENTRY(e); return bitize((int)((char *)e - (char *)sf)); } xfsprogs-3.1.9ubuntu2/db/type.c0000664000000000000000000001044611146407622013336 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "block.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "print.h" #include "sb.h" #include "inode.h" #include "btblock.h" #include "bmroot.h" #include "agf.h" #include "agfl.h" #include "agi.h" #include "dir.h" #include "dirshort.h" #include "io.h" #include "output.h" #include "write.h" #include "attr.h" #include "dquot.h" #include "dir2.h" #include "text.h" static const typ_t *findtyp(char *name); static int type_f(int argc, char **argv); const typ_t *cur_typ; static const cmdinfo_t type_cmd = { "type", NULL, type_f, 0, 1, 1, N_("[newtype]"), N_("set/show current data type"), NULL }; const typ_t typtab[] = { { TYP_AGF, "agf", handle_struct, agf_hfld }, { TYP_AGFL, "agfl", handle_struct, agfl_hfld }, { TYP_AGI, "agi", handle_struct, agi_hfld }, { TYP_ATTR, "attr", handle_struct, attr_hfld }, { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_hfld }, { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_hfld }, { TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld }, { TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld }, { TYP_DATA, "data", handle_block, NULL }, { TYP_DIR, "dir", handle_struct, dir_hfld }, { TYP_DIR2, "dir2", handle_struct, dir2_hfld }, { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld }, { TYP_INOBT, "inobt", handle_struct, inobt_hfld }, { TYP_INODATA, "inodata", NULL, NULL }, { TYP_INODE, "inode", handle_struct, inode_hfld }, { TYP_LOG, "log", NULL, NULL }, { TYP_RTBITMAP, "rtbitmap", NULL, NULL }, { TYP_RTSUMMARY, "rtsummary", NULL, NULL }, { TYP_SB, "sb", handle_struct, sb_hfld }, { TYP_SYMLINK, "symlink", handle_string, NULL }, { TYP_TEXT, "text", handle_text, NULL }, { TYP_NONE, NULL } }; static const typ_t * findtyp( char *name) { const typ_t *tt; for (tt = typtab; tt->name != NULL; tt++) { ASSERT(tt->typnm == (typnm_t)(tt - typtab)); if (strcmp(tt->name, name) == 0) return tt; } return NULL; } static int type_f( int argc, char **argv) { const typ_t *tt; int count = 0; if (argc == 1) { if (cur_typ == NULL) dbprintf(_("no current type\n")); else dbprintf(_("current type is \"%s\"\n"), cur_typ->name); dbprintf(_("\n supported types are:\n ")); for (tt = typtab, count = 0; tt->name != NULL; tt++) { if ((tt+1)->name != NULL) { dbprintf("%s, ", tt->name); if ((++count % 8) == 0) dbprintf("\n "); } else { dbprintf("%s\n", tt->name); } } } else { tt = findtyp(argv[1]); if (tt == NULL) { dbprintf(_("no such type %s\n"), argv[1]); } else { if (iocur_top->typ == NULL) { dbprintf(_("no current object\n")); } else { iocur_top->typ = cur_typ = tt; } } } return 0; } void type_init(void) { add_command(&type_cmd); } /* read/write selectors for each major data type */ void handle_struct( int action, const field_t *fields, int argc, char **argv) { if (action == DB_WRITE) write_struct(fields, argc, argv); else print_struct(fields, argc, argv); } void handle_string( int action, const field_t *fields, int argc, char **argv) { if (action == DB_WRITE) write_string(fields, argc, argv); else print_string(fields, argc, argv); } void handle_block( int action, const field_t *fields, int argc, char **argv) { if (action == DB_WRITE) write_block(fields, argc, argv); else print_block(fields, argc, argv); } void handle_text( int action, const field_t *fields, int argc, char **argv) { if (action != DB_WRITE) print_text(fields, argc, argv); } xfsprogs-3.1.9ubuntu2/db/io.h0000664000000000000000000000442711140033220012752 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct typ; #define BBMAP_SIZE (XFS_MAX_BLOCKSIZE / BBSIZE) typedef struct bbmap { __int64_t b[BBMAP_SIZE]; } bbmap_t; typedef struct iocur { __int64_t bb; /* BB number in filesystem of buf */ int blen; /* length of "buf", bb's */ int boff; /* data - buf */ void *buf; /* base address of buffer */ void *data; /* current interesting data */ xfs_ino_t dirino; /* current directory inode number */ xfs_ino_t ino; /* current inode number */ int len; /* length of "data", bytes */ __uint16_t mode; /* current inode's mode */ xfs_off_t off; /* fs offset of "data" in bytes */ const struct typ *typ; /* type of "data" */ int use_bbmap; /* set if bbmap is valid */ bbmap_t bbmap; /* map daddr if fragmented */ } iocur_t; #define DB_RING_ADD 1 /* add to ring on set_cur */ #define DB_RING_IGN 0 /* do not add to ring on set_cur */ extern iocur_t *iocur_base; /* base of stack */ extern iocur_t *iocur_top; /* top element of stack */ extern int iocur_sp; /* current top of stack */ extern int iocur_len; /* length of stack array */ extern void io_init(void); extern void off_cur(int off, int len); extern void pop_cur(void); extern void print_iocur(char *tag, iocur_t *ioc); extern void push_cur(void); extern int read_bbs(__int64_t daddr, int count, void **bufp, bbmap_t *bbmap); extern int write_bbs(__int64_t daddr, int count, void *bufp, bbmap_t *bbmap); extern void write_cur(void); extern void set_cur(const struct typ *t, __int64_t d, int c, int ring_add, bbmap_t *bbmap); extern void ring_add(void); xfsprogs-3.1.9ubuntu2/db/btblock.c0000664000000000000000000002650412062210562013770 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "btblock.h" #include "print.h" #include "bit.h" #include "init.h" /* * Definition of the possible btree block layouts. */ struct xfs_db_btree { size_t block_len; size_t key_len; size_t rec_len; size_t ptr_len; } btrees[] = { [/*0x424d415*/0] = { /* BMAP */ XFS_BTREE_LBLOCK_LEN, sizeof(xfs_bmbt_key_t), sizeof(xfs_bmbt_rec_t), sizeof(__be64), }, [/*0x4142544*/2] = { /* ABTB */ XFS_BTREE_SBLOCK_LEN, sizeof(xfs_alloc_key_t), sizeof(xfs_alloc_rec_t), sizeof(__be32), }, [/*0x4142544*/3] = { /* ABTC */ XFS_BTREE_SBLOCK_LEN, sizeof(xfs_alloc_key_t), sizeof(xfs_alloc_rec_t), sizeof(__be32), }, [/*0x4941425*/4] = { /* IABT */ XFS_BTREE_SBLOCK_LEN, sizeof(xfs_inobt_key_t), sizeof(xfs_inobt_rec_t), sizeof(__be32), }, }; /* * Find the right block defintion for a given ondisk block. * * We use the least significant bit of the magic number as index into * the array of block defintions. */ #define block_to_bt(bb) \ (&btrees[be32_to_cpu((bb)->bb_magic) & 0xf]) /* calculate max records. Only for non-leaves. */ static int btblock_maxrecs(struct xfs_db_btree *bt, int blocksize) { blocksize -= bt->block_len; return blocksize / (bt->key_len + bt->ptr_len); } /* * Get the number of keys in a btree block. * * Note: can also be used to get the number of ptrs because there are * always the same number of keys and ptrs in a block. */ static int btblock_key_count( void *obj, int startoff) { struct xfs_btree_block *block = obj; ASSERT(startoff == 0); if (block->bb_level == 0) return 0; return be16_to_cpu(block->bb_numrecs); } /* * Get the number of keys in a btree block. */ static int btblock_rec_count( void *obj, int startoff) { struct xfs_btree_block *block = obj; ASSERT(startoff == 0); if (block->bb_level != 0) return 0; return be16_to_cpu(block->bb_numrecs); } /* * Get the offset of the key at idx in a btree block. */ static int btblock_key_offset( void *obj, int startoff, int idx) { struct xfs_btree_block *block = obj; struct xfs_db_btree *bt = block_to_bt(block); int offset; ASSERT(startoff == 0); ASSERT(block->bb_level != 0); offset = bt->block_len + (idx - 1) * bt->key_len; return bitize(offset); } /* * Get the offset of the ptr at idx in a btree block. */ static int btblock_ptr_offset( void *obj, int startoff, int idx) { struct xfs_btree_block *block = obj; struct xfs_db_btree *bt = block_to_bt(block); int offset; int maxrecs; ASSERT(startoff == 0); ASSERT(block->bb_level != 0); maxrecs = btblock_maxrecs(bt, mp->m_sb.sb_blocksize); offset = bt->block_len + maxrecs * bt->key_len + (idx - 1) * bt->ptr_len; return bitize(offset); } /* * Get the offset of the record at idx in a btree block. */ static int btblock_rec_offset( void *obj, int startoff, int idx) { struct xfs_btree_block *block = obj; struct xfs_db_btree *bt = block_to_bt(block); int offset; ASSERT(startoff == 0); ASSERT(block->bb_level == 0); offset = bt->block_len + (idx - 1) * bt->rec_len; return bitize(offset); } /* * Get the size of a btree block. */ int btblock_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_blocksize); } /* * Bmap btree. */ const field_t bmapbta_hfld[] = { { "", FLDT_BMAPBTA, OI(0), C1, 0, TYP_NONE }, { NULL } }; const field_t bmapbtd_hfld[] = { { "", FLDT_BMAPBTD, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t bmapbta_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTA }, { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTA }, { "recs", FLDT_BMAPBTAREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_BMAPBTAKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_BMAPBTAPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA }, { NULL } }; const field_t bmapbtd_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTD }, { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTD }, { "recs", FLDT_BMAPBTDREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_BMAPBTDKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_BMAPBTDPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD }, { NULL } }; #undef OFF #define KOFF(f) bitize(offsetof(xfs_bmbt_key_t, br_ ## f)) const field_t bmapbta_key_flds[] = { { "startoff", FLDT_DFILOFFA, OI(KOFF(startoff)), C1, 0, TYP_ATTR }, { NULL } }; const field_t bmapbtd_key_flds[] = { { "startoff", FLDT_DFILOFFD, OI(KOFF(startoff)), C1, 0, TYP_INODATA }, { NULL } }; #undef KOFF #define BMBT_EXNTFLAG_BITOFF 0 #define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN) #define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN) #define BMBT_BLOCKCOUNT_BITOFF \ (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN) const field_t bmapbta_rec_flds[] = { { "startoff", FLDT_CFILEOFFA, OI(BMBT_STARTOFF_BITOFF), C1, 0, TYP_ATTR }, { "startblock", FLDT_CFSBLOCK, OI(BMBT_STARTBLOCK_BITOFF), C1, 0, TYP_ATTR }, { "blockcount", FLDT_CEXTLEN, OI(BMBT_BLOCKCOUNT_BITOFF), C1, 0, TYP_NONE }, { "extentflag", FLDT_CEXTFLG, OI(BMBT_EXNTFLAG_BITOFF), C1, 0, TYP_NONE }, { NULL } }; const field_t bmapbtd_rec_flds[] = { { "startoff", FLDT_CFILEOFFD, OI(BMBT_STARTOFF_BITOFF), C1, 0, TYP_INODATA }, { "startblock", FLDT_CFSBLOCK, OI(BMBT_STARTBLOCK_BITOFF), C1, 0, TYP_INODATA }, { "blockcount", FLDT_CEXTLEN, OI(BMBT_BLOCKCOUNT_BITOFF), C1, 0, TYP_NONE }, { "extentflag", FLDT_CEXTFLG, OI(BMBT_EXNTFLAG_BITOFF), C1, 0, TYP_NONE }, { NULL } }; /* * Inode allocation btree. */ const field_t inobt_hfld[] = { { "", FLDT_INOBT, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t inobt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT }, { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT }, { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_INOBTPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT }, { NULL } }; #undef OFF #define KOFF(f) bitize(offsetof(xfs_inobt_key_t, ir_ ## f)) const field_t inobt_key_flds[] = { { "startino", FLDT_AGINO, OI(KOFF(startino)), C1, 0, TYP_INODE }, { NULL } }; #undef KOFF #define ROFF(f) bitize(offsetof(xfs_inobt_rec_t, ir_ ## f)) const field_t inobt_rec_flds[] = { { "startino", FLDT_AGINO, OI(ROFF(startino)), C1, 0, TYP_INODE }, { "freecount", FLDT_INT32D, OI(ROFF(freecount)), C1, 0, TYP_NONE }, { "free", FLDT_INOFREE, OI(ROFF(free)), C1, 0, TYP_NONE }, { NULL } }; #undef ROFF /* * Allocation btrees. */ const field_t bnobt_hfld[] = { { "", FLDT_BNOBT, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t bnobt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_BNOBT }, { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_BNOBT }, { "recs", FLDT_BNOBTREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_BNOBTKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_BNOBTPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BNOBT }, { NULL } }; #undef OFF #define KOFF(f) bitize(offsetof(xfs_alloc_key_t, ar_ ## f)) const field_t bnobt_key_flds[] = { { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA }, { "blockcount", FLDT_EXTLEN, OI(KOFF(blockcount)), C1, 0, TYP_NONE }, { NULL } }; #undef KOFF #define ROFF(f) bitize(offsetof(xfs_alloc_rec_t, ar_ ## f)) const field_t bnobt_rec_flds[] = { { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA }, { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE }, { NULL } }; #undef ROFF const field_t cntbt_hfld[] = { { "", FLDT_CNTBT, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) const field_t cntbt_flds[] = { { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_CNTBT }, { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_CNTBT }, { "recs", FLDT_CNTBTREC, btblock_rec_offset, btblock_rec_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "keys", FLDT_CNTBTKEY, btblock_key_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_CNTBTPTR, btblock_ptr_offset, btblock_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_CNTBT }, { NULL } }; #undef OFF #define KOFF(f) bitize(offsetof(xfs_alloc_key_t, ar_ ## f)) const field_t cntbt_key_flds[] = { { "blockcount", FLDT_EXTLEN, OI(KOFF(blockcount)), C1, 0, TYP_NONE }, { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA }, { NULL } }; #undef KOFF #define ROFF(f) bitize(offsetof(xfs_alloc_rec_t, ar_ ## f)) const field_t cntbt_rec_flds[] = { { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA }, { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE }, { NULL } }; #undef ROFF xfsprogs-3.1.9ubuntu2/db/xfs_metadump.sh0000775000000000000000000000127211141371133015231 0ustar #!/bin/sh -f # # Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved. # OPTS=" " DBOPTS=" " USAGE="Usage: xfs_metadump [-efogwV] [-m max_extents] [-l logdev] source target" while getopts "efgl:m:owV" c do case $c in e) OPTS=$OPTS"-e ";; g) OPTS=$OPTS"-g ";; m) OPTS=$OPTS"-m "$OPTARG" ";; o) OPTS=$OPTS"-o ";; w) OPTS=$OPTS"-w ";; f) DBOPTS=$DBOPTS" -f";; l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; V) xfs_db -p xfs_metadump -V status=$? exit $status ;; \?) echo $USAGE 1>&2 exit 2 ;; esac done set -- extra $@ shift $OPTIND case $# in 2) xfs_db$DBOPTS -F -i -p xfs_metadump -c "metadump$OPTS $2" $1 status=$? ;; *) echo $USAGE 1>&2 exit 2 ;; esac exit $status xfsprogs-3.1.9ubuntu2/db/strvec.c0000664000000000000000000000330211140033220013633 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "strvec.h" #include "output.h" #include "malloc.h" static int count_strvec(char **vec); void add_strvec( char ***vecp, char *str) { char *dup; int i; char **vec; dup = xstrdup(str); vec = *vecp; i = count_strvec(vec); vec = xrealloc(vec, sizeof(*vec) * (i + 2)); vec[i] = dup; vec[i + 1] = NULL; *vecp = vec; } char ** copy_strvec( char **vec) { int i; char **rval; i = count_strvec(vec); rval = new_strvec(i); for (i = 0; vec[i] != NULL; i++) rval[i] = xstrdup(vec[i]); return rval; } static int count_strvec( char **vec) { int i; for (i = 0; vec[i] != NULL; i++) continue; return i; } void free_strvec( char **vec) { int i; for (i = 0; vec[i] != NULL; i++) xfree(vec[i]); xfree(vec); } char ** new_strvec( int count) { char **rval; rval = xmalloc(sizeof(*rval) * (count + 1)); rval[count] = NULL; return rval; } void print_strvec( char **vec) { int i; for (i = 0; vec[i] != NULL; i++) dbprintf("%s", vec[i]); } xfsprogs-3.1.9ubuntu2/db/dirshort.h0000664000000000000000000000177011140033220014177 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t dir_sf_entry_flds[]; extern const field_t dir_sf_hdr_flds[]; extern const field_t dir_shortform_flds[]; extern const field_t dirshort_hfld[]; extern int dir_sf_entry_size(void *obj, int startoff, int idx); extern int dirshort_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/flist.h0000664000000000000000000000136711140033220013464 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. */ struct field; typedef struct flist { char *name; const struct field *fld; struct flist *child; struct flist *sibling; int low; int high; int flags; int offset; } flist_t; /* * Flags for flist */ #define FL_OKLOW 1 #define FL_OKHIGH 2 typedef enum tokty { TT_NAME, TT_NUM, TT_STRING, TT_LB, TT_RB, TT_DASH, TT_DOT, TT_END } tokty_t; typedef struct ftok { char *tok; tokty_t tokty; } ftok_t; extern void flist_free(flist_t *fl); extern flist_t *flist_make(char *name); extern int flist_parse(const struct field *fields, flist_t *fl, void *obj, int startoff); extern void flist_print(flist_t *fl); extern flist_t *flist_scan(char *name); xfsprogs-3.1.9ubuntu2/db/freesp.h0000664000000000000000000000136711140033220013627 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void freesp_init(void); xfsprogs-3.1.9ubuntu2/db/output.h0000664000000000000000000000153711140033220013702 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern int dbprefix; extern int dbprintf(const char *, ...); extern void logprintf(const char *, ...); extern void output_init(void); xfsprogs-3.1.9ubuntu2/db/quit.c0000664000000000000000000000203111146407622013326 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "quit.h" static int quit_f(int argc, char **argv); static const cmdinfo_t quit_cmd = { "quit", "q", quit_f, 0, 0, 0, NULL, N_("exit xfs_db"), NULL }; static int quit_f( int argc, char **argv) { return 1; } void quit_init(void) { add_command(&quit_cmd); } xfsprogs-3.1.9ubuntu2/db/bmap.h0000664000000000000000000000232311650373060013272 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ struct bbmap; struct xfs_bmbt_rec; typedef struct bmap_ext { xfs_dfiloff_t startoff; xfs_dfsbno_t startblock; xfs_dfilblks_t blockcount; int flag; } bmap_ext_t; extern void bmap(xfs_dfiloff_t offset, xfs_dfilblks_t len, int whichfork, int *nexp, bmap_ext_t *bep); extern void bmap_init(void); extern void convert_extent(struct xfs_bmbt_rec *rp, xfs_dfiloff_t *op, xfs_dfsbno_t *sp, xfs_dfilblks_t *cp, int *fp); extern void make_bbmap(struct bbmap *bbmap, int nex, bmap_ext_t *bmp); xfsprogs-3.1.9ubuntu2/db/bmroot.h0000664000000000000000000000177711140033220013652 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field bmroota_flds[]; extern const struct field bmroota_key_flds[]; extern const struct field bmrootd_flds[]; extern const struct field bmrootd_key_flds[]; extern int bmroota_size(void *obj, int startoff, int idx); extern int bmrootd_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/attr.h0000664000000000000000000000231011140033220013302 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t attr_flds[]; extern const field_t attr_hfld[]; extern const field_t attr_blkinfo_flds[]; extern const field_t attr_leaf_entry_flds[]; extern const field_t attr_leaf_hdr_flds[]; extern const field_t attr_leaf_map_flds[]; extern const field_t attr_leaf_name_flds[]; extern const field_t attr_node_entry_flds[]; extern const field_t attr_node_hdr_flds[]; extern int attr_leaf_name_size(void *obj, int startoff, int idx); extern int attr_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/agi.c0000664000000000000000000000613611146407622013116 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "bit.h" #include "output.h" #include "init.h" #include "agi.h" static int agi_f(int argc, char **argv); static void agi_help(void); static const cmdinfo_t agi_cmd = { "agi", NULL, agi_f, 0, 1, 1, N_("[agno]"), N_("set address to agi header"), agi_help }; const field_t agi_hfld[] = { { "", FLDT_AGI, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(xfs_agi_t, agi_ ## f)) const field_t agi_flds[] = { { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, { "versionnum", FLDT_UINT32D, OI(OFF(versionnum)), C1, 0, TYP_NONE }, { "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE }, { "length", FLDT_AGBLOCK, OI(OFF(length)), C1, 0, TYP_NONE }, { "count", FLDT_AGINO, OI(OFF(count)), C1, 0, TYP_NONE }, { "root", FLDT_AGBLOCK, OI(OFF(root)), C1, 0, TYP_INOBT }, { "level", FLDT_UINT32D, OI(OFF(level)), C1, 0, TYP_NONE }, { "freecount", FLDT_AGINO, OI(OFF(freecount)), C1, 0, TYP_NONE }, { "newino", FLDT_AGINO, OI(OFF(newino)), C1, 0, TYP_INODE }, { "dirino", FLDT_AGINO, OI(OFF(dirino)), C1, 0, TYP_INODE }, { "unlinked", FLDT_AGINONN, OI(OFF(unlinked)), CI(XFS_AGI_UNLINKED_BUCKETS), FLD_ARRAY, TYP_NONE }, { NULL } }; static void agi_help(void) { dbprintf(_( "\n" " set allocation group inode btree\n" "\n" " Example:\n" "\n" " agi 3 (set location to 3rd allocation group inode btree and type to 'agi')\n" "\n" " Located in the 3rd 512 byte block of each allocation group,\n" " the agi inode btree tracks all used/free inodes in the allocation group.\n" " Inodes are allocated in 16k 'chunks', each btree entry tracks a 'chunk'.\n" "\n" )); } static int agi_f( int argc, char **argv) { xfs_agnumber_t agno; char *p; if (argc > 1) { agno = (xfs_agnumber_t)strtoul(argv[1], &p, 0); if (*p != '\0' || agno >= mp->m_sb.sb_agcount) { dbprintf(_("bad allocation group number %s\n"), argv[1]); return 0; } cur_agno = agno; } else if (cur_agno == NULLAGNUMBER) cur_agno = 0; ASSERT(typtab[TYP_AGI].typnm == TYP_AGI); set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, cur_agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_ADD, NULL); return 0; } void agi_init(void) { add_command(&agi_cmd); } /*ARGSUSED*/ int agi_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_sectsize); } xfsprogs-3.1.9ubuntu2/db/write.c0000664000000000000000000003346011146407622013510 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "bit.h" #include "block.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "flist.h" #include "io.h" #include "init.h" #include "output.h" #include "print.h" #include "write.h" #include "malloc.h" static int write_f(int argc, char **argv); static void write_help(void); static const cmdinfo_t write_cmd = { "write", NULL, write_f, 0, -1, 0, N_("[field or value]..."), N_("write value to disk"), write_help }; void write_init(void) { if (!expert_mode) return; add_command(&write_cmd); srand48(clock()); } static void write_help(void) { dbprintf(_( "\n" " The 'write' command takes on different personalities depending on the\n" " type of object being worked with.\n\n" " Write has 3 modes:\n" " 'struct mode' - is active anytime you're looking at a filesystem object\n" " which contains individual fields (ex: an inode).\n" " 'data mode' - is active anytime you set a disk address directly or set\n" " the type to 'data'.\n" " 'string mode' - only used for writing symlink blocks.\n" "\n" " Examples:\n" " Struct mode: 'write core.uid 23' - set an inode uid field to 23.\n" " 'write fname \"hello\\000\"' - write superblock fname.\n" " (note: in struct mode strings are not null terminated)\n" " 'write fname #6669736800' - write superblock fname with hex.\n" " 'write uuid 00112233-4455-6677-8899-aabbccddeeff'\n" " - write superblock uuid.\n" " Data mode: 'write fill 0xff' - fill the entire block with 0xff's\n" " 'write lshift 3' - shift the block 3 bytes to the left\n" " 'write sequence 1 5' - write a cycle of number [1-5] through\n" " the entire block.\n" " String mode: 'write \"This_is_a_filename\" - write null terminated string.\n" "\n" " In data mode type 'write' by itself for a list of specific commands.\n\n" )); } static int write_f( int argc, char **argv) { pfunc_t pf; extern char *progname; if (x.isreadonly & LIBXFS_ISREADONLY) { dbprintf(_("%s started in read only mode, writing disabled\n"), progname); return 0; } if (cur_typ == NULL) { dbprintf(_("no current type\n")); return 0; } pf = cur_typ->pfunc; if (pf == NULL) { dbprintf(_("no handler function for type %s, write unsupported.\n"), cur_typ->name); return 0; } /* move past the "write" command */ argc--; argv++; (*pf)(DB_WRITE, cur_typ->fields, argc, argv); return 0; } /* compare significant portions of commands */ static int sigcmp( char *s1, char *s2, int sig) { int sigcnt; if (!s1 || !s2) return 0; for (sigcnt = 0; *s1 == *s2; s1++, s2++) { sigcnt++; if (*s1 == '\0') return 1; } if (*s1 && *s2) return 0; if (sig && (sigcnt >= sig)) return 1; return 0; } /* ARGSUSED */ static void bwrite_lshift( int start, int len, int shift, int from, int to) { char *base; if (shift == -1) shift = 1; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } base = (char *)iocur_top->data + start; memcpy(base, base+shift, len-shift); memset(base+(len-shift), 0, shift); } /* ARGSUSED */ static void bwrite_rshift( int start, int len, int shift, int from, int to) { char *base; if (shift == -1) shift = 1; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } base = (char *)iocur_top->data + start; memcpy(base+shift, base, len-shift); memset(base, 0, shift); } /* ARGSUSED */ static void bwrite_lrot( int start, int len, int shift, int from, int to) { char *base; char *hold_region; if (shift == -1) shift = 1; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } base = (char *)iocur_top->data + start; hold_region = xmalloc(shift); memcpy(hold_region, base, shift); memcpy(base, base+shift, len-shift); memcpy(base+(len-shift), hold_region, shift); } /* ARGSUSED */ static void bwrite_rrot( int start, int len, int shift, int from, int to) { char *base; char *hold_region; if (shift == -1) shift = 1; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } base = (char *)iocur_top->data + start; hold_region = xmalloc(shift); memcpy(hold_region, base+(len-shift), shift); memmove(base+shift, base, len-shift); memcpy(base, hold_region, shift); } /* ARGSUSED */ static void bwrite_seq( int start, int len, int step, int from, int to) { int i; int tmp; int base; int range; int top; char *buf; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } if (from == -1 || from > 255) from = 0; if (to == -1 || to > 255) to = 255; if (step == -1) step = 1; base = from; top = to; if (from > to) { base = to; top = from; if (step > 0) step = -step; } range = top - base; buf = (char *)iocur_top->data + start; tmp = 0; for (i = start; i < start+len; i++) { *buf++ = tmp + base; tmp = (tmp + step)%(range+1); } } /* ARGSUSED */ static void bwrite_random( int start, int len, int shift, int from, int to) { int i; char *buf; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } buf = (char *)iocur_top->data + start; for (i = start; i < start+len; i++) *buf++ = (char)lrand48(); } /* ARGSUSED */ static void bwrite_fill( int start, int len, int value, int from, int to) { char *base; if (value == -1) value = 0; if (start == -1) start = 0; if (len == -1) len = iocur_top->len - start; if (len+start > iocur_top->len) { dbprintf(_("length (%d) too large for data block size (%d)"), len, iocur_top->len); } base = (char *)iocur_top->data + start; memset(base, value, len); } static struct bw_cmd { void (*cmdfunc)(int,int,int,int,int); char *cmdstr; int sig_chars; int argmin; int argmax; int shiftcount_arg; int from_arg; int to_arg; int start_arg; int len_arg; char *usage; } bw_cmdtab[] = { /* cmd sig min max sh frm to start len */ { bwrite_lshift, "lshift", 2, 0, 3, 1, 0, 0, 2, 3, "[shiftcount] [start] [len]", }, { bwrite_rshift, "rshift", 2, 0, 3, 1, 0, 0, 2, 3, "[shiftcount] [start] [len]", }, { bwrite_lrot, "lrot", 2, 0, 3, 1, 0, 0, 2, 3, "[shiftcount] [start] [len]", }, { bwrite_rrot, "rrot", 2, 0, 3, 1, 0, 0, 2, 3, "[shiftcount] [start] [len]", }, { bwrite_seq, "sequence", 3, 0, 4, 0, 1, 2, 3, 4, "[from] [to] [start] [len]", }, { bwrite_random, "random", 3, 0, 2, 0, 0, 0, 1, 2, "[start] [len]", }, { bwrite_fill, "fill", 1, 1, 3, 1, 0, 0, 2, 3, "num [start] [len]" } }; #define BWRITE_CMD_MAX (sizeof(bw_cmdtab)/sizeof(bw_cmdtab[0])) static int convert_oct( char *arg, int *ret) { int count; int i; int val = 0; /* only allow 1 case, '\' and 3 octal digits (or less) */ for (count = 0; count < 3; count++) { if (arg[count] == '\0') break; if ((arg[count] < '0') && (arg[count] > '7')) break; } for (i = 0; i < count; i++) { val |= ((arg[(count-1)-i]-'0')&0x07)<<(i*3); } *ret = val&0xff; return(count); } #define NYBBLE(x) (isdigit(x)?(x-'0'):(tolower(x)-'a'+0xa)) static char * convert_arg( char *arg, int bit_length) { int i; static char *buf = NULL; char *rbuf; long long *value; int alloc_size; char *ostr; int octval, ret; if (bit_length <= 64) alloc_size = 8; else alloc_size = (bit_length+7)/8; buf = xrealloc(buf, alloc_size); memset(buf, 0, alloc_size); value = (long long *)buf; rbuf = buf; if (*arg == '\"') { /* handle strings */ /* zap closing quote if there is one */ if ((ostr = strrchr(arg+1, '\"')) != NULL) *ostr = '\0'; ostr = arg+1; for (i = 0; i < alloc_size; i++) { if (!*ostr) break; /* do octal */ if (*ostr == '\\') { if (*(ostr+1) >= '0' || *(ostr+1) <= '7') { ret = convert_oct(ostr+1, &octval); *rbuf++ = octval; ostr += ret+1; continue; } } *rbuf++ = *ostr++; } return buf; } else if (arg[0] == '#' || ((arg[0] != '-') && strchr(arg,'-'))) { /* * handle hex blocks ie * #00112233445566778899aabbccddeeff * and uuids ie * 1122334455667788-99aa-bbcc-ddee-ff00112233445566778899 * * (but if it starts with "-" assume it's just an integer) */ int bytes=bit_length/8; /* skip leading hash */ if (*arg=='#') arg++; while (*arg && bytes--) { /* skip hypens */ while (*arg=='-') arg++; /* get first nybble */ if (!isxdigit((int)*arg)) return NULL; *rbuf=NYBBLE((int)*arg)<<4; arg++; /* skip more hyphens */ while (*arg=='-') arg++; /* get second nybble */ if (!isxdigit((int)*arg)) return NULL; *rbuf++|=NYBBLE((int)*arg); arg++; } if (bytes<0&&*arg) return NULL; return buf; } else { /* * handle integers */ *value = strtoll(arg, NULL, 0); #if __BYTE_ORDER == BIG_ENDIAN /* hackery for big endian */ if (bit_length <= 8) { rbuf += 7; } else if (bit_length <= 16) { rbuf += 6; } else if (bit_length <= 32) { rbuf += 4; } #endif return rbuf; } } /* ARGSUSED */ void write_struct( const field_t *fields, int argc, char **argv) { const ftattr_t *fa; flist_t *fl; flist_t *sfl; int bit_length; char *buf; int parentoffset; if (argc != 2) { dbprintf(_("usage: write fieldname value\n")); return; } fl = flist_scan(argv[0]); if (!fl) { dbprintf(_("unable to parse '%s'.\n"), argv[0]); return; } /* if we're a root field type, go down 1 layer to get field list */ if (fields->name[0] == '\0') { fa = &ftattrtab[fields->ftyp]; ASSERT(fa->ftyp == fields->ftyp); fields = fa->subfld; } /* run down the field list and set offsets into the data */ if (!flist_parse(fields, fl, iocur_top->data, 0)) { flist_free(fl); dbprintf(_("parsing error\n")); return; } sfl = fl; parentoffset = 0; while (sfl->child) { parentoffset = sfl->offset; sfl = sfl->child; } bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0); bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); /* convert this to a generic conversion routine */ /* should be able to handle str, num, or even labels */ buf = convert_arg(argv[1], bit_length); if (!buf) { dbprintf(_("unable to convert value '%s'.\n"), argv[1]); return; } setbitval(iocur_top->data, sfl->offset, bit_length, buf); write_cur(); flist_print(fl); print_flist(fl); flist_free(fl); } /* ARGSUSED */ void write_string( const field_t *fields, int argc, char **argv) { char *buf; int i; if (argc != 1) { dbprintf(_("usage (in string mode): write \"string...\"\n")); return; } buf = convert_arg(argv[0], (int)((strlen(argv[0])+1)*8)); for (i = 0; i < iocur_top->len; i++) { ((char *)iocur_top->data)[i] = *buf; if (*buf++ == '\0') break; } /* write back to disk */ write_cur(); } /* ARGSUSED */ void write_block( const field_t *fields, int argc, char **argv) { int i; int shiftcount = -1; int start = -1; int len = -1; int from = -1; int to = -1; struct bw_cmd *cmd = NULL; if (argc <= 1 || argc > 5) goto block_usage; for (i = 0; i < BWRITE_CMD_MAX; i++) { if (sigcmp(argv[0], bw_cmdtab[i].cmdstr, bw_cmdtab[i].sig_chars)) { cmd = &bw_cmdtab[i]; break; } } if (!cmd) { dbprintf(_("write: invalid subcommand\n")); goto block_usage; } if ((argc < cmd->argmin + 1) || (argc > cmd->argmax + 1)) { dbprintf(_("write %s: invalid number of arguments\n"), cmd->cmdstr); goto block_usage; } if (cmd->shiftcount_arg && (cmd->shiftcount_arg < argc)) shiftcount = (int)strtoul(argv[cmd->shiftcount_arg], NULL, 0); if (cmd->start_arg && (cmd->start_arg < argc)) start = (int)strtoul(argv[cmd->start_arg], NULL, 0); if (cmd->len_arg && (cmd->len_arg < argc)) len = (int)strtoul(argv[cmd->len_arg], NULL, 0); if (cmd->from_arg && (cmd->len_arg < argc)) from = (int)strtoul(argv[cmd->from_arg], NULL, 0); if (cmd->to_arg && (cmd->len_arg < argc)) to = (int)strtoul(argv[cmd->to_arg], NULL, 0); cmd->cmdfunc(start, len, shiftcount, from, to); /* write back to disk */ write_cur(); return; block_usage: dbprintf(_("usage: write (in data mode)\n")); for (i = 0; i < BWRITE_CMD_MAX; i++) { dbprintf(" %-9.9s %s\n", bw_cmdtab[i].cmdstr, bw_cmdtab[i].usage); } dbprintf("\n"); return; } xfsprogs-3.1.9ubuntu2/db/help.h0000664000000000000000000000136511140033220013271 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void help_init(void); xfsprogs-3.1.9ubuntu2/db/btblock.h0000664000000000000000000000316011140033220013754 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field bmapbta_flds[]; extern const struct field bmapbta_hfld[]; extern const struct field bmapbta_key_flds[]; extern const struct field bmapbta_rec_flds[]; extern const struct field bmapbtd_flds[]; extern const struct field bmapbtd_hfld[]; extern const struct field bmapbtd_key_flds[]; extern const struct field bmapbtd_rec_flds[]; extern const struct field inobt_flds[]; extern const struct field inobt_hfld[]; extern const struct field inobt_key_flds[]; extern const struct field inobt_rec_flds[]; extern const struct field bnobt_flds[]; extern const struct field bnobt_hfld[]; extern const struct field bnobt_key_flds[]; extern const struct field bnobt_rec_flds[]; extern const struct field cntbt_flds[]; extern const struct field cntbt_hfld[]; extern const struct field cntbt_key_flds[]; extern const struct field cntbt_rec_flds[]; extern int btblock_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/dquot.h0000664000000000000000000000156411140033220013476 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field disk_dquot_flds[]; extern const struct field dqblk_flds[]; extern const struct field dqblk_hfld[]; extern void dquot_init(void); xfsprogs-3.1.9ubuntu2/db/dquot.c0000664000000000000000000001141411146407622013505 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bit.h" #include "bmap.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "io.h" #include "init.h" #include "output.h" #include "dquot.h" static int dquot_f(int argc, char **argv); static void dquot_help(void); static const cmdinfo_t dquot_cmd = { "dquot", NULL, dquot_f, 1, 2, 1, N_("[projid|gid|uid]"), N_("set current address to project, group or user quota block"), dquot_help }; const field_t dqblk_hfld[] = { { "", FLDT_DQBLK, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define DDOFF(f) bitize(offsetof(xfs_dqblk_t, dd_ ## f)) #define DDSZC(f) szcount(xfs_dqblk_t, dd_ ## f) const field_t dqblk_flds[] = { { "diskdq", FLDT_DISK_DQUOT, OI(DDOFF(diskdq)), C1, 0, TYP_NONE }, { "fill", FLDT_CHARS, OI(DDOFF(fill)), CI(DDSZC(fill)), FLD_SKIPALL, TYP_NONE }, { NULL } }; #define DOFF(f) bitize(offsetof(xfs_disk_dquot_t, d_ ## f)) const field_t disk_dquot_flds[] = { { "magic", FLDT_UINT16X, OI(DOFF(magic)), C1, 0, TYP_NONE }, { "version", FLDT_UINT8X, OI(DOFF(version)), C1, 0, TYP_NONE }, { "flags", FLDT_UINT8X, OI(DOFF(flags)), C1, 0, TYP_NONE }, { "id", FLDT_DQID, OI(DOFF(id)), C1, 0, TYP_NONE }, { "blk_hardlimit", FLDT_QCNT, OI(DOFF(blk_hardlimit)), C1, 0, TYP_NONE }, { "blk_softlimit", FLDT_QCNT, OI(DOFF(blk_softlimit)), C1, 0, TYP_NONE }, { "ino_hardlimit", FLDT_QCNT, OI(DOFF(ino_hardlimit)), C1, 0, TYP_NONE }, { "ino_softlimit", FLDT_QCNT, OI(DOFF(ino_softlimit)), C1, 0, TYP_NONE }, { "bcount", FLDT_QCNT, OI(DOFF(bcount)), C1, 0, TYP_NONE }, { "icount", FLDT_QCNT, OI(DOFF(icount)), C1, 0, TYP_NONE }, { "itimer", FLDT_INT32D, OI(DOFF(itimer)), C1, 0, TYP_NONE }, { "btimer", FLDT_INT32D, OI(DOFF(btimer)), C1, 0, TYP_NONE }, { "iwarns", FLDT_QWARNCNT, OI(DOFF(iwarns)), C1, 0, TYP_NONE }, { "bwarns", FLDT_QWARNCNT, OI(DOFF(bwarns)), C1, 0, TYP_NONE }, { "pad0", FLDT_INT32D, OI(DOFF(pad0)), C1, FLD_SKIPALL, TYP_NONE }, { "rtb_hardlimit", FLDT_QCNT, OI(DOFF(rtb_hardlimit)), C1, 0, TYP_NONE }, { "rtb_softlimit", FLDT_QCNT, OI(DOFF(rtb_softlimit)), C1, 0, TYP_NONE }, { "rtbcount", FLDT_QCNT, OI(DOFF(rtbcount)), C1, 0, TYP_NONE }, { "rtbtimer", FLDT_INT32D, OI(DOFF(rtbtimer)), C1, 0, TYP_NONE }, { "rtbwarns", FLDT_QWARNCNT, OI(DOFF(rtbwarns)), C1, 0, TYP_NONE }, { "pad", FLDT_UINT16X, OI(DOFF(pad)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; static void dquot_help(void) { } static int dquot_f( int argc, char **argv) { bmap_ext_t bm; int c; int dogrp; int doprj; xfs_dqid_t id; xfs_ino_t ino; int nex; char *p; int perblock; xfs_fileoff_t qbno; int qoff; char *s; dogrp = doprj = optind = 0; while ((c = getopt(argc, argv, "gpu")) != EOF) { switch (c) { case 'g': dogrp = 1; doprj = 0; break; case 'p': doprj = 1; dogrp = 0; break; case 'u': dogrp = doprj = 0; break; default: dbprintf(_("bad option for dquot command\n")); return 0; } } s = doprj ? _("project") : dogrp ? _("group") : _("user"); if (optind != argc - 1) { dbprintf(_("dquot command requires one %s id argument\n"), s); return 0; } ino = (dogrp || doprj) ? mp->m_sb.sb_gquotino : mp->m_sb.sb_uquotino; if (ino == 0 || ino == NULLFSINO || (dogrp && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) || (doprj && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))) { dbprintf(_("no %s quota inode present\n"), s); return 0; } id = (xfs_dqid_t)strtol(argv[optind], &p, 0); if (*p != '\0') { dbprintf(_("bad %s id for dquot %s\n"), s, argv[optind]); return 0; } perblock = (int)(mp->m_sb.sb_blocksize / sizeof(xfs_dqblk_t)); qbno = (xfs_fileoff_t)id / perblock; qoff = (int)(id % perblock); push_cur(); set_cur_inode(ino); nex = 1; bmap(qbno, 1, XFS_DATA_FORK, &nex, &bm); pop_cur(); if (nex == 0) { dbprintf(_("no %s quota data for id %d\n"), s, id); return 0; } set_cur(&typtab[TYP_DQBLK], XFS_FSB_TO_DADDR(mp, bm.startblock), blkbb, DB_RING_IGN, NULL); off_cur(qoff * (int)sizeof(xfs_dqblk_t), sizeof(xfs_dqblk_t)); ring_add(); return 0; } void dquot_init(void) { add_command(&dquot_cmd); } xfsprogs-3.1.9ubuntu2/db/command.c0000664000000000000000000000570311146407622013773 0ustar /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "addr.h" #include "attrset.h" #include "block.h" #include "bmap.h" #include "check.h" #include "command.h" #include "convert.h" #include "debug.h" #include "type.h" #include "echo.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "agf.h" #include "agfl.h" #include "agi.h" #include "frag.h" #include "freesp.h" #include "help.h" #include "hash.h" #include "inode.h" #include "input.h" #include "io.h" #include "metadump.h" #include "output.h" #include "print.h" #include "quit.h" #include "sb.h" #include "write.h" #include "malloc.h" #include "dquot.h" cmdinfo_t *cmdtab; int ncmds; static int cmd_compare(const void *a, const void *b) { return strcmp(((const cmdinfo_t *)a)->name, ((const cmdinfo_t *)b)->name); } void add_command( const cmdinfo_t *ci) { cmdtab = xrealloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); cmdtab[ncmds - 1] = *ci; qsort(cmdtab, ncmds, sizeof(*cmdtab), cmd_compare); } int command( int argc, char **argv) { char *cmd; const cmdinfo_t *ct; cmd = argv[0]; ct = find_command(cmd); if (ct == NULL) { dbprintf(_("command %s not found\n"), cmd); return 0; } if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) { dbprintf(_("bad argument count %d to %s, expected "), argc-1, cmd); if (ct->argmax == -1) dbprintf(_("at least %d"), ct->argmin); else if (ct->argmin == ct->argmax) dbprintf("%d", ct->argmin); else dbprintf(_("between %d and %d"), ct->argmin, ct->argmax); dbprintf(_(" arguments\n")); return 0; } platform_getoptreset(); return ct->cfunc(argc, argv); } const cmdinfo_t * find_command( const char *cmd) { cmdinfo_t *ct; for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) { if (strcmp(ct->name, cmd) == 0 || (ct->altname && strcmp(ct->altname, cmd) == 0)) return (const cmdinfo_t *)ct; } return NULL; } void init_commands(void) { addr_init(); agf_init(); agfl_init(); agi_init(); attrset_init(); block_init(); bmap_init(); check_init(); convert_init(); debug_init(); echo_init(); frag_init(); freesp_init(); help_init(); hash_init(); inode_init(); input_init(); io_init(); metadump_init(); output_init(); print_init(); quit_init(); sb_init(); type_init(); write_init(); dquot_init(); } xfsprogs-3.1.9ubuntu2/db/metadump.c0000664000000000000000000014767611650373060014207 0ustar /* * Copyright (c) 2007, 2011 SGI * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bmap.h" #include "command.h" #include "metadump.h" #include "io.h" #include "output.h" #include "type.h" #include "init.h" #include "sig.h" #include "xfs_metadump.h" #define DEFAULT_MAX_EXT_SIZE 1000 /* * It's possible that multiple files in a directory (or attributes * in a file) produce the same obfuscated name. If that happens, we * try to create another one. After several rounds of this though, * we just give up and leave the original name as-is. */ #define DUP_MAX 5 /* Max duplicates before we give up */ /* copy all metadata structures to/from a file */ static int metadump_f(int argc, char **argv); static void metadump_help(void); /* * metadump commands issue info/wornings/errors to standard error as * metadump supports stdout as a destination. * * All static functions return zero on failure, while the public functions * return zero on success. */ static const cmdinfo_t metadump_cmd = { "metadump", NULL, metadump_f, 0, -1, 0, N_("[-e] [-g] [-m max_extent] [-w] [-o] filename"), N_("dump metadata to a file"), metadump_help }; static FILE *outf; /* metadump file */ static xfs_metablock_t *metablock; /* header + index + buffers */ static __be64 *block_index; static char *block_buffer; static int num_indicies; static int cur_index; static xfs_ino_t cur_ino; static int show_progress = 0; static int stop_on_read_error = 0; static int max_extent_size = DEFAULT_MAX_EXT_SIZE; static int dont_obfuscate = 0; static int show_warnings = 0; static int progress_since_warning = 0; void metadump_init(void) { add_command(&metadump_cmd); } static void metadump_help(void) { dbprintf(_( "\n" " The 'metadump' command dumps the known metadata to a compact file suitable\n" " for compressing and sending to an XFS maintainer for corruption analysis \n" " or xfs_repair failures.\n\n" " Options:\n" " -e -- Ignore read errors and keep going\n" " -g -- Display dump progress\n" " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n" " -o -- Don't obfuscate names and extended attributes\n" " -w -- Show warnings of bad metadata information\n" "\n"), DEFAULT_MAX_EXT_SIZE); } static void print_warning(const char *fmt, ...) { char buf[200]; va_list ap; if (seenint()) return; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); buf[sizeof(buf)-1] = '\0'; fprintf(stderr, "%s%s: %s\n", progress_since_warning ? "\n" : "", progname, buf); progress_since_warning = 0; } static void print_progress(const char *fmt, ...) { char buf[60]; va_list ap; FILE *f; if (seenint()) return; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); buf[sizeof(buf)-1] = '\0'; f = (outf == stdout) ? stderr : stdout; fprintf(f, "\r%-59s", buf); fflush(f); progress_since_warning = 1; } /* * A complete dump file will have a "zero" entry in the last index block, * even if the dump is exactly aligned, the last index will be full of * zeros. If the last index entry is non-zero, the dump is incomplete. * Correspondingly, the last chunk will have a count < num_indicies. */ static int write_index(void) { /* * write index block and following data blocks (streaming) */ metablock->mb_count = cpu_to_be16(cur_index); if (fwrite(metablock, (cur_index + 1) << BBSHIFT, 1, outf) != 1) { print_warning("error writing to file: %s", strerror(errno)); return 0; } memset(block_index, 0, num_indicies * sizeof(__be64)); cur_index = 0; return 1; } static int write_buf( iocur_t *buf) { char *data; __int64_t off; int i; for (i = 0, off = buf->bb, data = buf->data; i < buf->blen; i++, off++, data += BBSIZE) { block_index[cur_index] = cpu_to_be64(off); memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE); if (++cur_index == num_indicies) { if (!write_index()) return 0; } } return !seenint(); } static int scan_btree( xfs_agnumber_t agno, xfs_agblock_t agbno, int level, typnm_t btype, void *arg, int (*func)(struct xfs_btree_block *block, xfs_agnumber_t agno, xfs_agblock_t agbno, int level, typnm_t btype, void *arg)) { int rval = 0; push_cur(); set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read %s block %u/%u", typtab[btype].name, agno, agbno); rval = !stop_on_read_error; goto pop_out; } if (!write_buf(iocur_top)) goto pop_out; if (!(*func)(iocur_top->data, agno, agbno, level - 1, btype, arg)) goto pop_out; rval = 1; pop_out: pop_cur(); return rval; } /* free space tree copy routines */ static int valid_bno( xfs_agnumber_t agno, xfs_agblock_t agbno) { if (agno < (mp->m_sb.sb_agcount - 1) && agbno > 0 && agbno <= mp->m_sb.sb_agblocks) return 1; if (agno == (mp->m_sb.sb_agcount - 1) && agbno > 0 && agbno <= (mp->m_sb.sb_dblocks - (xfs_drfsbno_t)(mp->m_sb.sb_agcount - 1) * mp->m_sb.sb_agblocks)) return 1; return 0; } static int scanfunc_freesp( struct xfs_btree_block *block, xfs_agnumber_t agno, xfs_agblock_t agbno, int level, typnm_t btype, void *arg) { xfs_alloc_ptr_t *pp; int i; int numrecs; if (level == 0) return 1; numrecs = be16_to_cpu(block->bb_numrecs); if (numrecs > mp->m_alloc_mxr[1]) { if (show_warnings) print_warning("invalid numrecs (%u) in %s block %u/%u", numrecs, typtab[btype].name, agno, agbno); return 1; } pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); for (i = 0; i < numrecs; i++) { if (!valid_bno(agno, be32_to_cpu(pp[i]))) { if (show_warnings) print_warning("invalid block number (%u/%u) " "in %s block %u/%u", agno, be32_to_cpu(pp[i]), typtab[btype].name, agno, agbno); continue; } if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg, scanfunc_freesp)) return 0; } return 1; } static int copy_free_bno_btree( xfs_agnumber_t agno, xfs_agf_t *agf) { xfs_agblock_t root; int levels; root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); /* validate root and levels before processing the tree */ if (root == 0 || root > mp->m_sb.sb_agblocks) { if (show_warnings) print_warning("invalid block number (%u) in bnobt " "root in agf %u", root, agno); return 1; } if (levels >= XFS_BTREE_MAXLEVELS) { if (show_warnings) print_warning("invalid level (%u) in bnobt root " "in agf %u", levels, agno); return 1; } return scan_btree(agno, root, levels, TYP_BNOBT, agf, scanfunc_freesp); } static int copy_free_cnt_btree( xfs_agnumber_t agno, xfs_agf_t *agf) { xfs_agblock_t root; int levels; root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); /* validate root and levels before processing the tree */ if (root == 0 || root > mp->m_sb.sb_agblocks) { if (show_warnings) print_warning("invalid block number (%u) in cntbt " "root in agf %u", root, agno); return 1; } if (levels >= XFS_BTREE_MAXLEVELS) { if (show_warnings) print_warning("invalid level (%u) in cntbt root " "in agf %u", levels, agno); return 1; } return scan_btree(agno, root, levels, TYP_CNTBT, agf, scanfunc_freesp); } /* filename and extended attribute obfuscation routines */ struct name_ent { struct name_ent *next; xfs_dahash_t hash; int namelen; uchar_t name[1]; }; #define NAME_TABLE_SIZE 4096 static struct name_ent *nametable[NAME_TABLE_SIZE]; static void nametable_clear(void) { int i; struct name_ent *ent; for (i = 0; i < NAME_TABLE_SIZE; i++) { while ((ent = nametable[i])) { nametable[i] = ent->next; free(ent); } } } /* * See if the given name is already in the name table. If so, * return a pointer to its entry, otherwise return a null pointer. */ static struct name_ent * nametable_find(xfs_dahash_t hash, int namelen, uchar_t *name) { struct name_ent *ent; for (ent = nametable[hash % NAME_TABLE_SIZE]; ent; ent = ent->next) { if (ent->hash == hash && ent->namelen == namelen && !memcmp(ent->name, name, namelen)) return ent; } return NULL; } /* * Add the given name to the name table. Returns a pointer to the * name's new entry, or a null pointer if an error occurs. */ static struct name_ent * nametable_add(xfs_dahash_t hash, int namelen, uchar_t *name) { struct name_ent *ent; ent = malloc(sizeof *ent + namelen); if (!ent) return NULL; ent->namelen = namelen; memcpy(ent->name, name, namelen); ent->hash = hash; ent->next = nametable[hash % NAME_TABLE_SIZE]; nametable[hash % NAME_TABLE_SIZE] = ent; return ent; } #define is_invalid_char(c) ((c) == '/' || (c) == '\0') #define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) static inline uchar_t random_filename_char(void) { static uchar_t filename_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789-_"; return filename_alphabet[random() % (sizeof filename_alphabet - 1)]; } #define ORPHANAGE "lost+found" #define ORPHANAGE_LEN (sizeof (ORPHANAGE) - 1) static inline int is_orphanage_dir( struct xfs_mount *mp, xfs_ino_t dir_ino, size_t name_len, uchar_t *name) { return dir_ino == mp->m_sb.sb_rootino && name_len == ORPHANAGE_LEN && !memcmp(name, ORPHANAGE, ORPHANAGE_LEN); } /* * Determine whether a name is one we shouldn't obfuscate because * it's an orphan (or the "lost+found" directory itself). Note * "cur_ino" is the inode for the directory currently being * processed. * * Returns 1 if the name should NOT be obfuscated or 0 otherwise. */ static int in_lost_found( xfs_ino_t ino, int namelen, uchar_t *name) { static xfs_ino_t orphanage_ino = 0; char s[24]; /* 21 is enough (64 bits in decimal) */ int slen; /* Record the "lost+found" inode if we haven't done so already */ ASSERT(ino != 0); if (!orphanage_ino && is_orphanage_dir(mp, cur_ino, namelen, name)) orphanage_ino = ino; /* We don't obfuscate the "lost+found" directory itself */ if (ino == orphanage_ino) return 1; /* Most files aren't in "lost+found" at all */ if (cur_ino != orphanage_ino) return 0; /* * Within "lost+found", we don't obfuscate any file whose * name is the same as its inode number. Any others are * stray files and can be obfuscated. */ slen = snprintf(s, sizeof (s), "%llu", (unsigned long long) ino); return slen == namelen && !memcmp(name, s, namelen); } /* * Given a name and its hash value, massage the name in such a way * that the result is another name of equal length which shares the * same hash value. */ static void obfuscate_name( xfs_dahash_t hash, size_t name_len, uchar_t *name) { uchar_t *newp = name; int i; xfs_dahash_t new_hash = 0; uchar_t *first; uchar_t high_bit; int shift; /* * Our obfuscation algorithm requires at least 5-character * names, so don't bother if the name is too short. We * work backward from a hash value to determine the last * five bytes in a name required to produce a new name * with the same hash. */ if (name_len < 5) return; /* * The beginning of the obfuscated name can be pretty much * anything, so fill it in with random characters. * Accumulate its new hash value as we go. */ for (i = 0; i < name_len - 5; i++) { *newp = random_filename_char(); new_hash = *newp ^ rol32(new_hash, 7); newp++; } /* * Compute which five bytes need to be used at the end of * the name so the hash of the obfuscated name is the same * as the hash of the original. If any result in an invalid * character, flip a bit and arrange for a corresponding bit * in a neighboring byte to be flipped as well. For the * last byte, the "neighbor" to change is the first byte * we're computing here. */ new_hash = rol32(new_hash, 3) ^ hash; first = newp; high_bit = 0; for (shift = 28; shift >= 0; shift -= 7) { *newp = (new_hash >> shift & 0x7f) ^ high_bit; if (is_invalid_char(*newp)) { *newp ^= 1; high_bit = 0x80; } else high_bit = 0; ASSERT(!is_invalid_char(*newp)); newp++; } /* * If we flipped a bit on the last byte, we need to fix up * the matching bit in the first byte. The result will * be a valid character, because we know that first byte * has 0's in its upper four bits (it was produced by a * 28-bit right-shift of a 32-bit unsigned value). */ if (high_bit) { *first ^= 0x10; ASSERT(!is_invalid_char(*first)); } ASSERT(libxfs_da_hashname(name, name_len) == hash); } /* * Flip a bit in each of two bytes at the end of the given name. * This is used in generating a series of alternate names to be used * in the event a duplicate is found. * * The bits flipped are selected such that they both affect the same * bit in the name's computed hash value, so flipping them both will * preserve the hash. * * The following diagram aims to show the portion of a computed * hash that a given byte of a name affects. * * 31 28 24 21 14 8 7 3 0 * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ * hash: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ * last-4 ->| |<-- last-2 --->| |<--- last ---->| * |<-- last-3 --->| |<-- last-1 --->| |<- last-4 * |<-- last-7 --->| |<-- last-5 --->| * |<-- last-8 --->| |<-- last-6 --->| * . . . and so on * * The last byte of the name directly affects the low-order byte of * the hash. The next-to-last affects bits 7-14, the next one back * affects bits 14-21, and so on. The effect wraps around when it * goes beyond the top of the hash (as happens for byte last-4). * * Bits that are flipped together "overlap" on the hash value. As * an example of overlap, the last two bytes both affect bit 7 in * the hash. That pair of bytes (and their overlapping bits) can be * used for this "flip bit" operation (it's the first pair tried, * actually). * * A table defines overlapping pairs--the bytes involved and bits * within them--that can be used this way. The byte offset is * relative to a starting point within the name, which will be set * to affect the bytes at the end of the name. The function is * called with a "bitseq" value which indicates which bit flip is * desired, and this translates directly into selecting which entry * in the bit_to_flip[] table to apply. * * The function returns 1 if the operation was successful. It * returns 0 if the result produced a character that's not valid in * a name (either '/' or a '\0'). Finally, it returns -1 if the bit * sequence number is beyond what is supported for a name of this * length. * * Discussion * ---------- * (Also see the discussion above find_alternate(), below.) * * In order to make this function work for any length name, the * table is ordered by increasing byte offset, so that the earliest * entries can apply to the shortest strings. This way all names * are done consistently. * * When bit flips occur, they can convert printable characters * into non-printable ones. In an effort to reduce the impact of * this, the first bit flips are chosen to affect bytes the end of * the name (and furthermore, toward the low bits of a byte). Those * bytes are often non-printable anyway because of the way they are * initially selected by obfuscate_name()). This is accomplished, * using later table entries first. * * Each row in the table doubles the number of alternates that * can be generated. A two-byte name is limited to using only * the first row, so it's possible to generate two alternates * (the original name, plus the alternate produced by flipping * the one pair of bits). In a 5-byte name, the effect of the * first byte overlaps the last by 4 its, and there are 8 bits * to flip, allowing for 256 possible alternates. * * Short names (less than 5 bytes) are never even obfuscated, so for * such names the relatively small number of alternates should never * really be a problem. * * Long names (more than 6 bytes, say) are not likely to exhaust * the number of available alternates. In fact, the table could * probably have stopped at 8 entries, on the assumption that 256 * alternates should be enough for most any situation. The entries * beyond those are present mostly for demonstration of how it could * be populated with more entries, should it ever be necessary to do * so. */ static int flip_bit( size_t name_len, uchar_t *name, uint32_t bitseq) { int index; size_t offset; uchar_t *p0, *p1; uchar_t m0, m1; struct { int byte; /* Offset from start within name */ uchar_t bit; /* Bit within that byte */ } bit_to_flip[][2] = { /* Sorted by second entry's byte */ { { 0, 0 }, { 1, 7 } }, /* Each row defines a pair */ { { 1, 0 }, { 2, 7 } }, /* of bytes and a bit within */ { { 2, 0 }, { 3, 7 } }, /* each byte. Each bit in */ { { 0, 4 }, { 4, 0 } }, /* a pair affects the same */ { { 0, 5 }, { 4, 1 } }, /* bit in the hash, so flipping */ { { 0, 6 }, { 4, 2 } }, /* both will change the name */ { { 0, 7 }, { 4, 3 } }, /* while preserving the hash. */ { { 3, 0 }, { 4, 7 } }, { { 0, 0 }, { 5, 3 } }, /* The first entry's byte offset */ { { 0, 1 }, { 5, 4 } }, /* must be less than the second. */ { { 0, 2 }, { 5, 5 } }, { { 0, 3 }, { 5, 6 } }, /* The table can be extended to */ { { 0, 4 }, { 5, 7 } }, /* an arbitrary number of entries */ { { 4, 0 }, { 5, 7 } }, /* but there's not much point. */ /* . . . */ }; /* Find the first entry *not* usable for name of this length */ for (index = 0; index < ARRAY_SIZE(bit_to_flip); index++) if (bit_to_flip[index][1].byte >= name_len) break; /* * Back up to the last usable entry. If that number is * smaller than the bit sequence number, inform the caller * that nothing this large (or larger) will work. */ if (bitseq > --index) return -1; /* * We will be switching bits at the end of name, with a * preference for affecting the last bytes first. Compute * where in the name we'll start applying the changes. */ offset = name_len - (bit_to_flip[index][1].byte + 1); index -= bitseq; /* Use later table entries first */ p0 = name + offset + bit_to_flip[index][0].byte; p1 = name + offset + bit_to_flip[index][1].byte; m0 = 1 << bit_to_flip[index][0].bit; m1 = 1 << bit_to_flip[index][1].bit; /* Only change the bytes if it produces valid characters */ if (is_invalid_char(*p0 ^ m0) || is_invalid_char(*p1 ^ m1)) return 0; *p0 ^= m0; *p1 ^= m1; return 1; } /* * This function generates a well-defined sequence of "alternate" * names for a given name. An alternate is a name having the same * length and same hash value as the original name. This is needed * because the algorithm produces only one obfuscated name to use * for a given original name, and it's possible that result matches * a name already seen. This function checks for this, and if it * occurs, finds another suitable obfuscated name to use. * * Each bit in the binary representation of the sequence number is * used to select one possible "bit flip" operation to perform on * the name. So for example: * seq = 0: selects no bits to flip * seq = 1: selects the 0th bit to flip * seq = 2: selects the 1st bit to flip * seq = 3: selects the 0th and 1st bit to flip * ... and so on. * * The flip_bit() function takes care of the details of the bit * flipping within the name. Note that the "1st bit" in this * context is a bit sequence number; i.e. it doesn't necessarily * mean bit 0x02 will be changed. * * If a valid name (one that contains no '/' or '\0' characters) is * produced by this process for the given sequence number, this * function returns 1. If the result is not valid, it returns 0. * Returns -1 if the sequence number is beyond the the maximum for * names of the given length. * * * Discussion * ---------- * The number of alternates available for a given name is dependent * on its length. A "bit flip" involves inverting two bits in * a name--the two bits being selected such that their values * affect the name's hash value in the same way. Alternates are * thus generated by inverting the value of pairs of such * "overlapping" bits in the original name. Each byte after the * first in a name adds at least one bit of overlap to work with. * (See comments above flip_bit() for more discussion on this.) * * So the number of alternates is dependent on the number of such * overlapping bits in a name. If there are N bit overlaps, there * 2^N alternates for that hash value. * * Here are the number of overlapping bits available for generating * alternates for names of specific lengths: * 1 0 (must have 2 bytes to have any overlap) * 2 1 One bit overlaps--so 2 possible alternates * 3 2 Two bits overlap--so 4 possible alternates * 4 4 Three bits overlap, so 2^3 alternates * 5 8 8 bits overlap (due to wrapping), 256 alternates * 6 18 2^18 alternates * 7 28 2^28 alternates * ... * It's clear that the number of alternates grows very quickly with * the length of the name. But note that the set of alternates * includes invalid names. And for certain (contrived) names, the * number of valid names is a fairly small fraction of the total * number of alternates. * * The main driver for this infrastructure for coming up with * alternate names is really related to names 5 (or possibly 6) * bytes in length. 5-byte obfuscated names contain no randomly- * generated bytes in them, and the chance of an obfuscated name * matching an already-seen name is too high to just ignore. This * methodical selection of alternates ensures we don't produce * duplicate names unless we have exhausted our options. */ static int find_alternate( size_t name_len, uchar_t *name, uint32_t seq) { uint32_t bitseq = 0; uint32_t bits = seq; if (!seq) return 1; /* alternate 0 is the original name */ if (name_len < 2) /* Must have 2 bytes to flip */ return -1; for (bitseq = 0; bits; bitseq++) { uint32_t mask = 1 << bitseq; int fb; if (!(bits & mask)) continue; fb = flip_bit(name_len, name, bitseq); if (fb < 1) return fb ? -1 : 0; bits ^= mask; } return 1; } /* * Look up the given name in the name table. If it is already * present, iterate through a well-defined sequence of alternate * names and attempt to use an alternate name instead. * * Returns 1 if the (possibly modified) name is not present in the * name table. Returns 0 if the name and all possible alternates * are already in the table. */ static int handle_duplicate_name(xfs_dahash_t hash, size_t name_len, uchar_t *name) { uchar_t new_name[name_len + 1]; uint32_t seq = 1; if (!nametable_find(hash, name_len, name)) return 1; /* No duplicate */ /* Name is already in use. Need to find an alternate. */ do { int found; /* Only change incoming name if we find an alternate */ do { memcpy(new_name, name, name_len); found = find_alternate(name_len, new_name, seq++); if (found < 0) return 0; /* No more to check */ } while (!found); } while (nametable_find(hash, name_len, new_name)); /* * The alternate wasn't in the table already. Pass it back * to the caller. */ memcpy(name, new_name, name_len); return 1; } static void generate_obfuscated_name( xfs_ino_t ino, int namelen, uchar_t *name) { xfs_dahash_t hash; /* * We don't obfuscate "lost+found" or any orphan files * therein. When the name table is used for extended * attributes, the inode number provided is 0, in which * case we don't need to make this check. */ if (ino && in_lost_found(ino, namelen, name)) return; /* * If the name starts with a slash, just skip over it. It * isn't included in the hash and we don't record it in the * name table. Note that the namelen value passed in does * not count the leading slash (if one is present). */ if (*name == '/') name++; /* Obfuscate the name (if possible) */ hash = libxfs_da_hashname(name, namelen); obfuscate_name(hash, namelen, name); /* * Make sure the name is not something already seen. If we * fail to find a suitable alternate, we're dealing with a * very pathological situation, and we may end up creating * a duplicate name in the metadump, so issue a warning. */ if (!handle_duplicate_name(hash, namelen, name)) { print_warning("duplicate name for inode %llu " "in dir inode %llu\n", (unsigned long long) ino, (unsigned long long) cur_ino); return; } /* Create an entry for the new name in the name table. */ if (!nametable_add(hash, namelen, name)) print_warning("unable to record name for inode %llu " "in dir inode %llu\n", (unsigned long long) ino, (unsigned long long) cur_ino); } static void obfuscate_sf_dir( xfs_dinode_t *dip) { xfs_dir2_sf_t *sfp; xfs_dir2_sf_entry_t *sfep; __uint64_t ino_dir_size; int i; sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); ino_dir_size = be64_to_cpu(dip->di_size); if (ino_dir_size > XFS_DFORK_DSIZE(dip, mp)) { ino_dir_size = XFS_DFORK_DSIZE(dip, mp); if (show_warnings) print_warning("invalid size in dir inode %llu", (long long)cur_ino); } sfep = xfs_dir2_sf_firstentry(sfp); for (i = 0; (i < sfp->hdr.count) && ((char *)sfep - (char *)sfp < ino_dir_size); i++) { /* * first check for bad name lengths. If they are bad, we * have limitations to how much can be obfuscated. */ int namelen = sfep->namelen; if (namelen == 0) { if (show_warnings) print_warning("zero length entry in dir inode " "%llu", (long long)cur_ino); if (i != sfp->hdr.count - 1) break; namelen = ino_dir_size - ((char *)&sfep->name[0] - (char *)sfp); } else if ((char *)sfep - (char *)sfp + xfs_dir2_sf_entsize_byentry(sfp, sfep) > ino_dir_size) { if (show_warnings) print_warning("entry length in dir inode %llu " "overflows space", (long long)cur_ino); if (i != sfp->hdr.count - 1) break; namelen = ino_dir_size - ((char *)&sfep->name[0] - (char *)sfp); } generate_obfuscated_name(xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)), namelen, &sfep->name[0]); sfep = (xfs_dir2_sf_entry_t *)((char *)sfep + xfs_dir2_sf_entsize_byname(sfp, namelen)); } } static void obfuscate_sf_symlink( xfs_dinode_t *dip) { __uint64_t len; char *buf; len = be64_to_cpu(dip->di_size); if (len > XFS_DFORK_DSIZE(dip, mp)) { if (show_warnings) print_warning("invalid size (%d) in symlink inode %llu", len, (long long)cur_ino); len = XFS_DFORK_DSIZE(dip, mp); } buf = (char *)XFS_DFORK_DPTR(dip); while (len > 0) buf[--len] = random() % 127 + 1; } static void obfuscate_sf_attr( xfs_dinode_t *dip) { /* * with extended attributes, obfuscate the names and zero the actual * values. */ xfs_attr_shortform_t *asfp; xfs_attr_sf_entry_t *asfep; int ino_attr_size; int i; asfp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); if (asfp->hdr.count == 0) return; ino_attr_size = be16_to_cpu(asfp->hdr.totsize); if (ino_attr_size > XFS_DFORK_ASIZE(dip, mp)) { ino_attr_size = XFS_DFORK_ASIZE(dip, mp); if (show_warnings) print_warning("invalid attr size in inode %llu", (long long)cur_ino); } asfep = &asfp->list[0]; for (i = 0; (i < asfp->hdr.count) && ((char *)asfep - (char *)asfp < ino_attr_size); i++) { int namelen = asfep->namelen; if (namelen == 0) { if (show_warnings) print_warning("zero length attr entry in inode " "%llu", (long long)cur_ino); break; } else if ((char *)asfep - (char *)asfp + XFS_ATTR_SF_ENTSIZE(asfep) > ino_attr_size) { if (show_warnings) print_warning("attr entry length in inode %llu " "overflows space", (long long)cur_ino); break; } generate_obfuscated_name(0, asfep->namelen, &asfep->nameval[0]); memset(&asfep->nameval[asfep->namelen], 0, asfep->valuelen); asfep = (xfs_attr_sf_entry_t *)((char *)asfep + XFS_ATTR_SF_ENTSIZE(asfep)); } } /* * dir_data structure is used to track multi-fsblock dir2 blocks between extent * processing calls. */ static struct dir_data_s { int end_of_data; int block_index; int offset_to_entry; int bad_block; } dir_data; static void obfuscate_dir_data_blocks( char *block, xfs_dfiloff_t offset, xfs_dfilblks_t count, int is_block_format) { /* * we have to rely on the fileoffset and signature of the block to * handle it's contents. If it's invalid, leave it alone. * for multi-fsblock dir blocks, if a name crosses an extent boundary, * ignore it and continue. */ int c; int dir_offset; char *ptr; char *endptr; if (is_block_format && count != mp->m_dirblkfsbs) return; /* too complex to handle this rare case */ for (c = 0, endptr = block; c < count; c++) { if (dir_data.block_index == 0) { int wantmagic; if (offset % mp->m_dirblkfsbs != 0) return; /* corrupted, leave it alone */ dir_data.bad_block = 0; if (is_block_format) { xfs_dir2_leaf_entry_t *blp; xfs_dir2_block_tail_t *btp; btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)block); blp = xfs_dir2_block_leaf_p(btp); if ((char *)blp > (char *)btp) blp = (xfs_dir2_leaf_entry_t *)btp; dir_data.end_of_data = (char *)blp - block; wantmagic = XFS_DIR2_BLOCK_MAGIC; } else { /* leaf/node format */ dir_data.end_of_data = mp->m_dirblkfsbs << mp->m_sb.sb_blocklog; wantmagic = XFS_DIR2_DATA_MAGIC; } dir_data.offset_to_entry = offsetof(xfs_dir2_data_t, u); if (be32_to_cpu(((xfs_dir2_data_hdr_t*)block)->magic) != wantmagic) { if (show_warnings) print_warning("invalid magic in dir " "inode %llu block %ld", (long long)cur_ino, (long)offset); dir_data.bad_block = 1; } } dir_data.block_index++; if (dir_data.block_index == mp->m_dirblkfsbs) dir_data.block_index = 0; if (dir_data.bad_block) continue; dir_offset = (dir_data.block_index << mp->m_sb.sb_blocklog) + dir_data.offset_to_entry; ptr = endptr + dir_data.offset_to_entry; endptr += mp->m_sb.sb_blocksize; while (ptr < endptr && dir_offset < dir_data.end_of_data) { xfs_dir2_data_entry_t *dep; xfs_dir2_data_unused_t *dup; int length; dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { int length = be16_to_cpu(dup->length); if (dir_offset + length > dir_data.end_of_data || length == 0 || (length & (XFS_DIR2_DATA_ALIGN - 1))) { if (show_warnings) print_warning("invalid length " "for dir free space in " "inode %llu", (long long)cur_ino); dir_data.bad_block = 1; break; } if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != dir_offset) { dir_data.bad_block = 1; break; } dir_offset += length; ptr += length; if (dir_offset >= dir_data.end_of_data || ptr >= endptr) break; } dep = (xfs_dir2_data_entry_t *)ptr; length = xfs_dir2_data_entsize(dep->namelen); if (dir_offset + length > dir_data.end_of_data || ptr + length > endptr) { if (show_warnings) print_warning("invalid length for " "dir entry name in inode %llu", (long long)cur_ino); break; } if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) != dir_offset) { dir_data.bad_block = 1; break; } generate_obfuscated_name(be64_to_cpu(dep->inumber), dep->namelen, &dep->name[0]); dir_offset += length; ptr += length; } dir_data.offset_to_entry = dir_offset & (mp->m_sb.sb_blocksize - 1); } } static void obfuscate_symlink_blocks( char *block, xfs_dfilblks_t count) { int i; count <<= mp->m_sb.sb_blocklog; for (i = 0; i < count; i++) block[i] = random() % 127 + 1; } #define MAX_REMOTE_VALS 4095 static struct attr_data_s { int remote_val_count; xfs_dablk_t remote_vals[MAX_REMOTE_VALS]; } attr_data; static inline void add_remote_vals( xfs_dablk_t blockidx, int length) { while (length > 0 && attr_data.remote_val_count < MAX_REMOTE_VALS) { attr_data.remote_vals[attr_data.remote_val_count] = blockidx; attr_data.remote_val_count++; blockidx++; length -= XFS_LBSIZE(mp); } } static void obfuscate_attr_blocks( char *block, xfs_dfiloff_t offset, xfs_dfilblks_t count) { xfs_attr_leafblock_t *leaf; int c; int i; int nentries; xfs_attr_leaf_entry_t *entry; xfs_attr_leaf_name_local_t *local; xfs_attr_leaf_name_remote_t *remote; for (c = 0; c < count; c++, offset++, block += XFS_LBSIZE(mp)) { leaf = (xfs_attr_leafblock_t *)block; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) { for (i = 0; i < attr_data.remote_val_count; i++) { if (attr_data.remote_vals[i] == offset) memset(block, 0, XFS_LBSIZE(mp)); } continue; } nentries = be16_to_cpu(leaf->hdr.count); if (nentries * sizeof(xfs_attr_leaf_entry_t) + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) { if (show_warnings) print_warning("invalid attr count in inode %llu", (long long)cur_ino); continue; } for (i = 0, entry = &leaf->entries[0]; i < nentries; i++, entry++) { if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) { if (show_warnings) print_warning("invalid attr nameidx " "in inode %llu", (long long)cur_ino); break; } if (entry->flags & XFS_ATTR_LOCAL) { local = xfs_attr_leaf_name_local(leaf, i); if (local->namelen == 0) { if (show_warnings) print_warning("zero length for " "attr name in inode %llu", (long long)cur_ino); break; } generate_obfuscated_name(0, local->namelen, &local->nameval[0]); memset(&local->nameval[local->namelen], 0, be16_to_cpu(local->valuelen)); } else { remote = xfs_attr_leaf_name_remote(leaf, i); if (remote->namelen == 0 || remote->valueblk == 0) { if (show_warnings) print_warning("invalid attr " "entry in inode %llu", (long long)cur_ino); break; } generate_obfuscated_name(0, remote->namelen, &remote->name[0]); add_remote_vals(be32_to_cpu(remote->valueblk), be32_to_cpu(remote->valuelen)); } } } } /* inode copy routines */ static int process_bmbt_reclist( xfs_bmbt_rec_t *rp, int numrecs, typnm_t btype) { int i; xfs_dfiloff_t o, op = NULLDFILOFF; xfs_dfsbno_t s; xfs_dfilblks_t c, cp = NULLDFILOFF; int f; xfs_dfiloff_t last; xfs_agnumber_t agno; xfs_agblock_t agbno; if (btype == TYP_DATA) return 1; convert_extent(&rp[numrecs - 1], &o, &s, &c, &f); last = o + c; for (i = 0; i < numrecs; i++, rp++) { convert_extent(rp, &o, &s, &c, &f); /* * ignore extents that are clearly bogus, and if a bogus * one is found, stop processing remaining extents */ if (i > 0 && op + cp > o) { if (show_warnings) print_warning("bmap extent %d in %s ino %llu " "starts at %llu, previous extent " "ended at %llu", i, typtab[btype].name, (long long)cur_ino, o, op + cp - 1); break; } if (c > max_extent_size) { /* * since we are only processing non-data extents, * large numbers of blocks in a metadata extent is * extremely rare and more than likely to be corrupt. */ if (show_warnings) print_warning("suspicious count %u in bmap " "extent %d in %s ino %llu", c, i, typtab[btype].name, (long long)cur_ino); break; } op = o; cp = c; agno = XFS_FSB_TO_AGNO(mp, s); agbno = XFS_FSB_TO_AGBNO(mp, s); if (!valid_bno(agno, agbno)) { if (show_warnings) print_warning("invalid block number %u/%u " "(%llu) in bmap extent %d in %s ino " "%llu", agno, agbno, s, i, typtab[btype].name, (long long)cur_ino); break; } if (!valid_bno(agno, agbno + c - 1)) { if (show_warnings) print_warning("bmap extent %i in %s inode %llu " "overflows AG (end is %u/%u)", i, typtab[btype].name, (long long)cur_ino, agno, agbno + c - 1); break; } push_cur(); set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), c * blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read %s block %u/%u (%llu)", typtab[btype].name, agno, agbno, s); if (stop_on_read_error) { pop_cur(); return 0; } } else { if (!dont_obfuscate) switch (btype) { case TYP_DIR2: if (o < mp->m_dirleafblk) obfuscate_dir_data_blocks( iocur_top->data, o, c, last == mp->m_dirblkfsbs); break; case TYP_SYMLINK: obfuscate_symlink_blocks( iocur_top->data, c); break; case TYP_ATTR: obfuscate_attr_blocks(iocur_top->data, o, c); break; default: ; } if (!write_buf(iocur_top)) { pop_cur(); return 0; } } pop_cur(); } return 1; } static int scanfunc_bmap( struct xfs_btree_block *block, xfs_agnumber_t agno, xfs_agblock_t agbno, int level, typnm_t btype, void *arg) /* ptr to itype */ { int i; xfs_bmbt_ptr_t *pp; int nrecs; nrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (nrecs > mp->m_bmap_dmxr[0]) { if (show_warnings) print_warning("invalid numrecs (%u) in %s " "block %u/%u", nrecs, typtab[btype].name, agno, agbno); return 1; } return process_bmbt_reclist(XFS_BMBT_REC_ADDR(mp, block, 1), nrecs, *(typnm_t*)arg); } if (nrecs > mp->m_bmap_dmxr[1]) { if (show_warnings) print_warning("invalid numrecs (%u) in %s block %u/%u", nrecs, typtab[btype].name, agno, agbno); return 1; } pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < nrecs; i++) { xfs_agnumber_t ag; xfs_agblock_t bno; ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); if (bno == 0 || bno > mp->m_sb.sb_agblocks || ag > mp->m_sb.sb_agcount) { if (show_warnings) print_warning("invalid block number (%u/%u) " "in %s block %u/%u", ag, bno, typtab[btype].name, agno, agbno); continue; } if (!scan_btree(ag, bno, level, btype, arg, scanfunc_bmap)) return 0; } return 1; } static int process_btinode( xfs_dinode_t *dip, typnm_t itype) { xfs_bmdr_block_t *dib; int i; xfs_bmbt_ptr_t *pp; int level; int nrecs; int maxrecs; int whichfork; typnm_t btype; whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; btype = (itype == TYP_ATTR) ? TYP_BMAPBTA : TYP_BMAPBTD; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); level = be16_to_cpu(dib->bb_level); nrecs = be16_to_cpu(dib->bb_numrecs); if (level > XFS_BM_MAXLEVELS(mp, whichfork)) { if (show_warnings) print_warning("invalid level (%u) in inode %lld %s " "root", level, (long long)cur_ino, typtab[btype].name); return 1; } if (level == 0) { return process_bmbt_reclist(XFS_BMDR_REC_ADDR(dib, 1), nrecs, itype); } maxrecs = xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 0); if (nrecs > maxrecs) { if (show_warnings) print_warning("invalid numrecs (%u) in inode %lld %s " "root", nrecs, (long long)cur_ino, typtab[btype].name); return 1; } pp = XFS_BMDR_PTR_ADDR(dib, 1, maxrecs); for (i = 0; i < nrecs; i++) { xfs_agnumber_t ag; xfs_agblock_t bno; ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); if (bno == 0 || bno > mp->m_sb.sb_agblocks || ag > mp->m_sb.sb_agcount) { if (show_warnings) print_warning("invalid block number (%u/%u) " "in inode %llu %s root", ag, bno, (long long)cur_ino, typtab[btype].name); continue; } if (!scan_btree(ag, bno, level, btype, &itype, scanfunc_bmap)) return 0; } return 1; } static int process_exinode( xfs_dinode_t *dip, typnm_t itype) { int whichfork; xfs_extnum_t nex; whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; nex = XFS_DFORK_NEXTENTS(dip, whichfork); if (nex < 0 || nex > XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { if (show_warnings) print_warning("bad number of extents %d in inode %lld", nex, (long long)cur_ino); return 1; } return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork), nex, itype); } static int process_inode_data( xfs_dinode_t *dip, typnm_t itype) { switch (dip->di_format) { case XFS_DINODE_FMT_LOCAL: if (!dont_obfuscate) switch (itype) { case TYP_DIR2: obfuscate_sf_dir(dip); break; case TYP_SYMLINK: obfuscate_sf_symlink(dip); break; default: ; } break; case XFS_DINODE_FMT_EXTENTS: return process_exinode(dip, itype); case XFS_DINODE_FMT_BTREE: return process_btinode(dip, itype); } return 1; } static int process_inode( xfs_agnumber_t agno, xfs_agino_t agino, xfs_dinode_t *dip) { int success; success = 1; cur_ino = XFS_AGINO_TO_INO(mp, agno, agino); /* copy appropriate data fork metadata */ switch (be16_to_cpu(dip->di_mode) & S_IFMT) { case S_IFDIR: memset(&dir_data, 0, sizeof(dir_data)); success = process_inode_data(dip, TYP_DIR2); break; case S_IFLNK: success = process_inode_data(dip, TYP_SYMLINK); break; case S_IFREG: success = process_inode_data(dip, TYP_DATA); break; default: ; } nametable_clear(); /* copy extended attributes if they exist and forkoff is valid */ if (success && XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) { attr_data.remote_val_count = 0; switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: if (!dont_obfuscate) obfuscate_sf_attr(dip); break; case XFS_DINODE_FMT_EXTENTS: success = process_exinode(dip, TYP_ATTR); break; case XFS_DINODE_FMT_BTREE: success = process_btinode(dip, TYP_ATTR); break; } nametable_clear(); } return success; } static __uint32_t inodes_copied = 0; static int copy_inode_chunk( xfs_agnumber_t agno, xfs_inobt_rec_t *rp) { xfs_agino_t agino; int off; xfs_agblock_t agbno; int i; int rval = 0; agino = be32_to_cpu(rp->ir_startino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); off = XFS_INO_TO_OFFSET(mp, agino); if (agino == 0 || agino == NULLAGINO || !valid_bno(agno, agbno) || !valid_bno(agno, XFS_AGINO_TO_AGBNO(mp, agino + XFS_INODES_PER_CHUNK - 1))) { if (show_warnings) print_warning("bad inode number %llu (%u/%u)", XFS_AGINO_TO_INO(mp, agno, agino), agno, agino); return 1; } push_cur(); set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)), DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read inode block %u/%u", agno, agbno); rval = !stop_on_read_error; goto pop_out; } /* * check for basic assumptions about inode chunks, and if any * assumptions fail, don't process the inode chunk. */ if ((mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK && off != 0) || (mp->m_sb.sb_inopblock > XFS_INODES_PER_CHUNK && off % XFS_INODES_PER_CHUNK != 0) || (xfs_sb_version_hasalign(&mp->m_sb) && agbno % mp->m_sb.sb_inoalignmt != 0)) { if (show_warnings) print_warning("badly aligned inode (start = %llu)", XFS_AGINO_TO_INO(mp, agno, agino)); goto skip_processing; } /* * scan through inodes and copy any btree extent lists, directory * contents and extended attributes. */ for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { xfs_dinode_t *dip; if (XFS_INOBT_IS_FREE_DISK(rp, i)) continue; dip = (xfs_dinode_t *)((char *)iocur_top->data + ((off + i) << mp->m_sb.sb_inodelog)); if (!process_inode(agno, agino + i, dip)) goto pop_out; } skip_processing: if (!write_buf(iocur_top)) goto pop_out; inodes_copied += XFS_INODES_PER_CHUNK; if (show_progress) print_progress("Copied %u of %u inodes (%u of %u AGs)", inodes_copied, mp->m_sb.sb_icount, agno, mp->m_sb.sb_agcount); rval = 1; pop_out: pop_cur(); return rval; } static int scanfunc_ino( struct xfs_btree_block *block, xfs_agnumber_t agno, xfs_agblock_t agbno, int level, typnm_t btype, void *arg) { xfs_inobt_rec_t *rp; xfs_inobt_ptr_t *pp; int i; int numrecs; numrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (numrecs > mp->m_inobt_mxr[0]) { if (show_warnings) print_warning("invalid numrecs %d in %s " "block %u/%u", numrecs, typtab[btype].name, agno, agbno); numrecs = mp->m_inobt_mxr[0]; } rp = XFS_INOBT_REC_ADDR(mp, block, 1); for (i = 0; i < numrecs; i++, rp++) { if (!copy_inode_chunk(agno, rp)) return 0; } return 1; } if (numrecs > mp->m_inobt_mxr[1]) { if (show_warnings) print_warning("invalid numrecs %d in %s block %u/%u", numrecs, typtab[btype].name, agno, agbno); numrecs = mp->m_inobt_mxr[1]; } pp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]); for (i = 0; i < numrecs; i++) { if (!valid_bno(agno, be32_to_cpu(pp[i]))) { if (show_warnings) print_warning("invalid block number (%u/%u) " "in %s block %u/%u", agno, be32_to_cpu(pp[i]), typtab[btype].name, agno, agbno); continue; } if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg, scanfunc_ino)) return 0; } return 1; } static int copy_inodes( xfs_agnumber_t agno, xfs_agi_t *agi) { xfs_agblock_t root; int levels; root = be32_to_cpu(agi->agi_root); levels = be32_to_cpu(agi->agi_level); /* validate root and levels before processing the tree */ if (root == 0 || root > mp->m_sb.sb_agblocks) { if (show_warnings) print_warning("invalid block number (%u) in inobt " "root in agi %u", root, agno); return 1; } if (levels >= XFS_BTREE_MAXLEVELS) { if (show_warnings) print_warning("invalid level (%u) in inobt root " "in agi %u", levels, agno); return 1; } return scan_btree(agno, root, levels, TYP_INOBT, agi, scanfunc_ino); } static int scan_ag( xfs_agnumber_t agno) { xfs_agf_t *agf; xfs_agi_t *agi; int stack_count = 0; int rval = 0; /* copy the superblock of the AG */ push_cur(); stack_count++; set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (!iocur_top->data) { print_warning("cannot read superblock for ag %u", agno); if (stop_on_read_error) goto pop_out; } else { if (!write_buf(iocur_top)) goto pop_out; } /* copy the AG free space btree root */ push_cur(); stack_count++; set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agf = iocur_top->data; if (iocur_top->data == NULL) { print_warning("cannot read agf block for ag %u", agno); if (stop_on_read_error) goto pop_out; } else { if (!write_buf(iocur_top)) goto pop_out; } /* copy the AG inode btree root */ push_cur(); stack_count++; set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agi = iocur_top->data; if (iocur_top->data == NULL) { print_warning("cannot read agi block for ag %u", agno); if (stop_on_read_error) goto pop_out; } else { if (!write_buf(iocur_top)) goto pop_out; } /* copy the AG free list header */ push_cur(); stack_count++; set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read agfl block for ag %u", agno); if (stop_on_read_error) goto pop_out; } else { if (!write_buf(iocur_top)) goto pop_out; } /* copy AG free space btrees */ if (agf) { if (show_progress) print_progress("Copying free space trees of AG %u", agno); if (!copy_free_bno_btree(agno, agf)) goto pop_out; if (!copy_free_cnt_btree(agno, agf)) goto pop_out; } /* copy inode btrees and the inodes and their associated metadata */ if (agi) { if (!copy_inodes(agno, agi)) goto pop_out; } rval = 1; pop_out: while (stack_count--) pop_cur(); return rval; } static int copy_ino( xfs_ino_t ino, typnm_t itype) { xfs_agnumber_t agno; xfs_agblock_t agbno; xfs_agino_t agino; int offset; int rval = 0; if (ino == 0) return 1; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); offset = XFS_AGINO_TO_OFFSET(mp, agino); if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || offset >= mp->m_sb.sb_inopblock) { if (show_warnings) print_warning("invalid %s inode number (%lld)", typtab[itype].name, (long long)ino); return 1; } push_cur(); set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read %s inode %lld", typtab[itype].name, (long long)ino); rval = !stop_on_read_error; goto pop_out; } off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); cur_ino = ino; rval = process_inode_data(iocur_top->data, itype); pop_out: pop_cur(); return rval; } static int copy_sb_inodes(void) { if (!copy_ino(mp->m_sb.sb_rbmino, TYP_RTBITMAP)) return 0; if (!copy_ino(mp->m_sb.sb_rsumino, TYP_RTSUMMARY)) return 0; if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK)) return 0; return copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK); } static int copy_log(void) { if (show_progress) print_progress("Copying log"); push_cur(); set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { pop_cur(); print_warning("cannot read log"); return !stop_on_read_error; } return write_buf(iocur_top); } static int metadump_f( int argc, char **argv) { xfs_agnumber_t agno; int c; int start_iocur_sp; char *p; exitcode = 1; show_progress = 0; show_warnings = 0; stop_on_read_error = 0; if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) { print_warning("bad superblock magic number %x, giving up", mp->m_sb.sb_magicnum); return 0; } while ((c = getopt(argc, argv, "egm:ow")) != EOF) { switch (c) { case 'e': stop_on_read_error = 1; break; case 'g': show_progress = 1; break; case 'm': max_extent_size = (int)strtol(optarg, &p, 0); if (*p != '\0' || max_extent_size <= 0) { print_warning("bad max extent size %s", optarg); return 0; } break; case 'o': dont_obfuscate = 1; break; case 'w': show_warnings = 1; break; default: print_warning("bad option for metadump command"); return 0; } } if (optind != argc - 1) { print_warning("too few options for metadump (no filename given)"); return 0; } metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE); if (metablock == NULL) { print_warning("memory allocation failure"); return 0; } metablock->mb_blocklog = BBSHIFT; metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC); block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t)); block_buffer = (char *)metablock + BBSIZE; num_indicies = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64); cur_index = 0; start_iocur_sp = iocur_sp; if (strcmp(argv[optind], "-") == 0) { if (isatty(fileno(stdout))) { print_warning("cannot write to a terminal"); free(metablock); return 0; } outf = stdout; } else { outf = fopen(argv[optind], "wb"); if (outf == NULL) { print_warning("cannot create dump file"); free(metablock); return 0; } } exitcode = 0; for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { if (!scan_ag(agno)) { exitcode = 1; break; } } /* copy realtime and quota inode contents */ if (!exitcode) exitcode = !copy_sb_inodes(); /* copy log if it's internal */ if ((mp->m_sb.sb_logstart != 0) && !exitcode) exitcode = !copy_log(); /* write the remaining index */ if (!exitcode) exitcode = !write_index(); if (progress_since_warning) fputc('\n', (outf == stdout) ? stderr : stdout); if (outf != stdout) fclose(outf); /* cleanup iocur stack */ while (iocur_sp > start_iocur_sp) pop_cur(); free(metablock); return 0; } xfsprogs-3.1.9ubuntu2/db/convert.h0000664000000000000000000000137011140033220014015 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void convert_init(void); xfsprogs-3.1.9ubuntu2/db/fprint.h0000664000000000000000000000257011140033220013642 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef int (*prfnc_t)(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int fp_charns(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int fp_num(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int fp_sarray(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int fp_time(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int fp_uuid(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); xfsprogs-3.1.9ubuntu2/db/command.h0000664000000000000000000000233011140033220013750 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef int (*cfunc_t)(int argc, char **argv); typedef void (*helpfunc_t)(void); typedef struct cmdinfo { const char *name; const char *altname; cfunc_t cfunc; int argmin; int argmax; int canpush; const char *args; const char *oneline; helpfunc_t help; } cmdinfo_t; extern cmdinfo_t *cmdtab; extern int ncmds; extern void add_command(const cmdinfo_t *ci); extern int command(int argc, char **argv); extern const cmdinfo_t *find_command(const char *cmd); extern void init_commands(void); xfsprogs-3.1.9ubuntu2/db/inode.h0000664000000000000000000000254611140033220013441 0ustar /* * Copyright (c) 2000-2001 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field inode_a_flds[]; extern const struct field inode_core_flds[]; extern const struct field inode_flds[]; extern const struct field inode_hfld[]; extern const struct field inode_u_flds[]; extern const struct field timestamp_flds[]; extern int fp_dinode_fmt(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); extern int inode_a_size(void *obj, int startoff, int idx); extern void inode_init(void); extern typnm_t inode_next_type(void); extern int inode_size(void *obj, int startoff, int idx); extern int inode_u_size(void *obj, int startoff, int idx); extern void set_cur_inode(xfs_ino_t ino); xfsprogs-3.1.9ubuntu2/db/agi.h0000664000000000000000000000157011140033220013077 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field agi_flds[]; extern const struct field agi_hfld[]; extern void agi_init(void); extern int agi_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/input.c0000664000000000000000000001350411146407622013512 0ustar /* * Copyright (c) 2000-2003 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "command.h" #include "input.h" #include "output.h" #include "sig.h" #include "malloc.h" #include "init.h" #if defined(ENABLE_READLINE) # include # include #elif defined(ENABLE_EDITLINE) # include #endif int inputstacksize; FILE **inputstack; FILE *curinput; static void popfile(void); static int source_f(int argc, char **argv); static const cmdinfo_t source_cmd = { "source", NULL, source_f, 1, 1, 0, N_("source-file"), N_("get commands from source-file"), NULL }; /* our homegrown strtok that understands strings */ static char * tokenize( char *inp) { static char *last_place = NULL; char *start; char *walk; int in_string = 0; int in_escape = 0; if (inp) { start = inp; } else { if (last_place == NULL) return NULL; /* we're done */ if (*last_place != '\0') return NULL; start = last_place + 1; } last_place = NULL; /* eat whitespace */ while (*start == ' ' || *start == '\t') start++; walk = start; for (;*walk != '\0'; walk++) { if (in_escape) { in_escape = 0; continue; } if (*walk == '\\') in_escape = 1; else if (*walk == '\"') in_string ^= 1; if (!in_string && !in_escape && (*walk == ' ' || *walk == '\t')) { last_place = walk; *last_place = '\0'; break; } } if (walk == start) return NULL; return start; } char ** breakline( char *input, int *count) { int c; char *inp; char *p; char **rval; c = 0; inp = input; rval = xcalloc(sizeof(char *), 1); for (;;) { p = tokenize(inp); if (p == NULL) break; inp = NULL; c++; rval = xrealloc(rval, sizeof(*rval) * (c + 1)); rval[c - 1] = p; rval[c] = NULL; } *count = c; return rval; } void doneline( char *input, char **vec) { xfree(input); xfree(vec); } static char * get_prompt(void) { static char prompt[FILENAME_MAX + 1]; if (!prompt[0]) snprintf(prompt, sizeof(prompt), "%s> ", progname); return prompt; } static char * fetchline_internal(void) { char buf[1024]; int iscont; size_t len; size_t rlen; char *rval; rval = NULL; for (rlen = iscont = 0; ; ) { if (inputstacksize == 1) { if (iscont) dbprintf("... "); else dbprintf(get_prompt(), progname); fflush(stdin); } if (seenint() || (!fgets(buf, sizeof(buf), curinput) && ferror(curinput) && seenint())) { clearint(); dbprintf("^C\n"); clearerr(curinput); if (iscont) { iscont = 0; rlen = 0; if (rval) { xfree(rval); rval = NULL; } } continue; } if (ferror(curinput) || feof(curinput) || (len = strlen(buf)) == 0) { popfile(); if (curinput == NULL) { dbprintf("\n"); return NULL; } iscont = 0; rlen = 0; if (rval) { xfree(rval); rval = NULL; } continue; } if (inputstacksize == 1) logprintf("%s", buf); rval = xrealloc(rval, rlen + len + 1); if (rlen == 0) rval[0] = '\0'; rlen += len; strcat(rval, buf); if (buf[len - 1] == '\n') { if (len > 1 && buf[len - 2] == '\\') { rval[rlen - 2] = ' '; rval[rlen - 1] = '\0'; rlen--; iscont = 1; } else { rval[rlen - 1] = '\0'; rlen--; break; } } } return rval; } #ifdef ENABLE_READLINE char * fetchline(void) { char *line; if (inputstacksize == 1) { line = readline(get_prompt()); if (line && *line) { add_history(line); logprintf("%s", line); } } else { line = fetchline_internal(); } return line; } #elif defined(ENABLE_EDITLINE) static char *el_get_prompt(EditLine *e) { return get_prompt(); } char * fetchline(void) { static EditLine *el; static History *hist; HistEvent hevent; char *line; int count; if (!el) { hist = history_init(); history(hist, &hevent, H_SETSIZE, 100); el = el_init(progname, stdin, stdout, stderr); el_source(el, NULL); el_set(el, EL_SIGNAL, 1); el_set(el, EL_PROMPT, el_get_prompt); el_set(el, EL_HIST, history, (const char *)hist); } if (inputstacksize == 1) { line = xstrdup(el_gets(el, &count)); if (line) { if (count > 0) line[count-1] = '\0'; if (*line) { history(hist, &hevent, H_ENTER, line); logprintf("%s", line); } } } else { line = fetchline_internal(); } return line; } #else char * fetchline(void) { return fetchline_internal(); } #endif static void popfile(void) { if (inputstacksize == 0) { curinput = NULL; return; } if (curinput != stdin) fclose(curinput); inputstacksize--; if (inputstacksize) { inputstack = xrealloc(inputstack, inputstacksize * sizeof(*inputstack)); curinput = inputstack[inputstacksize - 1]; } else { free(inputstack); curinput = NULL; inputstack = NULL; } } void pushfile( FILE *file) { inputstack = xrealloc(inputstack, (inputstacksize + 1) * sizeof(*inputstack)); inputstacksize++; curinput = inputstack[inputstacksize - 1] = file; } /* ARGSUSED */ static int source_f( int argc, char **argv) { FILE *f; f = fopen(argv[1], "r"); if (f == NULL) dbprintf(_("can't open %s\n"), argv[0]); else pushfile(f); return 0; } void input_init(void) { add_command(&source_cmd); } xfsprogs-3.1.9ubuntu2/db/frag.h0000664000000000000000000000136511140033220013260 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void frag_init(void); xfsprogs-3.1.9ubuntu2/db/attr.c0000664000000000000000000002720511650373060013326 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bit.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "attr.h" #include "io.h" #include "init.h" static int attr_leaf_entries_count(void *obj, int startoff); static int attr_leaf_hdr_count(void *obj, int startoff); static int attr_leaf_name_local_count(void *obj, int startoff); static int attr_leaf_name_local_name_count(void *obj, int startoff); static int attr_leaf_name_local_value_count(void *obj, int startoff); static int attr_leaf_name_local_value_offset(void *obj, int startoff, int idx); static int attr_leaf_name_remote_count(void *obj, int startoff); static int attr_leaf_name_remote_name_count(void *obj, int startoff); static int attr_leaf_nvlist_count(void *obj, int startoff); static int attr_leaf_nvlist_offset(void *obj, int startoff, int idx); static int attr_node_btree_count(void *obj, int startoff); static int attr_node_hdr_count(void *obj, int startoff); const field_t attr_hfld[] = { { "", FLDT_ATTR, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define LOFF(f) bitize(offsetof(xfs_attr_leafblock_t, f)) #define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f)) const field_t attr_flds[] = { { "hdr", FLDT_ATTR_LEAF_HDR, OI(LOFF(hdr)), attr_leaf_hdr_count, FLD_COUNT, TYP_NONE }, { "hdr", FLDT_ATTR_NODE_HDR, OI(NOFF(hdr)), attr_node_hdr_count, FLD_COUNT, TYP_NONE }, { "entries", FLDT_ATTR_LEAF_ENTRY, OI(LOFF(entries)), attr_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(btree)), attr_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset, attr_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { NULL } }; #define BOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f)) const field_t attr_blkinfo_flds[] = { { "forw", FLDT_ATTRBLOCK, OI(BOFF(forw)), C1, 0, TYP_ATTR }, { "back", FLDT_ATTRBLOCK, OI(BOFF(back)), C1, 0, TYP_ATTR }, { "magic", FLDT_UINT16X, OI(BOFF(magic)), C1, 0, TYP_NONE }, { "pad", FLDT_UINT16X, OI(BOFF(pad)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; #define LEOFF(f) bitize(offsetof(xfs_attr_leaf_entry_t, f)) const field_t attr_leaf_entry_flds[] = { { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE }, { "nameidx", FLDT_UINT16D, OI(LEOFF(nameidx)), C1, 0, TYP_NONE }, { "flags", FLDT_UINT8X, OI(LEOFF(flags)), C1, FLD_SKIPALL, TYP_NONE }, { "incomplete", FLDT_UINT1, OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_INCOMPLETE_BIT - 1), C1, 0, TYP_NONE }, { "root", FLDT_UINT1, OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_ROOT_BIT - 1), C1, 0, TYP_NONE }, { "secure", FLDT_UINT1, OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_SECURE_BIT - 1), C1, 0, TYP_NONE }, { "local", FLDT_UINT1, OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_LOCAL_BIT - 1), C1, 0, TYP_NONE }, { "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; #define LHOFF(f) bitize(offsetof(xfs_attr_leaf_hdr_t, f)) const field_t attr_leaf_hdr_flds[] = { { "info", FLDT_ATTR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE }, { "usedbytes", FLDT_UINT16D, OI(LHOFF(usedbytes)), C1, 0, TYP_NONE }, { "firstused", FLDT_UINT16D, OI(LHOFF(firstused)), C1, 0, TYP_NONE }, { "holes", FLDT_UINT8D, OI(LHOFF(holes)), C1, 0, TYP_NONE }, { "pad1", FLDT_UINT8X, OI(LHOFF(pad1)), C1, FLD_SKIPALL, TYP_NONE }, { "freemap", FLDT_ATTR_LEAF_MAP, OI(LHOFF(freemap)), CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE }, { NULL } }; #define LMOFF(f) bitize(offsetof(xfs_attr_leaf_map_t, f)) const field_t attr_leaf_map_flds[] = { { "base", FLDT_UINT16D, OI(LMOFF(base)), C1, 0, TYP_NONE }, { "size", FLDT_UINT16D, OI(LMOFF(size)), C1, 0, TYP_NONE }, { NULL } }; #define LNOFF(f) bitize(offsetof(xfs_attr_leaf_name_local_t, f)) #define LVOFF(f) bitize(offsetof(xfs_attr_leaf_name_remote_t, f)) const field_t attr_leaf_name_flds[] = { { "valuelen", FLDT_UINT16D, OI(LNOFF(valuelen)), attr_leaf_name_local_count, FLD_COUNT, TYP_NONE }, { "namelen", FLDT_UINT8D, OI(LNOFF(namelen)), attr_leaf_name_local_count, FLD_COUNT, TYP_NONE }, { "name", FLDT_CHARNS, OI(LNOFF(nameval)), attr_leaf_name_local_name_count, FLD_COUNT, TYP_NONE }, { "value", FLDT_CHARNS, attr_leaf_name_local_value_offset, attr_leaf_name_local_value_count, FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "valueblk", FLDT_UINT32X, OI(LVOFF(valueblk)), attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE }, { "valuelen", FLDT_UINT32D, OI(LVOFF(valuelen)), attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE }, { "namelen", FLDT_UINT8D, OI(LVOFF(namelen)), attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE }, { "name", FLDT_CHARNS, OI(LVOFF(name)), attr_leaf_name_remote_name_count, FLD_COUNT, TYP_NONE }, { NULL } }; #define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f)) const field_t attr_node_entry_flds[] = { { "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE }, { "before", FLDT_ATTRBLOCK, OI(EOFF(before)), C1, 0, TYP_ATTR }, { NULL } }; #define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f)) const field_t attr_node_hdr_flds[] = { { "info", FLDT_ATTR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE }, { NULL } }; /*ARGSUSED*/ static int attr_leaf_entries_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int attr_leaf_hdr_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; ASSERT(startoff == 0); block = obj; return be16_to_cpu(block->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC; } static int attr_leaf_name_local_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; int i; int off; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) return (e->flags & XFS_ATTR_LOCAL) != 0; } return 0; } static int attr_leaf_name_local_name_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; int i; xfs_attr_leaf_name_local_t *l; int off; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) { if (e->flags & XFS_ATTR_LOCAL) { l = xfs_attr_leaf_name_local(block, i); return l->namelen; } else return 0; } } return 0; } static int attr_leaf_name_local_value_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; int i; xfs_attr_leaf_name_local_t *l; int off; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) { if (e->flags & XFS_ATTR_LOCAL) { l = xfs_attr_leaf_name_local(block, i); return be16_to_cpu(l->valuelen); } else return 0; } } return 0; } /*ARGSUSED*/ static int attr_leaf_name_local_value_offset( void *obj, int startoff, int idx) { xfs_attr_leafblock_t *block; xfs_attr_leaf_name_local_t *l; char *vp; int off; xfs_attr_leaf_entry_t *e; int i; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) break; } if (i >= be16_to_cpu(block->hdr.count)) return 0; l = xfs_attr_leaf_name_local(block, i); vp = (char *)&l->nameval[l->namelen]; return (int)bitize(vp - (char *)l); } static int attr_leaf_name_remote_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; int i; int off; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) return (e->flags & XFS_ATTR_LOCAL) == 0; } return 0; } static int attr_leaf_name_remote_name_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; int i; int off; xfs_attr_leaf_name_remote_t *r; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) { if (!(e->flags & XFS_ATTR_LOCAL)) { r = xfs_attr_leaf_name_remote(block, i); return r->namelen; } else return 0; } } return 0; } /*ARGSUSED*/ int attr_leaf_name_size( void *obj, int startoff, int idx) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; xfs_attr_leaf_name_local_t *l; xfs_attr_leaf_name_remote_t *r; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; e = &block->entries[idx]; if (e->flags & XFS_ATTR_LOCAL) { l = xfs_attr_leaf_name_local(block, idx); return (int)bitize(xfs_attr_leaf_entsize_local(l->namelen, be16_to_cpu(l->valuelen))); } else { r = xfs_attr_leaf_name_remote(block, idx); return (int)bitize(xfs_attr_leaf_entsize_remote(r->namelen)); } } /*ARGSUSED*/ static int attr_leaf_nvlist_count( void *obj, int startoff) { xfs_attr_leafblock_t *block; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int attr_leaf_nvlist_offset( void *obj, int startoff, int idx) { xfs_attr_leafblock_t *block; xfs_attr_leaf_entry_t *e; ASSERT(startoff == 0); block = obj; e = &block->entries[idx]; return bitize(be16_to_cpu(e->nameidx)); } /*ARGSUSED*/ static int attr_node_btree_count( void *obj, int startoff) { xfs_da_intnode_t *block; ASSERT(startoff == 0); /* this is a base structure */ block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int attr_node_hdr_count( void *obj, int startoff) { xfs_da_intnode_t *block; ASSERT(startoff == 0); block = obj; return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ int attr_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_blocksize); } xfsprogs-3.1.9ubuntu2/db/agfl.h0000664000000000000000000000157411140033220013254 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field agfl_flds[]; extern const struct field agfl_hfld[]; extern void agfl_init(void); extern int agfl_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/faddr.c0000664000000000000000000002045311146407622013434 0ustar /* * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "fprint.h" #include "faddr.h" #include "field.h" #include "inode.h" #include "io.h" #include "bit.h" #include "bmap.h" #include "output.h" #include "init.h" void fa_agblock( void *obj, int bit, typnm_t next) { xfs_agblock_t bno; if (cur_agno == NULLAGNUMBER) { dbprintf(_("no current allocation group, cannot set new addr\n")); return; } bno = (xfs_agblock_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLAGBLOCK) { dbprintf(_("null block number, cannot set new addr\n")); return; } ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], XFS_AGB_TO_DADDR(mp, cur_agno, bno), blkbb, DB_RING_ADD, NULL); } /*ARGSUSED*/ void fa_agino( void *obj, int bit, typnm_t next) { xfs_agino_t agino; if (cur_agno == NULLAGNUMBER) { dbprintf(_("no current allocation group, cannot set new addr\n")); return; } agino = (xfs_agino_t)getbitval(obj, bit, bitsz(agino), BVUNSIGNED); if (agino == NULLAGINO) { dbprintf(_("null inode number, cannot set new addr\n")); return; } set_cur_inode(XFS_AGINO_TO_INO(mp, cur_agno, agino)); } /*ARGSUSED*/ void fa_attrblock( void *obj, int bit, typnm_t next) { bmap_ext_t bm; __uint32_t bno; xfs_dfsbno_t dfsbno; int nex; bno = (__uint32_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == 0) { dbprintf(_("null attribute block number, cannot set new addr\n")); return; } nex = 1; bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm); if (nex == 0) { dbprintf(_("attribute block is unmapped\n")); return; } dfsbno = bm.startblock + (bno - bm.startoff); ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD, NULL); } void fa_cfileoffa( void *obj, int bit, typnm_t next) { bmap_ext_t bm; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int nex; bno = (xfs_dfiloff_t)getbitval(obj, bit, BMBT_STARTOFF_BITLEN, BVUNSIGNED); if (bno == NULLDFILOFF) { dbprintf(_("null block number, cannot set new addr\n")); return; } nex = 1; bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm); if (nex == 0) { dbprintf(_("file block is unmapped\n")); return; } dfsbno = bm.startblock + (bno - bm.startoff); ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD, NULL); } void fa_cfileoffd( void *obj, int bit, typnm_t next) { bbmap_t bbmap; bmap_ext_t *bmp; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int nb; int nex; bno = (xfs_dfiloff_t)getbitval(obj, bit, BMBT_STARTOFF_BITLEN, BVUNSIGNED); if (bno == NULLDFILOFF) { dbprintf(_("null block number, cannot set new addr\n")); return; } nex = nb = next == TYP_DIR2 ? mp->m_dirblkfsbs : 1; bmp = malloc(nb * sizeof(*bmp)); bmap(bno, nb, XFS_DATA_FORK, &nex, bmp); if (nex == 0) { dbprintf(_("file block is unmapped\n")); free(bmp); return; } dfsbno = bmp->startblock + (bno - bmp->startoff); ASSERT(typtab[next].typnm == next); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap: NULL); free(bmp); } void fa_cfsblock( void *obj, int bit, typnm_t next) { xfs_dfsbno_t bno; int nb; bno = (xfs_dfsbno_t)getbitval(obj, bit, BMBT_STARTBLOCK_BITLEN, BVUNSIGNED); if (bno == NULLDFSBNO) { dbprintf(_("null block number, cannot set new addr\n")); return; } nb = next == TYP_DIR2 ? mp->m_dirblkfsbs : 1; ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, bno), nb * blkbb, DB_RING_ADD, NULL); } void fa_dfiloffa( void *obj, int bit, typnm_t next) { bmap_ext_t bm; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int nex; bno = (xfs_dfiloff_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLDFILOFF) { dbprintf(_("null block number, cannot set new addr\n")); return; } nex = 1; bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm); if (nex == 0) { dbprintf(_("file block is unmapped\n")); return; } dfsbno = bm.startblock + (bno - bm.startoff); ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD, NULL); } void fa_dfiloffd( void *obj, int bit, typnm_t next) { bbmap_t bbmap; bmap_ext_t *bmp; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int nb; int nex; bno = (xfs_dfiloff_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLDFILOFF) { dbprintf(_("null block number, cannot set new addr\n")); return; } nex = nb = next == TYP_DIR2 ? mp->m_dirblkfsbs : 1; bmp = malloc(nb * sizeof(*bmp)); bmap(bno, nb, XFS_DATA_FORK, &nex, bmp); if (nex == 0) { dbprintf(_("file block is unmapped\n")); free(bmp); return; } dfsbno = bmp->startblock + (bno - bmp->startoff); ASSERT(typtab[next].typnm == next); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, dfsbno), nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap : NULL); free(bmp); } void fa_dfsbno( void *obj, int bit, typnm_t next) { xfs_dfsbno_t bno; bno = (xfs_dfsbno_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLDFSBNO) { dbprintf(_("null block number, cannot set new addr\n")); return; } ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_ADD, NULL); } /*ARGSUSED*/ void fa_dirblock( void *obj, int bit, typnm_t next) { bbmap_t bbmap; bmap_ext_t *bmp; __uint32_t bno; xfs_dfsbno_t dfsbno; int nex; bno = (__uint32_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == 0) { dbprintf(_("null directory block number, cannot set new addr\n")); return; } nex = mp->m_dirblkfsbs; bmp = malloc(nex * sizeof(*bmp)); bmap(bno, mp->m_dirblkfsbs, XFS_DATA_FORK, &nex, bmp); if (nex == 0) { dbprintf(_("directory block is unmapped\n")); free(bmp); return; } dfsbno = bmp->startblock + (bno - bmp->startoff); ASSERT(typtab[next].typnm == next); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[next], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno), XFS_FSB_TO_BB(mp, mp->m_dirblkfsbs), DB_RING_ADD, nex > 1 ? &bbmap : NULL); free(bmp); } void fa_drfsbno( void *obj, int bit, typnm_t next) { xfs_drfsbno_t bno; bno = (xfs_drfsbno_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLDRFSBNO) { dbprintf(_("null block number, cannot set new addr\n")); return; } ASSERT(typtab[next].typnm == next); set_cur(&typtab[next], (__int64_t)XFS_FSB_TO_BB(mp, bno), blkbb, DB_RING_ADD, NULL); } /*ARGSUSED*/ void fa_drtbno( void *obj, int bit, typnm_t next) { xfs_drtbno_t bno; bno = (xfs_drtbno_t)getbitval(obj, bit, bitsz(bno), BVUNSIGNED); if (bno == NULLDRTBNO) { dbprintf(_("null block number, cannot set new addr\n")); return; } /* need set_cur to understand rt subvolume */ } /*ARGSUSED*/ void fa_ino( void *obj, int bit, typnm_t next) { xfs_ino_t ino; ASSERT(next == TYP_INODE); ino = (xfs_ino_t)getbitval(obj, bit, bitsz(ino), BVUNSIGNED); if (ino == NULLFSINO) { dbprintf(_("null inode number, cannot set new addr\n")); return; } set_cur_inode(ino); } void fa_ino4( void *obj, int bit, typnm_t next) { xfs_ino_t ino; xfs_dir2_ino4_t ino4; ASSERT(next == TYP_INODE); ino = (xfs_ino_t)getbitval(obj, bit, bitsz(ino4), BVUNSIGNED); if (ino == NULLFSINO) { dbprintf(_("null inode number, cannot set new addr\n")); return; } set_cur_inode(ino); } void fa_ino8( void *obj, int bit, typnm_t next) { xfs_ino_t ino; xfs_dir2_ino8_t ino8; ASSERT(next == TYP_INODE); ino = (xfs_ino_t)getbitval(obj, bit, bitsz(ino8), BVUNSIGNED); if (ino == NULLFSINO) { dbprintf(_("null inode number, cannot set new addr\n")); return; } set_cur_inode(ino); } xfsprogs-3.1.9ubuntu2/db/metadump.h0000664000000000000000000000135711140033220014156 0ustar /* * Copyright (c) 2007 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void metadump_init(void); xfsprogs-3.1.9ubuntu2/db/sb.h0000664000000000000000000000162211140033220012741 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const struct field sb_flds[]; extern const struct field sb_hfld[]; extern void sb_init(void); extern int sb_logcheck(void); extern int sb_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/block.c0000664000000000000000000001472311146407622013451 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "block.h" #include "bmap.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "inode.h" #include "io.h" #include "output.h" #include "init.h" static int ablock_f(int argc, char **argv); static void ablock_help(void); static int daddr_f(int argc, char **argv); static void daddr_help(void); static int dblock_f(int argc, char **argv); static void dblock_help(void); static int fsblock_f(int argc, char **argv); static void fsblock_help(void); static void print_rawdata(void *data, int len); static const cmdinfo_t ablock_cmd = { "ablock", NULL, ablock_f, 1, 1, 1, N_("filoff"), N_("set address to file offset (attr fork)"), ablock_help }; static const cmdinfo_t daddr_cmd = { "daddr", NULL, daddr_f, 0, 1, 1, N_("[d]"), N_("set address to daddr value"), daddr_help }; static const cmdinfo_t dblock_cmd = { "dblock", NULL, dblock_f, 1, 1, 1, N_("filoff"), N_("set address to file offset (data fork)"), dblock_help }; static const cmdinfo_t fsblock_cmd = { "fsblock", "fsb", fsblock_f, 0, 1, 1, N_("[fsb]"), N_("set address to fsblock value"), fsblock_help }; static void ablock_help(void) { dbprintf(_( "\n Example:\n" "\n" " 'ablock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's attribute fork. The filesystem block size is specified in\n" " the superblock.\n\n" )); } /*ARGSUSED*/ static int ablock_f( int argc, char **argv) { bmap_ext_t bm; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int haveattr; int nex; char *p; bno = (xfs_dfiloff_t)strtoull(argv[1], &p, 0); if (*p != '\0') { dbprintf(_("bad block number %s\n"), argv[1]); return 0; } push_cur(); set_cur_inode(iocur_top->ino); haveattr = XFS_DFORK_Q((xfs_dinode_t *)iocur_top->data); pop_cur(); if (!haveattr) { dbprintf(_("no attribute data for file\n")); return 0; } nex = 1; bmap(bno, 1, XFS_ATTR_FORK, &nex, &bm); if (nex == 0) { dbprintf(_("file attr block is unmapped\n")); return 0; } dfsbno = bm.startblock + (bno - bm.startoff); ASSERT(typtab[TYP_ATTR].typnm == TYP_ATTR); set_cur(&typtab[TYP_ATTR], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno), blkbb, DB_RING_ADD, NULL); return 0; } void block_init(void) { add_command(&ablock_cmd); add_command(&daddr_cmd); add_command(&dblock_cmd); add_command(&fsblock_cmd); } static void daddr_help(void) { dbprintf(_( "\n Example:\n" "\n" " 'daddr 102' - sets position to the 102nd absolute disk block\n" " (512 byte block).\n" )); } static int daddr_f( int argc, char **argv) { __int64_t d; char *p; if (argc == 1) { dbprintf(_("current daddr is %lld\n"), iocur_top->off >> BBSHIFT); return 0; } d = (__int64_t)strtoull(argv[1], &p, 0); if (*p != '\0' || d >= mp->m_sb.sb_dblocks << (mp->m_sb.sb_blocklog - BBSHIFT)) { dbprintf(_("bad daddr %s\n"), argv[1]); return 0; } ASSERT(typtab[TYP_DATA].typnm == TYP_DATA); set_cur(&typtab[TYP_DATA], d, 1, DB_RING_ADD, NULL); return 0; } static void dblock_help(void) { dbprintf(_( "\n Example:\n" "\n" " 'dblock 23' - sets the file position to the 23rd filesystem block in\n" " the inode's data fork. The filesystem block size is specified in the\n" " superblock.\n\n" )); } static int dblock_f( int argc, char **argv) { bbmap_t bbmap; bmap_ext_t *bmp; xfs_dfiloff_t bno; xfs_dfsbno_t dfsbno; int nb; int nex; char *p; typnm_t type; bno = (xfs_dfiloff_t)strtoull(argv[1], &p, 0); if (*p != '\0') { dbprintf(_("bad block number %s\n"), argv[1]); return 0; } push_cur(); set_cur_inode(iocur_top->ino); type = inode_next_type(); pop_cur(); if (type == TYP_NONE) { dbprintf(_("no type for file data\n")); return 0; } nex = nb = type == TYP_DIR2 ? mp->m_dirblkfsbs : 1; bmp = malloc(nb * sizeof(*bmp)); bmap(bno, nb, XFS_DATA_FORK, &nex, bmp); if (nex == 0) { dbprintf(_("file data block is unmapped\n")); free(bmp); return 0; } dfsbno = bmp->startblock + (bno - bmp->startoff); ASSERT(typtab[type].typnm == type); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[type], (__int64_t)XFS_FSB_TO_DADDR(mp, dfsbno), nb * blkbb, DB_RING_ADD, nex > 1 ? &bbmap : NULL); free(bmp); return 0; } static void fsblock_help(void) { dbprintf(_( "\n Example:\n" "\n" " 'fsblock 1023' - sets the file position to the 1023rd filesystem block.\n" " The filesystem block size is specified in the superblock and set during\n" " mkfs time. Offset is absolute (not AG relative).\n\n" )); } static int fsblock_f( int argc, char **argv) { xfs_agblock_t agbno; xfs_agnumber_t agno; xfs_dfsbno_t d; char *p; if (argc == 1) { dbprintf(_("current fsblock is %lld\n"), XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT)); return 0; } d = strtoull(argv[1], &p, 0); if (*p != '\0') { dbprintf(_("bad fsblock %s\n"), argv[1]); return 0; } agno = XFS_FSB_TO_AGNO(mp, d); agbno = XFS_FSB_TO_AGBNO(mp, d); if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks) { dbprintf(_("bad fsblock %s\n"), argv[1]); return 0; } ASSERT(typtab[TYP_DATA].typnm == TYP_DATA); set_cur(&typtab[TYP_DATA], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_ADD, NULL); return 0; } void print_block( const field_t *fields, int argc, char **argv) { print_rawdata(iocur_top->data, iocur_top->len); } static void print_rawdata( void *data, int len) { int i; int j; int lastaddr; int offchars; unsigned char *p; lastaddr = (len - 1) & ~(32 - 1); if (lastaddr < 0x10) offchars = 1; else if (lastaddr < 0x100) offchars = 2; else if (lastaddr < 0x1000) offchars = 3; else offchars = 4; for (i = 0, p = data; i < len; i += 32) { dbprintf("%-0*.*x:", offchars, offchars, i); for (j = 0; j < 32 && i + j < len; j++, p++) { if ((j & 3) == 0) dbprintf(" "); dbprintf("%02x", *p); } dbprintf("\n"); } } xfsprogs-3.1.9ubuntu2/db/xfs_ncheck.sh0000775000000000000000000000121211256276416014661 0ustar #!/bin/sh -f # # Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. # OPTS=" " DBOPTS=" " USAGE="usage: xfs_ncheck [-sfV] [-l logdev] [-i ino]... special" while getopts "b:fi:l:svV" c do case $c in s) OPTS=$OPTS"-s ";; i) OPTS=$OPTS"-i "$OPTARG" ";; v) OPTS=$OPTS"-v ";; f) DBOPTS=$DBOPTS" -f";; l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; V) xfs_db -p xfs_ncheck -V status=$? exit $status ;; \?) echo $USAGE 1>&2 exit 2 ;; esac done set -- extra $@ shift $OPTIND case $# in 1) xfs_db$DBOPTS -r -p xfs_ncheck -c "blockget -ns" -c "ncheck$OPTS" $1 status=$? ;; *) echo $USAGE 1>&2 exit 2 ;; esac exit $status xfsprogs-3.1.9ubuntu2/db/flist.c0000664000000000000000000002142611146407622013476 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "flist.h" #include "debug.h" #include "output.h" #include "malloc.h" static void flist_expand_arrays(flist_t *fl); static void flist_expand_structs(flist_t *fl, void *obj); static flist_t *flist_replicate(flist_t *fl); static ftok_t *flist_split(char *s); static void ftok_free(ftok_t *ft); static void flist_expand_arrays( flist_t *fl) { const field_t *f; #ifdef DEBUG const ftattr_t *fa; #endif int high; int idx; int low; flist_t *new; flist_t *prev; flist_t *sib; f = fl->fld; #ifdef DEBUG fa = &ftattrtab[f->ftyp]; #endif ASSERT(fa->ftyp == f->ftyp); ASSERT(f->flags & FLD_ARRAY); low = fl->low; high = fl->high; fl->high = fl->low; sib = fl->sibling; for (idx = low + 1, prev = fl; idx <= high; idx++) { new = flist_make(f->name); new->fld = f; new->low = new->high = idx; new->flags |= FL_OKLOW | FL_OKHIGH; new->child = flist_replicate(fl->child); prev->sibling = new; prev = new; } prev->sibling = sib; } static void flist_expand_structs( flist_t *fl, void *obj) { const field_t *cf; const field_t *f; const ftattr_t *fa; flist_t *new; flist_t *prev; f = fl->fld; fa = &ftattrtab[f->ftyp]; ASSERT(fa->ftyp == f->ftyp); ASSERT(fa->subfld != NULL); ASSERT(fl->child == NULL); for (cf = fa->subfld, prev = NULL; cf->name != NULL; cf++) { if (fcount(cf, obj, fl->offset) == 0) continue; if (cf->flags & FLD_SKIPALL) continue; new = flist_make(cf->name); new->fld = cf; if (prev) prev->sibling = new; else fl->child = new; prev = new; } } void flist_free( flist_t *fl) { if (fl->child) flist_free(fl->child); if (fl->sibling) flist_free(fl->sibling); if (fl->name) xfree(fl->name); xfree(fl); } flist_t * flist_make( char *name) { flist_t *fl; fl = xmalloc(sizeof(*fl)); fl->name = xstrdup(name); fl->fld = NULL; fl->child = NULL; fl->sibling = NULL; fl->low = 0; fl->high = 0; fl->flags = 0; fl->offset = 0; return fl; } int flist_parse( const field_t *fields, flist_t *fl, void *obj, int startoff) { const field_t *f; const ftattr_t *fa; int high; int low; while (fl) { f = findfield(fl->name, fields, obj, startoff); if (f == NULL) { dbprintf(_("field %s not found\n"), fl->name); return 0; } fl->fld = f; fa = &ftattrtab[f->ftyp]; ASSERT(fa->ftyp == f->ftyp); if (f->flags & FLD_ARRAY) { low = (f->flags & FLD_ABASE1) != 0; high = fcount(f, obj, startoff) + low - 1; if (low > high) { dbprintf(_("no elements in %s\n"), fl->name); return 0; } if (fl->flags & FL_OKHIGH) { if (fl->low < low || fl->low > high || fl->high < low || fl->high > high) { dbprintf(_("indices %d-%d for field %s " "out of range %d-%d\n"), fl->low, fl->high, fl->name, low, high); return 0; } } else if (fl->flags & FL_OKLOW) { if (fl->low < low || fl->low > high) { dbprintf(_("index %d for field %s out of " "range %d-%d\n"), fl->low, fl->name, low, high); return 0; } fl->high = fl->low; fl->flags |= FL_OKHIGH; } else { fl->low = low; fl->high = high; fl->flags |= FL_OKLOW | FL_OKHIGH; } } else { if (fl->flags & FL_OKLOW) { dbprintf(_("field %s is not an array\n"), fl->name); return 0; } } fl->offset = startoff + bitoffset(f, obj, startoff, fl->low); if ((fl->child != NULL || fa->prfunc == NULL) && (f->flags & FLD_ARRAY) && fl->low != fl->high) flist_expand_arrays(fl); if (fa->prfunc == NULL && fl->child == NULL) flist_expand_structs(fl, obj); if (fl->child) { if (fa->subfld == NULL) { dbprintf(_("field %s has no subfields\n"), fl->name); return 0; } if (!flist_parse(fa->subfld, fl->child, obj, fl->offset)) return 0; } fl = fl->sibling; } return 1; } void flist_print( flist_t *fl) { if (!(debug_state & DEBUG_FLIST)) return; while (fl) { dbprintf(_("fl@%p:\n"), fl); dbprintf(_("\tname=%s, fld=%p, child=%p, sibling=%p\n"), fl->name, fl->fld, fl->child, fl->sibling); dbprintf(_("\tlow=%d, high=%d, flags=%d (%s%s), offset=%d\n"), fl->low, fl->high, fl->flags, fl->flags & FL_OKLOW ? _("oklow ") : "", fl->flags & FL_OKHIGH ? _("okhigh") : "", fl->offset); dbprintf(_("\tfld->name=%s, fld->ftyp=%d (%s)\n"), fl->fld->name, fl->fld->ftyp, ftattrtab[fl->fld->ftyp].name); dbprintf(_("\tfld->flags=%d (%s%s%s%s%s)\n"), fl->fld->flags, fl->fld->flags & FLD_ABASE1 ? "abase1 " : "", fl->fld->flags & FLD_SKIPALL ? "skipall " : "", fl->fld->flags & FLD_ARRAY ? "array " : "", fl->fld->flags & FLD_OFFSET ? "offset " : "", fl->fld->flags & FLD_COUNT ? "count " : ""); if (fl->child) flist_print(fl->child); fl = fl->sibling; } } static flist_t * flist_replicate( flist_t *f) { flist_t *new; if (f == NULL) return NULL; new = flist_make(f->name); new->fld = f->fld; new->child = flist_replicate(f->child); new->sibling = flist_replicate(f->sibling); new->low = f->low; new->high = f->high; new->flags = f->flags; new->offset = f->offset; return new; } flist_t * flist_scan( char *name) { flist_t *fl; flist_t *lfl; flist_t *nfl; int num; ftok_t *p; ftok_t *v; char *x; v = flist_split(name); if (!v) return NULL; p = v; fl = lfl = NULL; while (p->tokty != TT_END) { if (p->tokty != TT_NAME) goto bad; nfl = flist_make(p->tok); if (lfl) lfl->child = nfl; else fl = nfl; lfl = nfl; p++; if (p->tokty == TT_LB) { p++; if (p->tokty != TT_NUM) goto bad; num = (int)strtoul(p->tok, &x, 0); if (*x != '\0') goto bad; nfl->flags |= FL_OKLOW; nfl->low = num; p++; if (p->tokty == TT_DASH) { p++; if (p->tokty != TT_NUM) goto bad; num = (int)strtoul(p->tok, &x, 0); if (*x != '\0') goto bad; nfl->flags |= FL_OKHIGH; nfl->high = num; p++; } if (p->tokty != TT_RB) goto bad; p++; } if (p->tokty == TT_DOT) { p++; if (p->tokty == TT_END) goto bad; } } ftok_free(v); return fl; bad: dbprintf(_("bad syntax in field name %s\n"), name); ftok_free(v); if (fl) flist_free(fl); return NULL; } static ftok_t * flist_split( char *s) { char *a; int i; static char *idchars; static char *initidchar; int l; int tailskip = 0; static char *numchars; static char *xnumchars; /* extended for hex conversion */ int nv; static char punctchars[] = "[-]."; static tokty_t puncttypes[] = { TT_LB, TT_DASH, TT_RB, TT_DOT }; tokty_t t; ftok_t *v; if (idchars == NULL) { idchars = xmalloc(26 + 10 + 1 + 1); initidchar = xmalloc(26 + 1); numchars = xmalloc(10 + 1); xnumchars = xmalloc(12 + 1); for (i = 'a'; i <= 'z'; i++) { idchars[i - 'a'] = i; initidchar[i - 'a'] = i; } for (i = '0'; i <= '9'; i++) { idchars[26 + (i - '0')] = i; numchars[i - '0'] = i; xnumchars[i - '0'] = i; } idchars[26 + 10] = '_'; idchars[26 + 10 + 1] = '\0'; initidchar[26] = '\0'; numchars[10] = '\0'; xnumchars[10] = 'x'; xnumchars[11] = 'X'; xnumchars[12] = '\0'; } nv = 0; v = xmalloc(sizeof(*v)); v->tok = NULL; while (*s) { /* need to add string handling */ if (*s == '\"') { s++; /* skip first quote */ if ((a = strrchr(s, '\"')) == NULL) { dbprintf(_("missing closing quote %s\n"), s); ftok_free(v); return NULL; } tailskip = 1; /* skip remaing quote */ l = (int)(a - s); t = TT_STRING; } else if (strchr(initidchar, *s)) { l = (int)strspn(s, idchars); t = TT_NAME; } else if (strchr(numchars, *s)) { l = (int)strspn(s, xnumchars); t = TT_NUM; } else if ((a = strchr(punctchars, *s))) { l = 1; t = puncttypes[a - punctchars]; } else { dbprintf(_("bad character in field %s\n"), s); ftok_free(v); return NULL; } a = xmalloc(l + 1); strncpy(a, s, l); a[l] = '\0'; v = xrealloc(v, (nv + 2) * sizeof(*v)); v[nv].tok = a; v[nv].tokty = t; nv++; s += l + tailskip; tailskip = 0; } v[nv].tok = NULL; v[nv].tokty = TT_END; return v; } static void ftok_free( ftok_t *ft) { ftok_t *p; for (p = ft; p->tok; p++) xfree(p->tok); xfree(ft); } xfsprogs-3.1.9ubuntu2/db/help.c0000664000000000000000000000402111146407622013275 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "help.h" #include "output.h" static void help_all(void); static void help_onecmd(const char *cmd, const cmdinfo_t *ct); static int help_f(int argc, char **argv); static void help_oneline(const char *cmd, const cmdinfo_t *ct); static const cmdinfo_t help_cmd = { "help", "?", help_f, 0, 1, 0, N_("[command]"), N_("help for one or all commands"), NULL }; static void help_all(void) { const cmdinfo_t *ct; for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) help_oneline(ct->name, ct); dbprintf(_("\nUse 'help commandname' for extended help.\n")); } static int help_f( int argc, char **argv) { const cmdinfo_t *ct; if (argc == 1) { help_all(); return 0; } ct = find_command(argv[1]); if (ct == NULL) { dbprintf(_("command %s not found\n"), argv[1]); return 0; } help_onecmd(argv[1], ct); return 0; } void help_init(void) { add_command(&help_cmd); } static void help_onecmd( const char *cmd, const cmdinfo_t *ct) { help_oneline(cmd, ct); if (ct->help) ct->help(); } static void help_oneline( const char *cmd, const cmdinfo_t *ct) { if (cmd) dbprintf("%s ", cmd); else { dbprintf("%s ", ct->name); if (ct->altname) dbprintf(_("(or %s) "), ct->altname); } if (ct->args) dbprintf("%s ", ct->args); dbprintf("-- %s\n", ct->oneline); } xfsprogs-3.1.9ubuntu2/db/dir.c0000664000000000000000000001535611140033220013117 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bit.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "dir.h" #include "io.h" #include "init.h" static int dir_leaf_entries_count(void *obj, int startoff); static int dir_leaf_hdr_count(void *obj, int startoff); static int dir_leaf_name_count(void *obj, int startoff); static int dir_leaf_namelist_count(void *obj, int startoff); static int dir_leaf_namelist_offset(void *obj, int startoff, int idx); static int dir_node_btree_count(void *obj, int startoff); static int dir_node_hdr_count(void *obj, int startoff); const field_t dir_hfld[] = { { "", FLDT_DIR, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define LOFF(f) bitize(offsetof(xfs_dir_leafblock_t, f)) #define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f)) const field_t dir_flds[] = { { "lhdr", FLDT_DIR_LEAF_HDR, OI(LOFF(hdr)), dir_leaf_hdr_count, FLD_COUNT, TYP_NONE }, { "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir_node_hdr_count, FLD_COUNT, TYP_NONE }, { "entries", FLDT_DIR_LEAF_ENTRY, OI(LOFF(entries)), dir_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "btree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)), dir_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE }, { "namelist", FLDT_DIR_LEAF_NAME, dir_leaf_namelist_offset, dir_leaf_namelist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE }, { NULL } }; #define BOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f)) const field_t dir_blkinfo_flds[] = { { "forw", FLDT_DIRBLOCK, OI(BOFF(forw)), C1, 0, TYP_INODATA }, { "back", FLDT_DIRBLOCK, OI(BOFF(back)), C1, 0, TYP_INODATA }, { "magic", FLDT_UINT16X, OI(BOFF(magic)), C1, 0, TYP_NONE }, { "pad", FLDT_UINT16X, OI(BOFF(pad)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; #define LEOFF(f) bitize(offsetof(xfs_dir_leaf_entry_t, f)) const field_t dir_leaf_entry_flds[] = { { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE }, { "nameidx", FLDT_UINT16D, OI(LEOFF(nameidx)), C1, 0, TYP_NONE }, { "namelen", FLDT_UINT8D, OI(LEOFF(namelen)), C1, 0, TYP_NONE }, { "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; #define LHOFF(f) bitize(offsetof(xfs_dir_leaf_hdr_t, f)) const field_t dir_leaf_hdr_flds[] = { { "info", FLDT_DIR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE }, { "namebytes", FLDT_UINT16D, OI(LHOFF(namebytes)), C1, 0, TYP_NONE }, { "firstused", FLDT_UINT16D, OI(LHOFF(firstused)), C1, 0, TYP_NONE }, { "holes", FLDT_UINT8D, OI(LHOFF(holes)), C1, 0, TYP_NONE }, { "pad1", FLDT_UINT8X, OI(LHOFF(pad1)), C1, FLD_SKIPALL, TYP_NONE }, { "freemap", FLDT_DIR_LEAF_MAP, OI(LHOFF(freemap)), CI(XFS_DIR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE }, { NULL } }; #define LMOFF(f) bitize(offsetof(xfs_dir_leaf_map_t, f)) const field_t dir_leaf_map_flds[] = { { "base", FLDT_UINT16D, OI(LMOFF(base)), C1, 0, TYP_NONE }, { "size", FLDT_UINT16D, OI(LMOFF(size)), C1, 0, TYP_NONE }, { NULL } }; #define LNOFF(f) bitize(offsetof(xfs_dir_leaf_name_t, f)) const field_t dir_leaf_name_flds[] = { { "inumber", FLDT_DIR_INO, OI(LNOFF(inumber)), C1, 0, TYP_INODE }, { "name", FLDT_CHARNS, OI(LNOFF(name)), dir_leaf_name_count, FLD_COUNT, TYP_NONE }, { NULL } }; #define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f)) const field_t dir_node_entry_flds[] = { { "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE }, { "before", FLDT_DIRBLOCK, OI(EOFF(before)), C1, 0, TYP_INODATA }, { NULL } }; #define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f)) const field_t dir_node_hdr_flds[] = { { "info", FLDT_DIR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE }, { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE }, { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE }, { NULL } }; /*ARGSUSED*/ static int dir_leaf_entries_count( void *obj, int startoff) { xfs_dir_leafblock_t *block; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int dir_leaf_hdr_count( void *obj, int startoff) { xfs_dir_leafblock_t *block; ASSERT(startoff == 0); block = obj; return be16_to_cpu(block->hdr.info.magic) == XFS_DIR_LEAF_MAGIC; } static int dir_leaf_name_count( void *obj, int startoff) { xfs_dir_leafblock_t *block; xfs_dir_leaf_entry_t *e; int i; int off; ASSERT(bitoffs(startoff) == 0); off = byteize(startoff); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; for (i = 0; i < be16_to_cpu(block->hdr.count); i++) { e = &block->entries[i]; if (be16_to_cpu(e->nameidx) == off) return e->namelen; } return 0; } /*ARGSUSED*/ int dir_leaf_name_size( void *obj, int startoff, int idx) { xfs_dir_leafblock_t *block; xfs_dir_leaf_entry_t *e; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; e = &block->entries[idx]; return bitize((int)xfs_dir_leaf_entsize_byentry(e)); } /*ARGSUSED*/ static int dir_leaf_namelist_count( void *obj, int startoff) { xfs_dir_leafblock_t *block; ASSERT(startoff == 0); block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int dir_leaf_namelist_offset( void *obj, int startoff, int idx) { xfs_dir_leafblock_t *block; xfs_dir_leaf_entry_t *e; ASSERT(startoff == 0); block = obj; e = &block->entries[idx]; return bitize(be16_to_cpu(e->nameidx)); } /*ARGSUSED*/ static int dir_node_btree_count( void *obj, int startoff) { xfs_da_intnode_t *block; ASSERT(startoff == 0); /* this is a base structure */ block = obj; if (be16_to_cpu(block->hdr.info.magic) != XFS_DA_NODE_MAGIC) return 0; return be16_to_cpu(block->hdr.count); } /*ARGSUSED*/ static int dir_node_hdr_count( void *obj, int startoff) { xfs_da_intnode_t *block; ASSERT(startoff == 0); block = obj; return be16_to_cpu(block->hdr.info.magic) == XFS_DA_NODE_MAGIC; } /*ARGSUSED*/ int dir_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_blocksize); } xfsprogs-3.1.9ubuntu2/db/dirshort.c0000664000000000000000000000660311140033220014172 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "bit.h" #include "dirshort.h" static int dir_sf_entry_name_count(void *obj, int startoff); static int dir_shortform_list_count(void *obj, int startoff); static int dir_shortform_list_offset(void *obj, int startoff, int idx); #define OFF(f) bitize(offsetof(xfs_dir_shortform_t, f)) const field_t dir_shortform_flds[] = { { "hdr", FLDT_DIR_SF_HDR, OI(OFF(hdr)), C1, 0, TYP_NONE }, { "list", FLDT_DIR_SF_ENTRY, dir_shortform_list_offset, dir_shortform_list_count, FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { NULL } }; #define HOFF(f) bitize(offsetof(xfs_dir_sf_hdr_t, f)) const field_t dir_sf_hdr_flds[] = { { "parent", FLDT_DIR_INO, OI(HOFF(parent)), C1, 0, TYP_INODE }, { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE }, { NULL } }; #define EOFF(f) bitize(offsetof(xfs_dir_sf_entry_t, f)) const field_t dir_sf_entry_flds[] = { { "inumber", FLDT_DIR_INO, OI(EOFF(inumber)), C1, 0, TYP_INODE }, { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, { "name", FLDT_CHARNS, OI(EOFF(name)), dir_sf_entry_name_count, FLD_COUNT, TYP_NONE }, { NULL } }; static int dir_sf_entry_name_count( void *obj, int startoff) { xfs_dir_sf_entry_t *e; ASSERT(bitoffs(startoff) == 0); e = (xfs_dir_sf_entry_t *)((char *)obj + byteize(startoff)); return e->namelen; } int dir_sf_entry_size( void *obj, int startoff, int idx) { xfs_dir_sf_entry_t *e; int i; xfs_dir_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) e = xfs_dir_sf_nextentry(e); return bitize((int)xfs_dir_sf_entsize_byentry(e)); } static int dir_shortform_list_count( void *obj, int startoff) { xfs_dir_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); return sf->hdr.count; } static int dir_shortform_list_offset( void *obj, int startoff, int idx) { xfs_dir_sf_entry_t *e; int i; xfs_dir_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < idx; i++) e = xfs_dir_sf_nextentry(e); return bitize((int)((char *)e - (char *)sf)); } int dirshort_size( void *obj, int startoff, int idx) { xfs_dir_sf_entry_t *e; int i; xfs_dir_shortform_t *sf; ASSERT(bitoffs(startoff) == 0); ASSERT(idx == 0); sf = (xfs_dir_shortform_t *)((char *)obj + byteize(startoff)); e = &sf->list[0]; for (i = 0; i < sf->hdr.count; i++) e = xfs_dir_sf_nextentry(e); return bitize((int)((char *)e - (char *)sf)); } xfsprogs-3.1.9ubuntu2/db/hash.h0000664000000000000000000000136111140033220013260 0ustar /* * Copyright (c) 2000-2002 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void hash_init(void); xfsprogs-3.1.9ubuntu2/db/addr.c0000664000000000000000000000546111146407622013270 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "addr.h" #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "flist.h" #include "inode.h" #include "output.h" static int addr_f(int argc, char **argv); static void addr_help(void); static const cmdinfo_t addr_cmd = { "addr", "a", addr_f, 0, 1, 1, N_("[field-expression]"), N_("set current address"), addr_help }; static void addr_help(void) { dbprintf(_( "\n" " 'addr' uses the given field to set the filesystem address and type\n" "\n" " Examples:\n" "\n" " sb\n" " a rootino - set the type to inode and set position to the root inode\n" " a u.bmx[0].startblock (for inode with blockmap)\n" "\n" )); } static int addr_f( int argc, char **argv) { adfnc_t adf; const ftattr_t *fa; flist_t *fl; const field_t *fld; typnm_t next; flist_t *tfl; if (argc == 1) { print_iocur("current", iocur_top); return 0; } if (cur_typ == NULL) { dbprintf(_("no current type\n")); return 0; } fld = cur_typ->fields; if (fld != NULL && fld->name[0] == '\0') { fa = &ftattrtab[fld->ftyp]; ASSERT(fa->ftyp == fld->ftyp); fld = fa->subfld; } if (fld == NULL) { dbprintf(_("no fields for type %s\n"), cur_typ->name); return 0; } fl = flist_scan(argv[1]); if (fl == NULL) return 0; if (!flist_parse(fld, fl, iocur_top->data, 0)) { flist_free(fl); return 0; } flist_print(fl); for (tfl = fl; tfl->child != NULL; tfl = tfl->child) { if ((tfl->flags & FL_OKLOW) && tfl->low < tfl->high) { dbprintf(_("array not allowed for addr command\n")); flist_free(fl); return 0; } } fld = tfl->fld; next = fld->next; if (next == TYP_INODATA) next = inode_next_type(); if (next == TYP_NONE) { dbprintf(_("no next type for field %s\n"), fld->name); return 0; } fa = &ftattrtab[fld->ftyp]; ASSERT(fa->ftyp == fld->ftyp); adf = fa->adfunc; if (adf == NULL) { dbprintf(_("no addr function for field %s (type %s)\n"), fld->name, fa->name); return 0; } (*adf)(iocur_top->data, tfl->offset, next); flist_free(fl); return 0; } void addr_init(void) { add_command(&addr_cmd); } xfsprogs-3.1.9ubuntu2/db/dir.h0000664000000000000000000000227511140033220013120 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern const field_t dir_flds[]; extern const field_t dir_hfld[]; extern const field_t dir_blkinfo_flds[]; extern const field_t dir_leaf_entry_flds[]; extern const field_t dir_leaf_hdr_flds[]; extern const field_t dir_leaf_map_flds[]; extern const field_t dir_leaf_name_flds[]; extern const field_t dir_node_entry_flds[]; extern const field_t dir_node_hdr_flds[]; extern int dir_leaf_name_size(void *obj, int startoff, int idx); extern int dir_size(void *obj, int startoff, int idx); xfsprogs-3.1.9ubuntu2/db/output.c0000664000000000000000000000452211146407622013713 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "command.h" #include "output.h" #include "sig.h" #include "malloc.h" #include "init.h" static int log_f(int argc, char **argv); static const cmdinfo_t log_cmd = { "log", NULL, log_f, 0, 2, 0, N_("[stop|start ]"), N_("start or stop logging to a file"), NULL }; int dbprefix; static FILE *log_file; static char *log_file_name; int dbprintf(const char *fmt, ...) { va_list ap; int i; if (seenint()) return 0; va_start(ap, fmt); blockint(); i = 0; if (dbprefix) i += printf("%s: ", fsdevice); i += vprintf(fmt, ap); unblockint(); va_end(ap); if (log_file) { va_start(ap, fmt); vfprintf(log_file, fmt, ap); va_end(ap); } return i; } static int log_f( int argc, char **argv) { if (argc == 1) { if (log_file) dbprintf(_("logging to %s\n"), log_file_name); else dbprintf(_("no log file\n")); } else if (argc == 2 && strcmp(argv[1], "stop") == 0) { if (log_file) { xfree(log_file_name); fclose(log_file); log_file = NULL; } else dbprintf(_("no log file\n")); } else if (argc == 3 && strcmp(argv[1], "start") == 0) { if (log_file) dbprintf(_("already logging to %s\n"), log_file_name); else { log_file = fopen(argv[2], "a"); if (log_file == NULL) dbprintf(_("can't open %s for writing\n"), argv[2]); else log_file_name = xstrdup(argv[1]); } } else dbprintf(_("bad log command, ignored\n")); return 0; } void logprintf(const char *fmt, ...) { va_list ap; if (log_file) { va_start(ap, fmt); (void)vfprintf(log_file, fmt, ap); va_end(ap); } } void output_init(void) { add_command(&log_cmd); } xfsprogs-3.1.9ubuntu2/db/bmap.c0000664000000000000000000001664712062210562013276 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "fprint.h" #include "faddr.h" #include "field.h" #include "bmap.h" #include "io.h" #include "inode.h" #include "output.h" #include "init.h" static int bmap_f(int argc, char **argv); static int bmap_one_extent(xfs_bmbt_rec_t *ep, xfs_dfiloff_t *offp, xfs_dfiloff_t eoff, int *idxp, bmap_ext_t *bep); static xfs_fsblock_t select_child(xfs_dfiloff_t off, xfs_bmbt_key_t *kp, xfs_bmbt_ptr_t *pp, int nrecs); static const cmdinfo_t bmap_cmd = { "bmap", NULL, bmap_f, 0, 3, 0, N_("[-ad] [block [len]]"), N_("show block map for current file"), NULL }; void bmap( xfs_dfiloff_t offset, xfs_dfilblks_t len, int whichfork, int *nexp, bmap_ext_t *bep) { struct xfs_btree_block *block; xfs_fsblock_t bno; xfs_dfiloff_t curoffset; xfs_dinode_t *dip; xfs_dfiloff_t eoffset; xfs_bmbt_rec_t *ep; xfs_dinode_fmt_t fmt; int fsize; xfs_bmbt_key_t *kp; int n; int nex; xfs_fsblock_t nextbno; int nextents; xfs_bmbt_ptr_t *pp; xfs_bmdr_block_t *rblock; typnm_t typ; xfs_bmbt_rec_t *xp; push_cur(); set_cur_inode(iocur_top->ino); nex = *nexp; *nexp = 0; ASSERT(nex > 0); dip = iocur_top->data; n = 0; eoffset = offset + len - 1; curoffset = offset; fmt = (xfs_dinode_fmt_t)XFS_DFORK_FORMAT(dip, whichfork); typ = whichfork == XFS_DATA_FORK ? TYP_BMAPBTD : TYP_BMAPBTA; ASSERT(typtab[typ].typnm == typ); ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS || fmt == XFS_DINODE_FMT_BTREE); if (fmt == XFS_DINODE_FMT_EXTENTS) { nextents = XFS_DFORK_NEXTENTS(dip, whichfork); xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); for (ep = xp; ep < &xp[nextents] && n < nex; ep++) { if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep)) break; } } else if (fmt == XFS_DINODE_FMT_BTREE) { push_cur(); bno = NULLFSBLOCK; rblock = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); fsize = XFS_DFORK_SIZE(dip, mp, whichfork); pp = XFS_BMDR_PTR_ADDR(rblock, 1, xfs_bmdr_maxrecs(mp, fsize, 0)); kp = XFS_BMDR_KEY_ADDR(rblock, 1); bno = select_child(curoffset, kp, pp, be16_to_cpu(rblock->bb_numrecs)); for (;;) { set_cur(&typtab[typ], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); block = (struct xfs_btree_block *)iocur_top->data; if (be16_to_cpu(block->bb_level) == 0) break; pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_maxrecs(mp, mp->m_sb.sb_blocksize, 0)); kp = XFS_BMBT_KEY_ADDR(mp, block, 1); bno = select_child(curoffset, kp, pp, be16_to_cpu(block->bb_numrecs)); } for (;;) { nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); nextents = be16_to_cpu(block->bb_numrecs); xp = (xfs_bmbt_rec_t *) XFS_BMBT_REC_ADDR(mp, block, 1); for (ep = xp; ep < &xp[nextents] && n < nex; ep++) { if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep)) { nextbno = NULLFSBLOCK; break; } } bno = nextbno; if (bno == NULLFSBLOCK) break; set_cur(&typtab[typ], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); block = (struct xfs_btree_block *)iocur_top->data; } pop_cur(); } pop_cur(); *nexp = n; } static int bmap_f( int argc, char **argv) { int afork = 0; bmap_ext_t be; int c; xfs_dfiloff_t co, cosave; int dfork = 0; xfs_dinode_t *dip; xfs_dfiloff_t eo; xfs_dfilblks_t len; int nex; char *p; int whichfork; if (iocur_top->ino == NULLFSINO) { dbprintf(_("no current inode\n")); return 0; } optind = 0; if (argc) while ((c = getopt(argc, argv, "ad")) != EOF) { switch (c) { case 'a': afork = 1; break; case 'd': dfork = 1; break; default: dbprintf(_("bad option for bmap command\n")); return 0; } } if (afork + dfork == 0) { push_cur(); set_cur_inode(iocur_top->ino); dip = iocur_top->data; if (be32_to_cpu(dip->di_nextents)) dfork = 1; if (be16_to_cpu(dip->di_anextents)) afork = 1; pop_cur(); } if (optind < argc) { co = (xfs_dfiloff_t)strtoull(argv[optind], &p, 0); if (*p != '\0') { dbprintf(_("bad block number for bmap %s\n"), argv[optind]); return 0; } optind++; if (optind < argc) { len = (xfs_dfilblks_t)strtoull(argv[optind], &p, 0); if (*p != '\0') { dbprintf(_("bad len for bmap %s\n"), argv[optind]); return 0; } eo = co + len - 1; } else eo = co; } else { co = 0; eo = -1; } cosave = co; for (whichfork = XFS_DATA_FORK; whichfork <= XFS_ATTR_FORK; whichfork++) { if (whichfork == XFS_DATA_FORK && !dfork) continue; if (whichfork == XFS_ATTR_FORK && !afork) continue; for (;;) { nex = 1; bmap(co, eo - co + 1, whichfork, &nex, &be); if (nex == 0) break; dbprintf(_("%s offset %lld startblock %llu (%u/%u) count " "%llu flag %u\n"), whichfork == XFS_DATA_FORK ? _("data") : _("attr"), be.startoff, be.startblock, XFS_FSB_TO_AGNO(mp, be.startblock), XFS_FSB_TO_AGBNO(mp, be.startblock), be.blockcount, be.flag); co = be.startoff + be.blockcount; } co = cosave; } return 0; } void bmap_init(void) { add_command(&bmap_cmd); } static int bmap_one_extent( xfs_bmbt_rec_t *ep, xfs_dfiloff_t *offp, xfs_dfiloff_t eoff, int *idxp, bmap_ext_t *bep) { xfs_dfilblks_t c; xfs_dfiloff_t curoffset; int f; int idx; xfs_dfiloff_t o; xfs_dfsbno_t s; convert_extent(ep, &o, &s, &c, &f); curoffset = *offp; idx = *idxp; if (o + c <= curoffset) return 1; if (o > eoff) return 0; if (o < curoffset) { c -= curoffset - o; s += curoffset - o; o = curoffset; } if (o + c - 1 > eoff) c -= (o + c - 1) - eoff; bep[idx].startoff = o; bep[idx].startblock = s; bep[idx].blockcount = c; bep[idx].flag = f; *idxp = idx + 1; *offp = o + c; return 1; } void convert_extent( xfs_bmbt_rec_t *rp, xfs_dfiloff_t *op, xfs_dfsbno_t *sp, xfs_dfilblks_t *cp, int *fp) { xfs_bmbt_irec_t irec; libxfs_bmbt_disk_get_all(rp, &irec); *fp = irec.br_state == XFS_EXT_UNWRITTEN; *op = irec.br_startoff; *sp = irec.br_startblock; *cp = irec.br_blockcount; } void make_bbmap( bbmap_t *bbmap, int nex, bmap_ext_t *bmp) { int d; xfs_dfsbno_t dfsbno; int i; int j; int k; for (i = 0, d = 0; i < nex; i++) { dfsbno = bmp[i].startblock; for (j = 0; j < bmp[i].blockcount; j++, dfsbno++) { for (k = 0; k < blkbb; k++) bbmap->b[d++] = XFS_FSB_TO_DADDR(mp, dfsbno) + k; } } } static xfs_fsblock_t select_child( xfs_dfiloff_t off, xfs_bmbt_key_t *kp, xfs_bmbt_ptr_t *pp, int nrecs) { int i; for (i = 0; i < nrecs; i++) { if (be64_to_cpu(kp[i].br_startoff) == off) return be64_to_cpu(pp[i]); if (be64_to_cpu(kp[i].br_startoff) > off) { if (i == 0) return be64_to_cpu(pp[i]); else return be64_to_cpu(pp[i - 1]); } } return be64_to_cpu(pp[nrecs - 1]); } xfsprogs-3.1.9ubuntu2/db/echo.h0000664000000000000000000000136511140033220013257 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern void echo_init(void); xfsprogs-3.1.9ubuntu2/db/init.h0000664000000000000000000000160211140033220013276 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern char *fsdevice; extern int blkbb; extern int exitcode; extern int expert_mode; extern xfs_mount_t *mp; extern libxfs_init_t x; extern xfs_agnumber_t cur_agno; xfsprogs-3.1.9ubuntu2/db/check.c0000664000000000000000000033562211650373060013436 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "bmap.h" #include "check.h" #include "command.h" #include "io.h" #include "type.h" #include "fprint.h" #include "faddr.h" #include "field.h" #include "sb.h" #include "output.h" #include "init.h" #include "malloc.h" typedef enum { IS_USER_QUOTA, IS_PROJECT_QUOTA, IS_GROUP_QUOTA, } qtype_t; typedef enum { DBM_UNKNOWN, DBM_AGF, DBM_AGFL, DBM_AGI, DBM_ATTR, DBM_BTBMAPA, DBM_BTBMAPD, DBM_BTBNO, DBM_BTCNT, DBM_BTINO, DBM_DATA, DBM_DIR, DBM_FREE1, DBM_FREE2, DBM_FREELIST, DBM_INODE, DBM_LOG, DBM_MISSING, DBM_QUOTA, DBM_RTBITMAP, DBM_RTDATA, DBM_RTFREE, DBM_RTSUM, DBM_SB, DBM_SYMLINK, DBM_NDBM } dbm_t; typedef struct inodata { struct inodata *next; nlink_t link_set; nlink_t link_add; char isdir; char security; char ilist; xfs_ino_t ino; struct inodata *parent; char *name; } inodata_t; #define MIN_INODATA_HASH_SIZE 256 #define MAX_INODATA_HASH_SIZE 65536 #define INODATA_AVG_HASH_LENGTH 8 typedef struct qinfo { xfs_qcnt_t bc; xfs_qcnt_t ic; xfs_qcnt_t rc; } qinfo_t; #define QDATA_HASH_SIZE 256 typedef struct qdata { struct qdata *next; xfs_dqid_t id; qinfo_t count; qinfo_t dq; } qdata_t; typedef struct blkent { xfs_fileoff_t startoff; int nblks; xfs_fsblock_t blks[1]; } blkent_t; #define BLKENT_SIZE(n) \ (offsetof(blkent_t, blks) + (sizeof(xfs_fsblock_t) * (n))) typedef struct blkmap { int naents; int nents; blkent_t *ents[1]; } blkmap_t; #define BLKMAP_SIZE(n) \ (offsetof(blkmap_t, ents) + (sizeof(blkent_t *) * (n))) typedef struct freetab { int naents; int nents; xfs_dir2_data_off_t ents[1]; } freetab_t; #define FREETAB_SIZE(n) \ (offsetof(freetab_t, ents) + (sizeof(xfs_dir2_data_off_t) * (n))) typedef struct dirhash { struct dirhash *next; __u32 hashval; __u32 address; int seen; } dirhash_t; #define DIR_HASH_SIZE 1024 #define DIR_HASH_FUNC(h,a) (((h) ^ (a)) % DIR_HASH_SIZE) static xfs_extlen_t agffreeblks; static xfs_extlen_t agflongest; static __uint64_t agf_aggr_freeblks; /* aggregate count over all */ static __uint32_t agfbtreeblks; static int lazycount; static xfs_agino_t agicount; static xfs_agino_t agifreecount; static xfs_fsblock_t *blist; static int blist_size; static char **dbmap; /* really dbm_t:8 */ static dirhash_t **dirhash; static int error; static __uint64_t fdblocks; static __uint64_t frextents; static __uint64_t icount; static __uint64_t ifree; static inodata_t ***inodata; static int inodata_hash_size; static inodata_t ***inomap; static int nflag; static int pflag; static int tflag; static qdata_t **qpdata; static int qpdo; static qdata_t **qudata; static int qudo; static qdata_t **qgdata; static int qgdo; static unsigned sbversion; static int sbver_err; static int serious_error; static int sflag; static xfs_suminfo_t *sumcompute; static xfs_suminfo_t *sumfile; static const char *typename[] = { "unknown", "agf", "agfl", "agi", "attr", "btbmapa", "btbmapd", "btbno", "btcnt", "btino", "data", "dir", "free1", "free2", "freelist", "inode", "log", "missing", "quota", "rtbitmap", "rtdata", "rtfree", "rtsum", "sb", "symlink", NULL }; static int verbose; #define CHECK_BLIST(b) (blist_size && check_blist(b)) #define CHECK_BLISTA(a,b) \ (blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b))) typedef void (*scan_lbtree_f_t)(struct xfs_btree_block *block, int level, dbm_t type, xfs_fsblock_t bno, inodata_t *id, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int isroot, typnm_t btype); typedef void (*scan_sbtree_f_t)(struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot); static void add_blist(xfs_fsblock_t bno); static void add_ilist(xfs_ino_t ino); static void addlink_inode(inodata_t *id); static void addname_inode(inodata_t *id, char *name, int namelen); static void addparent_inode(inodata_t *id, xfs_ino_t parent); static void blkent_append(blkent_t **entp, xfs_fsblock_t b, xfs_extlen_t c); static blkent_t *blkent_new(xfs_fileoff_t o, xfs_fsblock_t b, xfs_extlen_t c); static void blkent_prepend(blkent_t **entp, xfs_fsblock_t b, xfs_extlen_t c); static blkmap_t *blkmap_alloc(xfs_extnum_t); static void blkmap_free(blkmap_t *blkmap); static xfs_fsblock_t blkmap_get(blkmap_t *blkmap, xfs_fileoff_t o); static int blkmap_getn(blkmap_t *blkmap, xfs_fileoff_t o, int nb, bmap_ext_t **bmpp); static void blkmap_grow(blkmap_t **blkmapp, blkent_t **entp, blkent_t *newent); static xfs_fileoff_t blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o, int *t); static void blkmap_set_blk(blkmap_t **blkmapp, xfs_fileoff_t o, xfs_fsblock_t b); static void blkmap_set_ext(blkmap_t **blkmapp, xfs_fileoff_t o, xfs_fsblock_t b, xfs_extlen_t c); static void blkmap_shrink(blkmap_t *blkmap, blkent_t **entp); static int blockfree_f(int argc, char **argv); static int blockget_f(int argc, char **argv); static int blocktrash_f(int argc, char **argv); static int blockuse_f(int argc, char **argv); static int check_blist(xfs_fsblock_t bno); static void check_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type); static int check_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, xfs_ino_t c_ino); static void check_linkcounts(xfs_agnumber_t agno); static int check_range(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len); static void check_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type); static int check_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len, xfs_ino_t c_ino); static void check_rootdir(void); static int check_rrange(xfs_drfsbno_t bno, xfs_extlen_t len); static void check_set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type1, dbm_t type2, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno); static void check_set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type1, dbm_t type2); static void check_summary(void); static void checknot_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, int typemask); static void checknot_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len, int typemask); static void dir_hash_add(xfs_dahash_t hash, xfs_dir2_dataptr_t addr); static void dir_hash_check(inodata_t *id, int v); static void dir_hash_done(void); static void dir_hash_init(void); static int dir_hash_see(xfs_dahash_t hash, xfs_dir2_dataptr_t addr); static inodata_t *find_inode(xfs_ino_t ino, int add); static void free_inodata(xfs_agnumber_t agno); static int init(int argc, char **argv); static char *inode_name(xfs_ino_t ino, inodata_t **ipp); static int ncheck_f(int argc, char **argv); static char *prepend_path(char *oldpath, char *parent); static xfs_ino_t process_block_dir_v2(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id); static void process_bmbt_reclist(xfs_bmbt_rec_t *rp, int numrecs, dbm_t type, inodata_t *id, xfs_drfsbno_t *tot, blkmap_t **blkmapp); static void process_btinode(inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork); static xfs_ino_t process_data_dir_v2(int *dot, int *dotdot, inodata_t *id, int v, xfs_dablk_t dabno, freetab_t **freetabp); static xfs_dir2_data_free_t *process_data_dir_v2_freefind(xfs_dir2_data_t *data, xfs_dir2_data_unused_t *dup); static void process_dir(xfs_dinode_t *dip, blkmap_t *blkmap, inodata_t *id); static int process_dir_v1(xfs_dinode_t *dip, blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_ino_t *parent); static int process_dir_v2(xfs_dinode_t *dip, blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_ino_t *parent); static void process_exinode(inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork); static void process_inode(xfs_agf_t *agf, xfs_agino_t agino, xfs_dinode_t *dip, int isfree); static void process_lclinode(inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork); static xfs_ino_t process_leaf_dir_v1(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id); static xfs_ino_t process_leaf_dir_v1_int(int *dot, int *dotdot, inodata_t *id); static xfs_ino_t process_leaf_node_dir_v2(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_fsize_t dirsize); static void process_leaf_node_dir_v2_free(inodata_t *id, int v, xfs_dablk_t dbno, freetab_t *freetab); static void process_leaf_node_dir_v2_int(inodata_t *id, int v, xfs_dablk_t dbno, freetab_t *freetab); static xfs_ino_t process_node_dir_v1(blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id); static void process_quota(qtype_t qtype, inodata_t *id, blkmap_t *blkmap); static void process_rtbitmap(blkmap_t *blkmap); static void process_rtsummary(blkmap_t *blkmap); static xfs_ino_t process_sf_dir_v2(xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id); static xfs_ino_t process_shortform_dir_v1(xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id); static void quota_add(xfs_dqid_t *p, xfs_dqid_t *g, xfs_dqid_t *u, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc); static void quota_add1(qdata_t **qt, xfs_dqid_t id, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc); static void quota_check(char *s, qdata_t **qt); static void quota_init(void); static void scan_ag(xfs_agnumber_t agno); static void scan_freelist(xfs_agf_t *agf); static void scan_lbtree(xfs_fsblock_t root, int nlevels, scan_lbtree_f_t func, dbm_t type, inodata_t *id, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int isroot, typnm_t btype); static void scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root, int nlevels, int isroot, scan_sbtree_f_t func, typnm_t btype); static void scanfunc_bmap(struct xfs_btree_block *block, int level, dbm_t type, xfs_fsblock_t bno, inodata_t *id, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int isroot, typnm_t btype); static void scanfunc_bno(struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot); static void scanfunc_cnt(struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot); static void scanfunc_ino(struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot); static void set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno); static void set_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, inodata_t *id); static void set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type); static void set_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len, inodata_t *id); static void setlink_inode(inodata_t *id, nlink_t nlink, int isdir, int security); static const cmdinfo_t blockfree_cmd = { "blockfree", NULL, blockfree_f, 0, 0, 0, NULL, N_("free block usage information"), NULL }; static const cmdinfo_t blockget_cmd = { "blockget", "check", blockget_f, 0, -1, 0, N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."), N_("get block usage and check consistency"), NULL }; static const cmdinfo_t blocktrash_cmd = { "blocktrash", NULL, blocktrash_f, 0, -1, 0, N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."), N_("trash randomly selected block(s)"), NULL }; static const cmdinfo_t blockuse_cmd = { "blockuse", NULL, blockuse_f, 0, 3, 0, N_("[-n] [-c blockcount]"), N_("print usage for current block(s)"), NULL }; static const cmdinfo_t ncheck_cmd = { "ncheck", NULL, ncheck_f, 0, -1, 0, N_("[-s] [-i ino] ..."), N_("print inode-name pairs"), NULL }; static void add_blist( xfs_fsblock_t bno) { blist_size++; blist = xrealloc(blist, blist_size * sizeof(bno)); blist[blist_size - 1] = bno; } static void add_ilist( xfs_ino_t ino) { inodata_t *id; id = find_inode(ino, 1); if (id == NULL) { dbprintf(_("-i %lld bad inode number\n"), ino); return; } id->ilist = 1; } static void addlink_inode( inodata_t *id) { id->link_add++; if (verbose || id->ilist) dbprintf(_("inode %lld add link, now %u\n"), id->ino, id->link_add); } static void addname_inode( inodata_t *id, char *name, int namelen) { if (!nflag || id->name) return; id->name = xmalloc(namelen + 1); memcpy(id->name, name, namelen); id->name[namelen] = '\0'; } static void addparent_inode( inodata_t *id, xfs_ino_t parent) { inodata_t *pid; pid = find_inode(parent, 1); id->parent = pid; if (verbose || id->ilist || (pid && pid->ilist)) dbprintf(_("inode %lld parent %lld\n"), id->ino, parent); } static void blkent_append( blkent_t **entp, xfs_fsblock_t b, xfs_extlen_t c) { blkent_t *ent; int i; ent = *entp; *entp = ent = xrealloc(ent, BLKENT_SIZE(c + ent->nblks)); for (i = 0; i < c; i++) ent->blks[ent->nblks + i] = b + i; ent->nblks += c; } static blkent_t * blkent_new( xfs_fileoff_t o, xfs_fsblock_t b, xfs_extlen_t c) { blkent_t *ent; int i; ent = xmalloc(BLKENT_SIZE(c)); ent->nblks = c; ent->startoff = o; for (i = 0; i < c; i++) ent->blks[i] = b + i; return ent; } static void blkent_prepend( blkent_t **entp, xfs_fsblock_t b, xfs_extlen_t c) { int i; blkent_t *newent; blkent_t *oldent; oldent = *entp; newent = xmalloc(BLKENT_SIZE(oldent->nblks + c)); newent->nblks = oldent->nblks + c; newent->startoff = oldent->startoff - c; for (i = 0; i < c; i++) newent->blks[i] = b + c; for (; i < oldent->nblks + c; i++) newent->blks[i] = oldent->blks[i - c]; xfree(oldent); *entp = newent; } static blkmap_t * blkmap_alloc( xfs_extnum_t nex) { blkmap_t *blkmap; if (nex < 1) nex = 1; blkmap = xmalloc(BLKMAP_SIZE(nex)); blkmap->naents = nex; blkmap->nents = 0; return blkmap; } static void blkmap_free( blkmap_t *blkmap) { blkent_t **entp; xfs_extnum_t i; for (i = 0, entp = blkmap->ents; i < blkmap->nents; i++, entp++) xfree(*entp); xfree(blkmap); } static xfs_fsblock_t blkmap_get( blkmap_t *blkmap, xfs_fileoff_t o) { blkent_t *ent; blkent_t **entp; int i; for (i = 0, entp = blkmap->ents; i < blkmap->nents; i++, entp++) { ent = *entp; if (o >= ent->startoff && o < ent->startoff + ent->nblks) return ent->blks[o - ent->startoff]; } return NULLFSBLOCK; } static int blkmap_getn( blkmap_t *blkmap, xfs_fileoff_t o, int nb, bmap_ext_t **bmpp) { bmap_ext_t *bmp; blkent_t *ent; xfs_fileoff_t ento; blkent_t **entp; int i; int nex; for (i = nex = 0, bmp = NULL, entp = blkmap->ents; i < blkmap->nents; i++, entp++) { ent = *entp; if (ent->startoff >= o + nb) break; if (ent->startoff + ent->nblks <= o) continue; for (ento = ent->startoff; ento < ent->startoff + ent->nblks && ento < o + nb; ento++) { if (ento < o) continue; if (bmp && bmp[nex - 1].startoff + bmp[nex - 1].blockcount == ento && bmp[nex - 1].startblock + bmp[nex - 1].blockcount == ent->blks[ento - ent->startoff]) bmp[nex - 1].blockcount++; else { bmp = realloc(bmp, ++nex * sizeof(*bmp)); bmp[nex - 1].startoff = ento; bmp[nex - 1].startblock = ent->blks[ento - ent->startoff]; bmp[nex - 1].blockcount = 1; bmp[nex - 1].flag = 0; } } } *bmpp = bmp; return nex; } static void blkmap_grow( blkmap_t **blkmapp, blkent_t **entp, blkent_t *newent) { blkmap_t *blkmap; int i; int idx; blkmap = *blkmapp; idx = (int)(entp - blkmap->ents); if (blkmap->naents == blkmap->nents) { blkmap = xrealloc(blkmap, BLKMAP_SIZE(blkmap->nents + 1)); *blkmapp = blkmap; blkmap->naents++; } for (i = blkmap->nents; i > idx; i--) blkmap->ents[i] = blkmap->ents[i - 1]; blkmap->ents[idx] = newent; blkmap->nents++; } static xfs_fileoff_t blkmap_last_off( blkmap_t *blkmap) { blkent_t *ent; if (!blkmap->nents) return NULLFILEOFF; ent = blkmap->ents[blkmap->nents - 1]; return ent->startoff + ent->nblks; } static xfs_fileoff_t blkmap_next_off( blkmap_t *blkmap, xfs_fileoff_t o, int *t) { blkent_t *ent; blkent_t **entp; if (!blkmap->nents) return NULLFILEOFF; if (o == NULLFILEOFF) { *t = 0; ent = blkmap->ents[0]; return ent->startoff; } entp = &blkmap->ents[*t]; ent = *entp; if (o < ent->startoff + ent->nblks - 1) return o + 1; entp++; if (entp >= &blkmap->ents[blkmap->nents]) return NULLFILEOFF; (*t)++; ent = *entp; return ent->startoff; } static void blkmap_set_blk( blkmap_t **blkmapp, xfs_fileoff_t o, xfs_fsblock_t b) { blkmap_t *blkmap; blkent_t *ent; blkent_t **entp; blkent_t *nextent; blkmap = *blkmapp; for (entp = blkmap->ents; entp < &blkmap->ents[blkmap->nents]; entp++) { ent = *entp; if (o < ent->startoff - 1) { ent = blkent_new(o, b, 1); blkmap_grow(blkmapp, entp, ent); return; } if (o == ent->startoff - 1) { blkent_prepend(entp, b, 1); return; } if (o >= ent->startoff && o < ent->startoff + ent->nblks) { ent->blks[o - ent->startoff] = b; return; } if (o > ent->startoff + ent->nblks) continue; blkent_append(entp, b, 1); if (entp == &blkmap->ents[blkmap->nents - 1]) return; ent = *entp; nextent = entp[1]; if (ent->startoff + ent->nblks < nextent->startoff) return; blkent_append(entp, nextent->blks[0], nextent->nblks); blkmap_shrink(blkmap, &entp[1]); return; } ent = blkent_new(o, b, 1); blkmap_grow(blkmapp, entp, ent); } static void blkmap_set_ext( blkmap_t **blkmapp, xfs_fileoff_t o, xfs_fsblock_t b, xfs_extlen_t c) { blkmap_t *blkmap; blkent_t *ent; blkent_t **entp; xfs_extnum_t i; blkmap = *blkmapp; if (!blkmap->nents) { blkmap->ents[0] = blkent_new(o, b, c); blkmap->nents = 1; return; } entp = &blkmap->ents[blkmap->nents - 1]; ent = *entp; if (ent->startoff + ent->nblks == o) { blkent_append(entp, b, c); return; } if (ent->startoff + ent->nblks < o) { ent = blkent_new(o, b, c); blkmap_grow(blkmapp, &blkmap->ents[blkmap->nents], ent); return; } for (i = 0; i < c; i++) blkmap_set_blk(blkmapp, o + i, b + i); } static void blkmap_shrink( blkmap_t *blkmap, blkent_t **entp) { int i; int idx; xfree(*entp); idx = (int)(entp - blkmap->ents); for (i = idx + 1; i < blkmap->nents; i++) blkmap->ents[i] = blkmap->ents[i - 1]; blkmap->nents--; } /* ARGSUSED */ static int blockfree_f( int argc, char **argv) { xfs_agnumber_t c; int rt; if (!dbmap) { dbprintf(_("block usage information not allocated\n")); return 0; } rt = mp->m_sb.sb_rextents != 0; for (c = 0; c < mp->m_sb.sb_agcount; c++) { xfree(dbmap[c]); xfree(inomap[c]); free_inodata(c); } if (rt) { xfree(dbmap[c]); xfree(inomap[c]); xfree(sumcompute); xfree(sumfile); sumcompute = sumfile = NULL; } xfree(dbmap); xfree(inomap); xfree(inodata); dbmap = NULL; inomap = NULL; inodata = NULL; return 0; } /* * Check consistency of xfs filesystem contents. */ static int blockget_f( int argc, char **argv) { xfs_agnumber_t agno; int oldprefix; int sbyell; if (dbmap) { dbprintf(_("already have block usage information\n")); return 0; } if (!init(argc, argv)) { if (serious_error) exitcode = 3; else exitcode = 1; return 0; } oldprefix = dbprefix; dbprefix |= pflag; for (agno = 0, sbyell = 0; agno < mp->m_sb.sb_agcount; agno++) { scan_ag(agno); if (sbver_err > 4 && !sbyell && sbver_err >= agno) { sbyell = 1; dbprintf(_("WARNING: this may be a newer XFS " "filesystem.\n")); } } if (blist_size) { xfree(blist); blist = NULL; blist_size = 0; } if (serious_error) { exitcode = 2; dbprefix = oldprefix; return 0; } check_rootdir(); /* * Check that there are no blocks either * a) unaccounted for or * b) bno-free but not cnt-free */ if (!tflag) { /* are we in test mode, faking out freespace? */ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) checknot_dbmap(agno, 0, mp->m_sb.sb_agblocks, (1 << DBM_UNKNOWN) | (1 << DBM_FREE1)); } for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) check_linkcounts(agno); if (mp->m_sb.sb_rblocks) { checknot_rdbmap(0, (xfs_extlen_t)(mp->m_sb.sb_rextents * mp->m_sb.sb_rextsize), 1 << DBM_UNKNOWN); check_summary(); } if (mp->m_sb.sb_icount != icount) { if (!sflag) dbprintf(_("sb_icount %lld, counted %lld\n"), mp->m_sb.sb_icount, icount); error++; } if (mp->m_sb.sb_ifree != ifree) { if (!sflag) dbprintf(_("sb_ifree %lld, counted %lld\n"), mp->m_sb.sb_ifree, ifree); error++; } if (mp->m_sb.sb_fdblocks != fdblocks) { if (!sflag) dbprintf(_("sb_fdblocks %lld, counted %lld\n"), mp->m_sb.sb_fdblocks, fdblocks); error++; } if (lazycount && mp->m_sb.sb_fdblocks != agf_aggr_freeblks) { if (!sflag) dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"), mp->m_sb.sb_fdblocks, agf_aggr_freeblks); error++; } if (mp->m_sb.sb_frextents != frextents) { if (!sflag) dbprintf(_("sb_frextents %lld, counted %lld\n"), mp->m_sb.sb_frextents, frextents); error++; } if (mp->m_sb.sb_bad_features2 != 0 && mp->m_sb.sb_bad_features2 != mp->m_sb.sb_features2) { if (!sflag) dbprintf(_("sb_features2 (0x%x) not same as " "sb_bad_features2 (0x%x)\n"), mp->m_sb.sb_features2, mp->m_sb.sb_bad_features2); error++; } if ((sbversion & XFS_SB_VERSION_ATTRBIT) && !xfs_sb_version_hasattr(&mp->m_sb)) { if (!sflag) dbprintf(_("sb versionnum missing attr bit %x\n"), XFS_SB_VERSION_ATTRBIT); error++; } if ((sbversion & XFS_SB_VERSION_NLINKBIT) && !xfs_sb_version_hasnlink(&mp->m_sb)) { if (!sflag) dbprintf(_("sb versionnum missing nlink bit %x\n"), XFS_SB_VERSION_NLINKBIT); error++; } if ((sbversion & XFS_SB_VERSION_QUOTABIT) && !xfs_sb_version_hasquota(&mp->m_sb)) { if (!sflag) dbprintf(_("sb versionnum missing quota bit %x\n"), XFS_SB_VERSION_QUOTABIT); error++; } if (!(sbversion & XFS_SB_VERSION_ALIGNBIT) && xfs_sb_version_hasalign(&mp->m_sb)) { if (!sflag) dbprintf(_("sb versionnum extra align bit %x\n"), XFS_SB_VERSION_ALIGNBIT); error++; } if (qudo) quota_check("user", qudata); if (qpdo) quota_check("project", qpdata); if (qgdo) quota_check("group", qgdata); if (sbver_err > mp->m_sb.sb_agcount / 2) dbprintf(_("WARNING: this may be a newer XFS filesystem.\n")); if (error) exitcode = 3; dbprefix = oldprefix; return 0; } typedef struct ltab { int min; int max; } ltab_t; static void blocktrash_b( xfs_agnumber_t agno, xfs_agblock_t agbno, dbm_t type, ltab_t *ltabp, int mode) { int bit; int bitno; char *buf; int byte; int len; int mask; int newbit; int offset; static char *modestr[] = { N_("zeroed"), N_("set"), N_("flipped"), N_("randomized") }; len = (int)((random() % (ltabp->max - ltabp->min + 1)) + ltabp->min); offset = (int)(random() % (int)(mp->m_sb.sb_blocksize * NBBY)); newbit = 0; push_cur(); set_cur(&typtab[DBM_UNKNOWN], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); if ((buf = iocur_top->data) == NULL) { dbprintf(_("can't read block %u/%u for trashing\n"), agno, agbno); pop_cur(); return; } for (bitno = 0; bitno < len; bitno++) { bit = (offset + bitno) % (mp->m_sb.sb_blocksize * NBBY); byte = bit / NBBY; bit %= NBBY; mask = 1 << bit; switch (mode) { case 0: newbit = 0; break; case 1: newbit = 1; break; case 2: newbit = (buf[byte] & mask) == 0; break; case 3: newbit = (int)random() & 1; break; } if (newbit) buf[byte] |= mask; else buf[byte] &= ~mask; } write_cur(); pop_cur(); printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"), agno, agbno, typename[type], len, len == 1 ? "" : "s", offset / NBBY, offset % NBBY, modestr[mode]); } int blocktrash_f( int argc, char **argv) { xfs_agblock_t agbno; xfs_agnumber_t agno; xfs_drfsbno_t bi; xfs_drfsbno_t blocks; int c; int count; int done; int goodmask; int i; ltab_t *lentab; int lentablen; int max; int min; int mode; struct timeval now; char *p; xfs_drfsbno_t randb; uint seed; int sopt; int tmask; if (!dbmap) { dbprintf(_("must run blockget first\n")); return 0; } optind = 0; count = 1; min = 1; max = 128 * NBBY; mode = 2; gettimeofday(&now, NULL); seed = (unsigned int)(now.tv_sec ^ now.tv_usec); sopt = 0; tmask = 0; goodmask = (1 << DBM_AGF) | (1 << DBM_AGFL) | (1 << DBM_AGI) | (1 << DBM_ATTR) | (1 << DBM_BTBMAPA) | (1 << DBM_BTBMAPD) | (1 << DBM_BTBNO) | (1 << DBM_BTCNT) | (1 << DBM_BTINO) | (1 << DBM_DIR) | (1 << DBM_INODE) | (1 << DBM_QUOTA) | (1 << DBM_RTBITMAP) | (1 << DBM_RTSUM) | (1 << DBM_SB); while ((c = getopt(argc, argv, "0123n:s:t:x:y:")) != EOF) { switch (c) { case '0': mode = 0; break; case '1': mode = 1; break; case '2': mode = 2; break; case '3': mode = 3; break; case 'n': count = (int)strtol(optarg, &p, 0); if (*p != '\0' || count <= 0) { dbprintf(_("bad blocktrash count %s\n"), optarg); return 0; } break; case 's': seed = (uint)strtoul(optarg, &p, 0); sopt = 1; break; case 't': for (i = 0; typename[i]; i++) { if (strcmp(typename[i], optarg) == 0) break; } if (!typename[i] || (((1 << i) & goodmask) == 0)) { dbprintf(_("bad blocktrash type %s\n"), optarg); return 0; } tmask |= 1 << i; break; case 'x': min = (int)strtol(optarg, &p, 0); if (*p != '\0' || min <= 0 || min > mp->m_sb.sb_blocksize * NBBY) { dbprintf(_("bad blocktrash min %s\n"), optarg); return 0; } break; case 'y': max = (int)strtol(optarg, &p, 0); if (*p != '\0' || max <= 0 || max > mp->m_sb.sb_blocksize * NBBY) { dbprintf(_("bad blocktrash max %s\n"), optarg); return 0; } break; default: dbprintf(_("bad option for blocktrash command\n")); return 0; } } if (min > max) { dbprintf(_("bad min/max for blocktrash command\n")); return 0; } if (tmask == 0) tmask = goodmask; lentab = xmalloc(sizeof(ltab_t)); lentab->min = lentab->max = min; lentablen = 1; for (i = min + 1; i <= max; i++) { if ((i & (i - 1)) == 0) { lentab = xrealloc(lentab, sizeof(ltab_t) * (lentablen + 1)); lentab[lentablen].min = lentab[lentablen].max = i; lentablen++; } else lentab[lentablen - 1].max = i; } for (blocks = 0, agno = 0; agno < mp->m_sb.sb_agcount; agno++) { for (agbno = 0, p = dbmap[agno]; agbno < mp->m_sb.sb_agblocks; agbno++, p++) { if ((1 << *p) & tmask) blocks++; } } if (blocks == 0) { dbprintf(_("blocktrash: no matching blocks\n")); return 0; } if (!sopt) dbprintf(_("blocktrash: seed %u\n"), seed); srandom(seed); for (i = 0; i < count; i++) { randb = (xfs_drfsbno_t)((((__int64_t)random() << 32) | random()) % blocks); for (bi = 0, agno = 0, done = 0; !done && agno < mp->m_sb.sb_agcount; agno++) { for (agbno = 0, p = dbmap[agno]; agbno < mp->m_sb.sb_agblocks; agbno++, p++) { if (!((1 << *p) & tmask)) continue; if (bi++ < randb) continue; blocktrash_b(agno, agbno, (dbm_t)*p, &lentab[random() % lentablen], mode); done = 1; break; } } } xfree(lentab); return 0; } int blockuse_f( int argc, char **argv) { xfs_agblock_t agbno; xfs_agnumber_t agno; int c; int count; xfs_agblock_t end; xfs_fsblock_t fsb; inodata_t *i; char *p; int shownames; if (!dbmap) { dbprintf(_("must run blockget first\n")); return 0; } optind = 0; count = 1; shownames = 0; fsb = XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT); agno = XFS_FSB_TO_AGNO(mp, fsb); end = agbno = XFS_FSB_TO_AGBNO(mp, fsb); while ((c = getopt(argc, argv, "c:n")) != EOF) { switch (c) { case 'c': count = (int)strtol(optarg, &p, 0); end = agbno + count - 1; if (*p != '\0' || count <= 0 || end >= mp->m_sb.sb_agblocks) { dbprintf(_("bad blockuse count %s\n"), optarg); return 0; } break; case 'n': if (!nflag) { dbprintf(_("must run blockget -n first\n")); return 0; } shownames = 1; break; default: dbprintf(_("bad option for blockuse command\n")); return 0; } } while (agbno <= end) { p = &dbmap[agno][agbno]; i = inomap[agno][agbno]; dbprintf(_("block %llu (%u/%u) type %s"), (xfs_dfsbno_t)XFS_AGB_TO_FSB(mp, agno, agbno), agno, agbno, typename[(dbm_t)*p]); if (i) { dbprintf(_(" inode %lld"), i->ino); if (shownames && (p = inode_name(i->ino, NULL))) { dbprintf(" %s", p); xfree(p); } } dbprintf("\n"); agbno++; } return 0; } static int check_blist( xfs_fsblock_t bno) { int i; for (i = 0; i < blist_size; i++) { if (blist[i] == bno) return 1; } return 0; } static void check_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type) { xfs_extlen_t i; char *p; for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { if ((dbm_t)*p != type) { if (!sflag || CHECK_BLISTA(agno, agbno + i)) dbprintf(_("block %u/%u expected type %s got " "%s\n"), agno, agbno + i, typename[type], typename[(dbm_t)*p]); error++; } } } void check_init(void) { add_command(&blockfree_cmd); add_command(&blockget_cmd); if (expert_mode) add_command(&blocktrash_cmd); add_command(&blockuse_cmd); add_command(&ncheck_cmd); } static int check_inomap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, xfs_ino_t c_ino) { xfs_extlen_t i; inodata_t **idp; int rval; if (!check_range(agno, agbno, len)) { dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"), agno, agbno, agbno + len - 1, c_ino); return 0; } for (i = 0, rval = 1, idp = &inomap[agno][agbno]; i < len; i++, idp++) { if (*idp) { if (!sflag || (*idp)->ilist || CHECK_BLISTA(agno, agbno + i)) dbprintf(_("block %u/%u claimed by inode %lld, " "previous inum %lld\n"), agno, agbno + i, c_ino, (*idp)->ino); error++; rval = 0; } } return rval; } static void check_linkcounts( xfs_agnumber_t agno) { inodata_t *ep; inodata_t **ht; int idx; char *path; ht = inodata[agno]; for (idx = 0; idx < inodata_hash_size; ht++, idx++) { ep = *ht; while (ep) { if (ep->link_set != ep->link_add || ep->link_set == 0) { path = inode_name(ep->ino, NULL); if (!path && ep->link_add) path = xstrdup("?"); if (!sflag || ep->ilist) { if (ep->link_add) dbprintf(_("link count mismatch " "for inode %lld (name " "%s), nlink %d, " "counted %d\n"), ep->ino, path, ep->link_set, ep->link_add); else if (ep->link_set) dbprintf(_("disconnected inode " "%lld, nlink %d\n"), ep->ino, ep->link_set); else dbprintf(_("allocated inode %lld " "has 0 link count\n"), ep->ino); } if (path) xfree(path); error++; } else if (verbose || ep->ilist) { path = inode_name(ep->ino, NULL); if (path) { dbprintf(_("inode %lld name %s\n"), ep->ino, path); xfree(path); } } ep = ep->next; } } } static int check_range( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len) { xfs_extlen_t i; xfs_agblock_t low = 0; xfs_agblock_t high = 0; int valid_range = 0; int cur, prev = 0; if (agno >= mp->m_sb.sb_agcount || agbno + len - 1 >= mp->m_sb.sb_agblocks) { for (i = 0; i < len; i++) { cur = !sflag || CHECK_BLISTA(agno, agbno + i) ? 1 : 0; if (cur == 1 && prev == 0) { low = high = agbno + i; valid_range = 1; } else if (cur == 0 && prev == 0) { /* Do nothing */ } else if (cur == 0 && prev == 1) { if (low == high) { dbprintf(_("block %u/%u out of range\n"), agno, low); } else { dbprintf(_("blocks %u/%u..%u " "out of range\n"), agno, low, high); } valid_range = 0; } else if (cur == 1 && prev == 1) { high = agbno + i; } prev = cur; } if (valid_range) { if (low == high) { dbprintf(_("block %u/%u out of range\n"), agno, low); } else { dbprintf(_("blocks %u/%u..%u " "out of range\n"), agno, low, high); } } error++; return 0; } return 1; } static void check_rdbmap( xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type) { xfs_extlen_t i; char *p; for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) { if ((dbm_t)*p != type) { if (!sflag || CHECK_BLIST(bno + i)) dbprintf(_("rtblock %llu expected type %s got " "%s\n"), bno + i, typename[type], typename[(dbm_t)*p]); error++; } } } static int check_rinomap( xfs_drfsbno_t bno, xfs_extlen_t len, xfs_ino_t c_ino) { xfs_extlen_t i; inodata_t **idp; int rval; if (!check_rrange(bno, len)) { dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"), bno, bno + len - 1, c_ino); return 0; } for (i = 0, rval = 1, idp = &inomap[mp->m_sb.sb_agcount][bno]; i < len; i++, idp++) { if (*idp) { if (!sflag || (*idp)->ilist || CHECK_BLIST(bno + i)) dbprintf(_("rtblock %llu claimed by inode %lld, " "previous inum %lld\n"), bno + i, c_ino, (*idp)->ino); error++; rval = 0; } } return rval; } static void check_rootdir(void) { inodata_t *id; id = find_inode(mp->m_sb.sb_rootino, 0); if (id == NULL) { if (!sflag) dbprintf(_("root inode %lld is missing\n"), mp->m_sb.sb_rootino); error++; } else if (!id->isdir) { if (!sflag || id->ilist) dbprintf(_("root inode %lld is not a directory\n"), mp->m_sb.sb_rootino); error++; } } static int check_rrange( xfs_drfsbno_t bno, xfs_extlen_t len) { xfs_extlen_t i; if (bno + len - 1 >= mp->m_sb.sb_rblocks) { for (i = 0; i < len; i++) { if (!sflag || CHECK_BLIST(bno + i)) dbprintf(_("rtblock %llu out of range\n"), bno + i); } error++; return 0; } return 1; } static void check_set_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type1, dbm_t type2, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno) { xfs_extlen_t i; int mayprint; char *p; if (!check_range(agno, agbno, len)) { dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno, agbno, agbno + len - 1, c_agno, c_agbno); return; } check_dbmap(agno, agbno, len, type1); mayprint = verbose | blist_size; for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { *p = (char)type2; if (mayprint && (verbose || CHECK_BLISTA(agno, agbno + i))) dbprintf(_("setting block %u/%u to %s\n"), agno, agbno + i, typename[type2]); } } static void check_set_rdbmap( xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type1, dbm_t type2) { xfs_extlen_t i; int mayprint; char *p; if (!check_rrange(bno, len)) return; check_rdbmap(bno, len, type1); mayprint = verbose | blist_size; for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) { *p = (char)type2; if (mayprint && (verbose || CHECK_BLIST(bno + i))) dbprintf(_("setting rtblock %llu to %s\n"), bno + i, typename[type2]); } } static void check_summary(void) { xfs_drfsbno_t bno; xfs_suminfo_t *csp; xfs_suminfo_t *fsp; int log; csp = sumcompute; fsp = sumfile; for (log = 0; log < mp->m_rsumlevels; log++) { for (bno = 0; bno < mp->m_sb.sb_rbmblocks; bno++, csp++, fsp++) { if (*csp != *fsp) { if (!sflag) dbprintf(_("rt summary mismatch, size %d " "block %llu, file: %d, " "computed: %d\n"), log, bno, *fsp, *csp); error++; } } } } static void checknot_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, int typemask) { xfs_extlen_t i; char *p; if (!check_range(agno, agbno, len)) return; for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { if ((1 << *p) & typemask) { if (!sflag || CHECK_BLISTA(agno, agbno + i)) dbprintf(_("block %u/%u type %s not expected\n"), agno, agbno + i, typename[(dbm_t)*p]); error++; } } } static void checknot_rdbmap( xfs_drfsbno_t bno, xfs_extlen_t len, int typemask) { xfs_extlen_t i; char *p; if (!check_rrange(bno, len)) return; for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) { if ((1 << *p) & typemask) { if (!sflag || CHECK_BLIST(bno + i)) dbprintf(_("rtblock %llu type %s not expected\n"), bno + i, typename[(dbm_t)*p]); error++; } } } static void dir_hash_add( xfs_dahash_t hash, xfs_dir2_dataptr_t addr) { int i; dirhash_t *p; i = DIR_HASH_FUNC(hash, addr); p = malloc(sizeof(*p)); p->next = dirhash[i]; dirhash[i] = p; p->hashval = hash; p->address = addr; p->seen = 0; } static void dir_hash_check( inodata_t *id, int v) { int i; dirhash_t *p; for (i = 0; i < DIR_HASH_SIZE; i++) { for (p = dirhash[i]; p; p = p->next) { if (p->seen) continue; if (!sflag || id->ilist || v) dbprintf(_("dir ino %lld missing leaf entry for " "%x/%x\n"), id->ino, p->hashval, p->address); error++; } } } static void dir_hash_done(void) { int i; dirhash_t *n; dirhash_t *p; for (i = 0; i < DIR_HASH_SIZE; i++) { for (p = dirhash[i]; p; p = n) { n = p->next; free(p); } dirhash[i] = NULL; } } static void dir_hash_init(void) { if (!dirhash) dirhash = calloc(DIR_HASH_SIZE, sizeof(*dirhash)); } static int dir_hash_see( xfs_dahash_t hash, xfs_dir2_dataptr_t addr) { int i; dirhash_t *p; i = DIR_HASH_FUNC(hash, addr); for (p = dirhash[i]; p; p = p->next) { if (p->hashval == hash && p->address == addr) { if (p->seen) return 1; p->seen = 1; return 0; } } return -1; } static inodata_t * find_inode( xfs_ino_t ino, int add) { xfs_agino_t agino; xfs_agnumber_t agno; inodata_t *ent; inodata_t **htab; xfs_agino_t ih; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); if (agno >= mp->m_sb.sb_agcount || XFS_AGINO_TO_INO(mp, agno, agino) != ino) return NULL; htab = inodata[agno]; ih = agino % inodata_hash_size; ent = htab[ih]; while (ent) { if (ent->ino == ino) return ent; ent = ent->next; } if (!add) return NULL; ent = xcalloc(1, sizeof(*ent)); ent->ino = ino; ent->next = htab[ih]; htab[ih] = ent; return ent; } static void free_inodata( xfs_agnumber_t agno) { inodata_t *hp; inodata_t **ht; int i; inodata_t *next; ht = inodata[agno]; for (i = 0; i < inodata_hash_size; i++) { hp = ht[i]; while (hp) { next = hp->next; if (hp->name) xfree(hp->name); xfree(hp); hp = next; } } xfree(ht); } static int init( int argc, char **argv) { xfs_fsblock_t bno; int c; xfs_ino_t ino; int rt; serious_error = 0; if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) { dbprintf(_("bad superblock magic number %x, giving up\n"), mp->m_sb.sb_magicnum); serious_error = 1; return 0; } if (!sb_logcheck()) return 0; rt = mp->m_sb.sb_rextents != 0; dbmap = xmalloc((mp->m_sb.sb_agcount + rt) * sizeof(*dbmap)); inomap = xmalloc((mp->m_sb.sb_agcount + rt) * sizeof(*inomap)); inodata = xmalloc(mp->m_sb.sb_agcount * sizeof(*inodata)); inodata_hash_size = (int)MAX(MIN(mp->m_sb.sb_icount / (INODATA_AVG_HASH_LENGTH * mp->m_sb.sb_agcount), MAX_INODATA_HASH_SIZE), MIN_INODATA_HASH_SIZE); for (c = 0; c < mp->m_sb.sb_agcount; c++) { dbmap[c] = xcalloc(mp->m_sb.sb_agblocks, sizeof(**dbmap)); inomap[c] = xcalloc(mp->m_sb.sb_agblocks, sizeof(**inomap)); inodata[c] = xcalloc(inodata_hash_size, sizeof(**inodata)); } if (rt) { dbmap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**dbmap)); inomap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**inomap)); sumfile = xcalloc(mp->m_rsumsize, 1); sumcompute = xcalloc(mp->m_rsumsize, 1); } nflag = sflag = tflag = verbose = optind = 0; while ((c = getopt(argc, argv, "b:i:npstv")) != EOF) { switch (c) { case 'b': bno = strtoll(optarg, NULL, 10); add_blist(bno); break; case 'i': ino = strtoll(optarg, NULL, 10); add_ilist(ino); break; case 'n': nflag = 1; break; case 'p': pflag = 1; break; case 's': sflag = 1; break; case 't': tflag = 1; break; case 'v': verbose = 1; break; default: dbprintf(_("bad option for blockget command\n")); return 0; } } error = sbver_err = serious_error = 0; fdblocks = frextents = icount = ifree = 0; sbversion = XFS_SB_VERSION_4; if (mp->m_sb.sb_inoalignmt) sbversion |= XFS_SB_VERSION_ALIGNBIT; if ((mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) || (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO)) sbversion |= XFS_SB_VERSION_QUOTABIT; quota_init(); return 1; } static char * inode_name( xfs_ino_t ino, inodata_t **ipp) { inodata_t *id; char *npath; char *path; id = find_inode(ino, 0); if (ipp) *ipp = id; if (id == NULL) return NULL; if (id->name == NULL) return NULL; path = xstrdup(id->name); while (id->parent) { id = id->parent; if (id->name == NULL) break; npath = prepend_path(path, id->name); xfree(path); path = npath; } return path; } static int ncheck_f( int argc, char **argv) { xfs_agnumber_t agno; int c; inodata_t *hp; inodata_t **ht; int i; inodata_t *id; xfs_ino_t *ilist; int ilist_size; xfs_ino_t *ilp; xfs_ino_t ino; char *p; int security; if (!inodata || !nflag) { dbprintf(_("must run blockget -n first\n")); return 0; } security = optind = ilist_size = 0; ilist = NULL; while ((c = getopt(argc, argv, "i:s")) != EOF) { switch (c) { case 'i': ino = strtoll(optarg, NULL, 10); ilist = xrealloc(ilist, (ilist_size + 1) * sizeof(*ilist)); ilist[ilist_size++] = ino; break; case 's': security = 1; break; default: dbprintf(_("bad option -%c for ncheck command\n"), c); return 0; } } if (ilist) { for (ilp = ilist; ilp < &ilist[ilist_size]; ilp++) { ino = *ilp; if ((p = inode_name(ino, &hp))) { dbprintf("%11llu %s", ino, p); if (hp->isdir) dbprintf("/."); dbprintf("\n"); xfree(p); } } xfree(ilist); return 0; } for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { ht = inodata[agno]; for (i = 0; i < inodata_hash_size; i++) { hp = ht[i]; for (hp = ht[i]; hp; hp = hp->next) { ino = XFS_AGINO_TO_INO(mp, agno, hp->ino); p = inode_name(ino, &id); if (!p || !id) continue; if (!security || id->security) { dbprintf("%11llu %s", ino, p); if (hp->isdir) dbprintf("/."); dbprintf("\n"); } xfree(p); } } } return 0; } static char * prepend_path( char *oldpath, char *parent) { int len; char *path; len = (int)(strlen(oldpath) + strlen(parent) + 2); path = xmalloc(len); snprintf(path, len, "%s/%s", parent, oldpath); return path; } static xfs_ino_t process_block_dir_v2( blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id) { xfs_fsblock_t b; bbmap_t bbmap; bmap_ext_t *bmp; int nex; xfs_ino_t parent; int v; int x; nex = blkmap_getn(blkmap, 0, mp->m_dirblkfsbs, &bmp); v = id->ilist || verbose; if (nex == 0) { if (!sflag || v) dbprintf(_("block 0 for directory inode %lld is " "missing\n"), id->ino); error++; return 0; } push_cur(); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock), mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL); for (x = 0; !v && x < nex; x++) { for (b = bmp[x].startblock; !v && b < bmp[x].startblock + bmp[x].blockcount; b++) v = CHECK_BLIST(b); } free(bmp); if (iocur_top->data == NULL) { if (!sflag || id->ilist || v) dbprintf(_("can't read block 0 for directory inode " "%lld\n"), id->ino); error++; pop_cur(); return 0; } dir_hash_init(); parent = process_data_dir_v2(dot, dotdot, id, v, mp->m_dirdatablk, NULL); dir_hash_check(id, v); dir_hash_done(); pop_cur(); return parent; } static void process_bmbt_reclist( xfs_bmbt_rec_t *rp, int numrecs, dbm_t type, inodata_t *id, xfs_drfsbno_t *tot, blkmap_t **blkmapp) { xfs_agblock_t agbno; xfs_agnumber_t agno; xfs_fsblock_t b; xfs_dfilblks_t c; xfs_dfilblks_t cp; int f; int i; xfs_agblock_t iagbno; xfs_agnumber_t iagno; xfs_dfiloff_t o; xfs_dfiloff_t op; xfs_dfsbno_t s; int v; cp = op = 0; v = verbose || id->ilist; iagno = XFS_INO_TO_AGNO(mp, id->ino); iagbno = XFS_INO_TO_AGBNO(mp, id->ino); for (i = 0; i < numrecs; i++, rp++) { convert_extent(rp, &o, &s, &c, &f); if (v) dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"), id->ino, o, s, c, f); if (!sflag && i > 0 && op + cp > o) dbprintf(_("bmap rec out of order, inode %lld entry %d\n"), id->ino, i); op = o; cp = c; if (type == DBM_RTDATA) { if (!sflag && s >= mp->m_sb.sb_rblocks) { dbprintf(_("inode %lld bad rt block number %lld, " "offset %lld\n"), id->ino, s, o); continue; } } else if (!sflag) { agno = XFS_FSB_TO_AGNO(mp, s); agbno = XFS_FSB_TO_AGBNO(mp, s); if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks) { dbprintf(_("inode %lld bad block number %lld " "[%d,%d], offset %lld\n"), id->ino, s, agno, agbno, o); continue; } if (agbno + c - 1 >= mp->m_sb.sb_agblocks) { dbprintf(_("inode %lld bad block number %lld " "[%d,%d], offset %lld\n"), id->ino, s + c - 1, agno, agbno + (xfs_agblock_t)c - 1, o); continue; } } if (blkmapp && *blkmapp) blkmap_set_ext(blkmapp, (xfs_fileoff_t)o, (xfs_fsblock_t)s, (xfs_extlen_t)c); if (type == DBM_RTDATA) { set_rdbmap((xfs_fsblock_t)s, (xfs_extlen_t)c, DBM_RTDATA); set_rinomap((xfs_fsblock_t)s, (xfs_extlen_t)c, id); for (b = (xfs_fsblock_t)s; blist_size && b < s + c; b++, o++) { if (CHECK_BLIST(b)) dbprintf(_("inode %lld block %lld at " "offset %lld\n"), id->ino, (xfs_dfsbno_t)b, o); } } else { agno = XFS_FSB_TO_AGNO(mp, (xfs_fsblock_t)s); agbno = XFS_FSB_TO_AGBNO(mp, (xfs_fsblock_t)s); set_dbmap(agno, agbno, (xfs_extlen_t)c, type, iagno, iagbno); set_inomap(agno, agbno, (xfs_extlen_t)c, id); for (b = (xfs_fsblock_t)s; blist_size && b < s + c; b++, o++, agbno++) { if (CHECK_BLIST(b)) dbprintf(_("inode %lld block %lld at " "offset %lld\n"), id->ino, (xfs_dfsbno_t)b, o); } } *tot += c; } } static void process_btinode( inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork) { xfs_bmdr_block_t *dib; int i; xfs_bmbt_ptr_t *pp; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); if (be16_to_cpu(dib->bb_level) >= XFS_BM_MAXLEVELS(mp, whichfork)) { if (!sflag || id->ilist) dbprintf(_("level for ino %lld %s fork bmap root too " "large (%u)\n"), id->ino, whichfork == XFS_DATA_FORK ? _("data") : _("attr"), be16_to_cpu(dib->bb_level)); error++; return; } if (be16_to_cpu(dib->bb_numrecs) > xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), be16_to_cpu(dib->bb_level) == 0)) { if (!sflag || id->ilist) dbprintf(_("numrecs for ino %lld %s fork bmap root too " "large (%u)\n"), id->ino, whichfork == XFS_DATA_FORK ? _("data") : _("attr"), be16_to_cpu(dib->bb_numrecs)); error++; return; } if (be16_to_cpu(dib->bb_level) == 0) { xfs_bmbt_rec_t *rp = XFS_BMDR_REC_ADDR(dib, 1); process_bmbt_reclist(rp, be16_to_cpu(dib->bb_numrecs), type, id, totd, blkmapp); *nex += be16_to_cpu(dib->bb_numrecs); return; } else { pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 0)); for (i = 0; i < be16_to_cpu(dib->bb_numrecs); i++) scan_lbtree(be64_to_cpu(pp[i]), be16_to_cpu(dib->bb_level), scanfunc_bmap, type, id, totd, toti, nex, blkmapp, 1, whichfork == XFS_DATA_FORK ? TYP_BMAPBTD : TYP_BMAPBTA); } if (*nex <= XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { if (!sflag || id->ilist) dbprintf(_("extent count for ino %lld %s fork too low " "(%d) for file format\n"), id->ino, whichfork == XFS_DATA_FORK ? _("data") : _("attr"), *nex); error++; } } static xfs_ino_t process_data_dir_v2( int *dot, int *dotdot, inodata_t *id, int v, xfs_dablk_t dabno, freetab_t **freetabp) { xfs_dir2_dataptr_t addr; xfs_dir2_data_free_t *bf; int bf_err; xfs_dir2_block_t *block; xfs_dir2_block_tail_t *btp = NULL; inodata_t *cid; int count; xfs_dir2_data_t *data; xfs_dir2_db_t db; xfs_dir2_data_entry_t *dep; xfs_dir2_data_free_t *dfp; xfs_dir2_data_unused_t *dup; char *endptr; int freeseen; freetab_t *freetab; int i; int lastfree; int lastfree_err; xfs_dir2_leaf_entry_t *lep = NULL; xfs_ino_t lino; xfs_ino_t parent = 0; char *ptr; int stale = 0; int tag_err; __be16 *tagp; struct xfs_name xname; data = iocur_top->data; block = iocur_top->data; if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC && be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) { if (!sflag || v) dbprintf(_("bad directory data magic # %#x for dir ino " "%lld block %d\n"), be32_to_cpu(data->hdr.magic), id->ino, dabno); error++; return NULLFSINO; } db = xfs_dir2_da_to_db(mp, dabno); bf = data->hdr.bestfree; ptr = (char *)data->u; if (be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp, block); lep = xfs_dir2_block_leaf_p(btp); endptr = (char *)lep; if (endptr <= ptr || endptr > (char *)btp) { endptr = (char *)data + mp->m_dirblksize; lep = NULL; if (!sflag || v) dbprintf(_("bad block directory tail for dir ino " "%lld\n"), id->ino); error++; } } else endptr = (char *)data + mp->m_dirblksize; bf_err = lastfree_err = tag_err = 0; count = lastfree = freeseen = 0; if (be16_to_cpu(bf[0].length) == 0) { bf_err += be16_to_cpu(bf[0].offset) != 0; freeseen |= 1 << 0; } if (be16_to_cpu(bf[1].length) == 0) { bf_err += be16_to_cpu(bf[1].offset) != 0; freeseen |= 1 << 1; } if (be16_to_cpu(bf[2].length) == 0) { bf_err += be16_to_cpu(bf[2].offset) != 0; freeseen |= 1 << 2; } bf_err += be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length); bf_err += be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length); if (freetabp) { freetab = *freetabp; if (freetab->naents <= db) { *freetabp = freetab = realloc(freetab, FREETAB_SIZE(db + 1)); for (i = freetab->naents; i < db; i++) freetab->ents[i] = NULLDATAOFF; freetab->naents = db + 1; } if (freetab->nents < db + 1) freetab->nents = db + 1; freetab->ents[db] = be16_to_cpu(bf[0].length); } while (ptr < endptr) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { lastfree_err += lastfree != 0; tagp = xfs_dir2_data_unused_tag_p(dup); if ((be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1)) || be16_to_cpu(dup->length) == 0 || (char *)tagp >= endptr) { if (!sflag || v) dbprintf(_("dir %lld block %d bad free " "entry at %d\n"), id->ino, dabno, (int)((char *)dup - (char *)data)); error++; break; } tag_err += be16_to_cpu(*tagp) != (char *)dup - (char *)data; dfp = process_data_dir_v2_freefind(data, dup); if (dfp) { i = (int)(dfp - bf); bf_err += (freeseen & (1 << i)) != 0; freeseen |= 1 << i; } else bf_err += be16_to_cpu(dup->length) > be16_to_cpu(bf[2].length); ptr += be16_to_cpu(dup->length); lastfree = 1; continue; } dep = (xfs_dir2_data_entry_t *)dup; if (dep->namelen == 0) { if (!sflag || v) dbprintf(_("dir %lld block %d zero length entry " "at %d\n"), id->ino, dabno, (int)((char *)dep - (char *)data)); error++; } tagp = xfs_dir2_data_entry_tag_p(dep); if ((char *)tagp >= endptr) { if (!sflag || v) dbprintf(_("dir %lld block %d bad entry at %d\n"), id->ino, dabno, (int)((char *)dep - (char *)data)); error++; break; } tag_err += be16_to_cpu(*tagp) != (char *)dep - (char *)data; addr = xfs_dir2_db_off_to_dataptr(mp, db, (char *)dep - (char *)data); xname.name = dep->name; xname.len = dep->namelen; dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); ptr += xfs_dir2_data_entsize(dep->namelen); count++; lastfree = 0; lino = be64_to_cpu(dep->inumber); cid = find_inode(lino, 1); if (v) dbprintf(_("dir %lld block %d entry %*.*s %lld\n"), id->ino, dabno, dep->namelen, dep->namelen, dep->name, lino); if (cid) addlink_inode(cid); else { if (!sflag || v) dbprintf(_("dir %lld block %d entry %*.*s bad " "inode number %lld\n"), id->ino, dabno, dep->namelen, dep->namelen, dep->name, lino); error++; } if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') { if (parent) { if (!sflag || v) dbprintf(_("multiple .. entries in dir " "%lld (%lld, %lld)\n"), id->ino, parent, lino); error++; } else parent = cid ? lino : NULLFSINO; (*dotdot)++; } else if (dep->namelen != 1 || dep->name[0] != '.') { if (cid != NULL) { if (!cid->parent) cid->parent = id; addname_inode(cid, (char *)dep->name, dep->namelen); } } else { if (lino != id->ino) { if (!sflag || v) dbprintf(_("dir %lld entry . inode " "number mismatch (%lld)\n"), id->ino, lino); error++; } (*dot)++; } } if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { endptr = (char *)data + mp->m_dirblksize; for (i = stale = 0; lep && i < be32_to_cpu(btp->count); i++) { if ((char *)&lep[i] >= endptr) { if (!sflag || v) dbprintf(_("dir %lld block %d bad count " "%u\n"), id->ino, dabno, be32_to_cpu(btp->count)); error++; break; } if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; else if (dir_hash_see(be32_to_cpu(lep[i].hashval), be32_to_cpu(lep[i].address))) { if (!sflag || v) dbprintf(_("dir %lld block %d extra leaf " "entry %x %x\n"), id->ino, dabno, be32_to_cpu(lep[i].hashval), be32_to_cpu(lep[i].address)); error++; } } } bf_err += freeseen != 7; if (bf_err) { if (!sflag || v) dbprintf(_("dir %lld block %d bad bestfree data\n"), id->ino, dabno); error++; } if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad block tail count %d " "(stale %d)\n"), id->ino, dabno, be32_to_cpu(btp->count), be32_to_cpu(btp->stale)); error++; } if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && stale != be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad stale tail count %d\n"), id->ino, dabno, be32_to_cpu(btp->stale)); error++; } if (lastfree_err) { if (!sflag || v) dbprintf(_("dir %lld block %d consecutive free entries\n"), id->ino, dabno); error++; } if (tag_err) { if (!sflag || v) dbprintf(_("dir %lld block %d entry/unused tag " "mismatch\n"), id->ino, dabno); error++; } return parent; } static xfs_dir2_data_free_t * process_data_dir_v2_freefind( xfs_dir2_data_t *data, xfs_dir2_data_unused_t *dup) { xfs_dir2_data_free_t *dfp; xfs_dir2_data_aoff_t off; off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)data); if (be16_to_cpu(dup->length) < be16_to_cpu(data->hdr. bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; for (dfp = &data->hdr.bestfree[0]; dfp < &data->hdr. bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (be16_to_cpu(dfp->offset) == 0) return NULL; if (be16_to_cpu(dfp->offset) == off) return dfp; } return NULL; } static void process_dir( xfs_dinode_t *dip, blkmap_t *blkmap, inodata_t *id) { xfs_fsblock_t bno; int dot; int dotdot; xfs_ino_t parent; dot = dotdot = 0; if (xfs_sb_version_hasdirv2(&mp->m_sb)) { if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent)) return; } else { if (process_dir_v1(dip, blkmap, &dot, &dotdot, id, &parent)) return; } bno = XFS_INO_TO_FSB(mp, id->ino); if (dot == 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("no . entry for directory %lld\n"), id->ino); error++; } if (dotdot == 0) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("no .. entry for directory %lld\n"), id->ino); error++; } else if (parent == id->ino && id->ino != mp->m_sb.sb_rootino) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_(". and .. same for non-root directory %lld\n"), id->ino); error++; } else if (id->ino == mp->m_sb.sb_rootino && id->ino != parent) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("root directory %lld has .. %lld\n"), id->ino, parent); error++; } else if (parent != NULLFSINO && id->ino != parent) addparent_inode(id, parent); } static int process_dir_v1( xfs_dinode_t *dip, blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_ino_t *parent) { xfs_fsize_t size = be64_to_cpu(dip->di_size); if (size <= XFS_DFORK_DSIZE(dip, mp) && dip->di_format == XFS_DINODE_FMT_LOCAL) *parent = process_shortform_dir_v1(dip, dot, dotdot, id); else if (size == XFS_LBSIZE(mp) && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) *parent = process_leaf_dir_v1(blkmap, dot, dotdot, id); else if (size >= XFS_LBSIZE(mp) && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) *parent = process_node_dir_v1(blkmap, dot, dotdot, id); else { dbprintf(_("bad size (%lld) or format (%d) for directory inode " "%lld\n"), size, dip->di_format, id->ino); error++; return 1; } return 0; } static int process_dir_v2( xfs_dinode_t *dip, blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_ino_t *parent) { xfs_fileoff_t last = 0; xfs_fsize_t size = be64_to_cpu(dip->di_size); if (blkmap) last = blkmap_last_off(blkmap); if (size <= XFS_DFORK_DSIZE(dip, mp) && dip->di_format == XFS_DINODE_FMT_LOCAL) *parent = process_sf_dir_v2(dip, dot, dotdot, id); else if (last == mp->m_dirblkfsbs && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) *parent = process_block_dir_v2(blkmap, dot, dotdot, id); else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs && (dip->di_format == XFS_DINODE_FMT_EXTENTS || dip->di_format == XFS_DINODE_FMT_BTREE)) *parent = process_leaf_node_dir_v2(blkmap, dot, dotdot, id, size); else { dbprintf(_("bad size (%lld) or format (%d) for directory inode " "%lld\n"), size, dip->di_format, id->ino); error++; return 1; } return 0; } /* ARGSUSED */ static void process_exinode( inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork) { xfs_bmbt_rec_t *rp; rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); *nex = XFS_DFORK_NEXTENTS(dip, whichfork); if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { if (!sflag || id->ilist) dbprintf(_("bad number of extents %d for inode %lld\n"), *nex, id->ino); error++; return; } process_bmbt_reclist(rp, *nex, type, id, totd, blkmapp); } static void process_inode( xfs_agf_t *agf, xfs_agino_t agino, xfs_dinode_t *dip, int isfree) { blkmap_t *blkmap; xfs_fsblock_t bno = 0; xfs_icdinode_t idic; inodata_t *id = NULL; xfs_ino_t ino; xfs_extnum_t nextents = 0; int nlink; int security; xfs_drfsbno_t totblocks; xfs_drfsbno_t totdblocks = 0; xfs_drfsbno_t totiblocks = 0; dbm_t type; xfs_extnum_t anextents = 0; xfs_drfsbno_t atotdblocks = 0; xfs_drfsbno_t atotiblocks = 0; xfs_qcnt_t bc = 0; xfs_qcnt_t ic = 0; xfs_qcnt_t rc = 0; xfs_dqid_t dqprid; int v = 0; static char okfmts[] = { 0, /* type 0 unused */ 1 << XFS_DINODE_FMT_DEV, /* FIFO */ 1 << XFS_DINODE_FMT_DEV, /* CHR */ 0, /* type 3 unused */ (1 << XFS_DINODE_FMT_LOCAL) | (1 << XFS_DINODE_FMT_EXTENTS) | (1 << XFS_DINODE_FMT_BTREE), /* DIR */ 0, /* type 5 unused */ 1 << XFS_DINODE_FMT_DEV, /* BLK */ 0, /* type 7 unused */ (1 << XFS_DINODE_FMT_EXTENTS) | (1 << XFS_DINODE_FMT_BTREE), /* REG */ 0, /* type 9 unused */ (1 << XFS_DINODE_FMT_LOCAL) | (1 << XFS_DINODE_FMT_EXTENTS), /* LNK */ 0, /* type 11 unused */ 1 << XFS_DINODE_FMT_DEV, /* SOCK */ 0, /* type 13 unused */ 1 << XFS_DINODE_FMT_UUID, /* MNT */ 0 /* type 15 unused */ }; static char *fmtnames[] = { "dev", "local", "extents", "btree", "uuid" }; libxfs_dinode_from_disk(&idic, dip); ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino); if (!isfree) { id = find_inode(ino, 1); bno = XFS_INO_TO_FSB(mp, ino); blkmap = NULL; } v = (!sflag || (id && id->ilist) || CHECK_BLIST(bno)); if (idic.di_magic != XFS_DINODE_MAGIC) { if (isfree || v) dbprintf(_("bad magic number %#x for inode %lld\n"), idic.di_magic, ino); error++; return; } if (!XFS_DINODE_GOOD_VERSION(idic.di_version)) { if (isfree || v) dbprintf(_("bad version number %#x for inode %lld\n"), idic.di_version, ino); error++; return; } if (isfree) { if (idic.di_nblocks != 0) { if (v) dbprintf(_("bad nblocks %lld for free inode " "%lld\n"), idic.di_nblocks, ino); error++; } if (idic.di_version == 1) nlink = idic.di_onlink; else nlink = idic.di_nlink; if (nlink != 0) { if (v) dbprintf(_("bad nlink %d for free inode %lld\n"), nlink, ino); error++; } if (idic.di_mode != 0) { if (v) dbprintf(_("bad mode %#o for free inode %lld\n"), idic.di_mode, ino); error++; } return; } if (be32_to_cpu(dip->di_next_unlinked) != NULLAGINO) { if (v) dbprintf(_("bad next unlinked %#x for inode %lld\n"), be32_to_cpu(dip->di_next_unlinked), ino); error++; } /* * di_mode is a 16-bit uint so no need to check the < 0 case */ if ((((idic.di_mode & S_IFMT) >> 12) > 15) || (!(okfmts[(idic.di_mode & S_IFMT) >> 12] & (1 << idic.di_format)))) { if (v) dbprintf(_("bad format %d for inode %lld type %#o\n"), idic.di_format, id->ino, idic.di_mode & S_IFMT); error++; return; } if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= XFS_LITINO(mp)) { if (v) dbprintf(_("bad fork offset %d for inode %lld\n"), idic.di_forkoff, id->ino); error++; return; } if ((unsigned int)idic.di_aformat > XFS_DINODE_FMT_BTREE) { if (v) dbprintf(_("bad attribute format %d for inode %lld\n"), idic.di_aformat, id->ino); error++; return; } if (verbose || (id && id->ilist) || CHECK_BLIST(bno)) dbprintf(_("inode %lld mode %#o fmt %s " "afmt %s " "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"), id->ino, idic.di_mode, fmtnames[(int)idic.di_format], fmtnames[(int)idic.di_aformat], idic.di_nextents, idic.di_anextents, idic.di_nblocks, idic.di_size, idic.di_flags & XFS_DIFLAG_REALTIME ? " rt" : "", idic.di_flags & XFS_DIFLAG_PREALLOC ? " pre" : "", idic.di_flags & XFS_DIFLAG_IMMUTABLE? " imm" : "", idic.di_flags & XFS_DIFLAG_APPEND ? " app" : "", idic.di_flags & XFS_DIFLAG_SYNC ? " syn" : "", idic.di_flags & XFS_DIFLAG_NOATIME ? " noa" : "", idic.di_flags & XFS_DIFLAG_NODUMP ? " nod" : ""); security = 0; switch (idic.di_mode & S_IFMT) { case S_IFDIR: type = DBM_DIR; if (idic.di_format == XFS_DINODE_FMT_LOCAL) break; blkmap = blkmap_alloc(idic.di_nextents); break; case S_IFREG: if (idic.di_flags & XFS_DIFLAG_REALTIME) type = DBM_RTDATA; else if (id->ino == mp->m_sb.sb_rbmino) { type = DBM_RTBITMAP; blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_rsumino) { type = DBM_RTSUM; blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_uquotino || id->ino == mp->m_sb.sb_gquotino) { type = DBM_QUOTA; blkmap = blkmap_alloc(idic.di_nextents); addlink_inode(id); } else type = DBM_DATA; if (idic.di_mode & (S_ISUID | S_ISGID)) security = 1; break; case S_IFLNK: type = DBM_SYMLINK; break; default: security = 1; type = DBM_UNKNOWN; break; } if (idic.di_version == 1) setlink_inode(id, idic.di_onlink, type == DBM_DIR, security); else { sbversion |= XFS_SB_VERSION_NLINKBIT; setlink_inode(id, idic.di_nlink, type == DBM_DIR, security); } switch (idic.di_format) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, type, &totdblocks, &totiblocks, &nextents, &blkmap, XFS_DATA_FORK); break; case XFS_DINODE_FMT_EXTENTS: process_exinode(id, dip, type, &totdblocks, &totiblocks, &nextents, &blkmap, XFS_DATA_FORK); break; case XFS_DINODE_FMT_BTREE: process_btinode(id, dip, type, &totdblocks, &totiblocks, &nextents, &blkmap, XFS_DATA_FORK); break; } if (XFS_DFORK_Q(dip)) { sbversion |= XFS_SB_VERSION_ATTRBIT; switch (idic.di_aformat) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, DBM_ATTR, &atotdblocks, &atotiblocks, &anextents, NULL, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_EXTENTS: process_exinode(id, dip, DBM_ATTR, &atotdblocks, &atotiblocks, &anextents, NULL, XFS_ATTR_FORK); break; case XFS_DINODE_FMT_BTREE: process_btinode(id, dip, DBM_ATTR, &atotdblocks, &atotiblocks, &anextents, NULL, XFS_ATTR_FORK); break; } } if (qgdo || qpdo || qudo) { switch (type) { case DBM_DATA: case DBM_DIR: case DBM_RTBITMAP: case DBM_RTSUM: case DBM_SYMLINK: case DBM_UNKNOWN: bc = totdblocks + totiblocks + atotdblocks + atotiblocks; ic = 1; break; case DBM_RTDATA: bc = totiblocks + atotdblocks + atotiblocks; rc = totdblocks; ic = 1; break; default: break; } if (ic) { dqprid = xfs_get_projid(idic); /* dquot ID is u32 */ quota_add(&dqprid, &idic.di_gid, &idic.di_uid, 0, bc, ic, rc); } } totblocks = totdblocks + totiblocks + atotdblocks + atotiblocks; if (totblocks != idic.di_nblocks) { if (v) dbprintf(_("bad nblocks %lld for inode %lld, counted " "%lld\n"), idic.di_nblocks, id->ino, totblocks); error++; } if (nextents != idic.di_nextents) { if (v) dbprintf(_("bad nextents %d for inode %lld, counted %d\n"), idic.di_nextents, id->ino, nextents); error++; } if (anextents != idic.di_anextents) { if (v) dbprintf(_("bad anextents %d for inode %lld, counted " "%d\n"), idic.di_anextents, id->ino, anextents); error++; } if (type == DBM_DIR) process_dir(dip, blkmap, id); else if (type == DBM_RTBITMAP) process_rtbitmap(blkmap); else if (type == DBM_RTSUM) process_rtsummary(blkmap); /* * If the CHKD flag is not set, this can legitimately contain garbage; * xfs_repair may have cleared that bit. */ else if (type == DBM_QUOTA) { if (id->ino == mp->m_sb.sb_uquotino && (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD)) process_quota(IS_USER_QUOTA, id, blkmap); else if (id->ino == mp->m_sb.sb_gquotino && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD)) process_quota(IS_GROUP_QUOTA, id, blkmap); else if (id->ino == mp->m_sb.sb_gquotino && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD)) process_quota(IS_PROJECT_QUOTA, id, blkmap); } if (blkmap) blkmap_free(blkmap); } /* ARGSUSED */ static void process_lclinode( inodata_t *id, xfs_dinode_t *dip, dbm_t type, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork) { xfs_attr_shortform_t *asf; xfs_fsblock_t bno; bno = XFS_INO_TO_FSB(mp, id->ino); if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_size) > XFS_DFORK_DSIZE(dip, mp)) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("local inode %lld data is too large (size " "%lld)\n"), id->ino, be64_to_cpu(dip->di_size)); error++; } else if (whichfork == XFS_ATTR_FORK) { asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); if (be16_to_cpu(asf->hdr.totsize) > XFS_DFORK_ASIZE(dip, mp)) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("local inode %lld attr is too large " "(size %d)\n"), id->ino, be16_to_cpu(asf->hdr.totsize)); error++; } } } static xfs_ino_t process_leaf_dir_v1( blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id) { xfs_fsblock_t bno; xfs_ino_t parent; bno = blkmap_get(blkmap, 0); if (bno == NULLFSBLOCK) { if (!sflag || id->ilist) dbprintf(_("block 0 for directory inode %lld is " "missing\n"), id->ino); error++; return 0; } push_cur(); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("can't read block 0 for directory inode " "%lld\n"), id->ino); error++; pop_cur(); return 0; } parent = process_leaf_dir_v1_int(dot, dotdot, id); pop_cur(); return parent; } static xfs_ino_t process_leaf_dir_v1_int( int *dot, int *dotdot, inodata_t *id) { xfs_fsblock_t bno; inodata_t *cid; xfs_dir_leaf_entry_t *entry; int i; xfs_dir_leafblock_t *leaf; xfs_ino_t lino; xfs_dir_leaf_name_t *namest; xfs_ino_t parent = 0; int v; bno = XFS_DADDR_TO_FSB(mp, iocur_top->bb); v = verbose || id->ilist || CHECK_BLIST(bno); leaf = iocur_top->data; if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("bad directory leaf magic # %#x for dir ino " "%lld\n"), be16_to_cpu(leaf->hdr.info.magic), id->ino); error++; return NULLFSINO; } entry = &leaf->entries[0]; for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { namest = xfs_dir_leaf_namestruct(leaf, be16_to_cpu(entry->nameidx)); lino = XFS_GET_DIR_INO8(namest->inumber); cid = find_inode(lino, 1); if (v) dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino, entry->namelen, entry->namelen, namest->name, lino); if (cid) addlink_inode(cid); else { if (!sflag) dbprintf(_("dir %lld entry %*.*s bad inode " "number %lld\n"), id->ino, entry->namelen, entry->namelen, namest->name, lino); error++; } if (entry->namelen == 2 && namest->name[0] == '.' && namest->name[1] == '.') { if (parent) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("multiple .. entries in dir " "%lld (%lld, %lld)\n"), id->ino, parent, lino); error++; } else parent = cid ? lino : NULLFSINO; (*dotdot)++; } else if (entry->namelen != 1 || namest->name[0] != '.') { if (cid != NULL) { if (!cid->parent) cid->parent = id; addname_inode(cid, (char *)namest->name, entry->namelen); } } else { if (lino != id->ino) { if (!sflag) dbprintf(_("dir %lld entry . inode " "number mismatch (%lld)\n"), id->ino, lino); error++; } (*dot)++; } } return parent; } static xfs_ino_t process_leaf_node_dir_v2( blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id, xfs_fsize_t dirsize) { xfs_fsblock_t b; bbmap_t bbmap; bmap_ext_t *bmp; xfs_fileoff_t dbno; freetab_t *freetab; int i; xfs_ino_t lino; int nex; xfs_ino_t parent; int t = 0; int v; int v2; int x; v2 = verbose || id->ilist; v = parent = 0; dbno = NULLFILEOFF; freetab = malloc(FREETAB_SIZE(dirsize / mp->m_dirblksize)); freetab->naents = (int)(dirsize / mp->m_dirblksize); freetab->nents = 0; for (i = 0; i < freetab->naents; i++) freetab->ents[i] = NULLDATAOFF; dir_hash_init(); while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) { nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp); ASSERT(nex > 0); for (v = v2, x = 0; !v && x < nex; x++) { for (b = bmp[x].startblock; !v && b < bmp[x].startblock + bmp[x].blockcount; b++) v = CHECK_BLIST(b); } if (v) dbprintf(_("dir inode %lld block %u=%llu\n"), id->ino, (__uint32_t)dbno, (xfs_dfsbno_t)bmp->startblock); push_cur(); if (nex > 1) make_bbmap(&bbmap, nex, bmp); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock), mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL); free(bmp); if (iocur_top->data == NULL) { if (!sflag || v) dbprintf(_("can't read block %u for directory " "inode %lld\n"), (__uint32_t)dbno, id->ino); error++; pop_cur(); dbno += mp->m_dirblkfsbs - 1; continue; } if (dbno < mp->m_dirleafblk) { lino = process_data_dir_v2(dot, dotdot, id, v, (xfs_dablk_t)dbno, &freetab); if (lino) { if (parent) { if (!sflag || v) dbprintf(_("multiple .. entries " "in dir %lld\n"), id->ino); error++; } else parent = lino; } } else if (dbno < mp->m_dirfreeblk) { process_leaf_node_dir_v2_int(id, v, (xfs_dablk_t)dbno, freetab); } else { process_leaf_node_dir_v2_free(id, v, (xfs_dablk_t)dbno, freetab); } pop_cur(); dbno += mp->m_dirblkfsbs - 1; } dir_hash_check(id, v); dir_hash_done(); for (i = 0; i < freetab->nents; i++) { if (freetab->ents[i] != NULLDATAOFF) { if (!sflag || v) dbprintf(_("missing free index for data block %d " "in dir ino %lld\n"), xfs_dir2_db_to_da(mp, i), id->ino); error++; } } free(freetab); return parent; } static void process_leaf_node_dir_v2_free( inodata_t *id, int v, xfs_dablk_t dabno, freetab_t *freetab) { xfs_dir2_data_off_t ent; xfs_dir2_free_t *free; int i; int maxent; int used; free = iocur_top->data; if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) { if (!sflag || v) dbprintf(_("bad free block magic # %#x for dir ino %lld " "block %d\n"), be32_to_cpu(free->hdr.magic), id->ino, dabno); error++; return; } maxent = XFS_DIR2_MAX_FREE_BESTS(mp); if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp, dabno - mp->m_dirfreeblk) * maxent) { if (!sflag || v) dbprintf(_("bad free block firstdb %d for dir ino %lld " "block %d\n"), be32_to_cpu(free->hdr.firstdb), id->ino, dabno); error++; return; } if (be32_to_cpu(free->hdr.nvalid) > maxent || be32_to_cpu(free->hdr.nvalid) < 0 || be32_to_cpu(free->hdr.nused) > maxent || be32_to_cpu(free->hdr.nused) < 0 || be32_to_cpu(free->hdr.nused) > be32_to_cpu(free->hdr.nvalid)) { if (!sflag || v) dbprintf(_("bad free block nvalid/nused %d/%d for dir " "ino %lld block %d\n"), be32_to_cpu(free->hdr.nvalid), be32_to_cpu(free->hdr.nused), id->ino, dabno); error++; return; } for (used = i = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { if (freetab->nents <= be32_to_cpu(free->hdr.firstdb) + i) ent = NULLDATAOFF; else ent = freetab->ents[be32_to_cpu(free->hdr.firstdb) + i]; if (ent != be16_to_cpu(free->bests[i])) { if (!sflag || v) dbprintf(_("bad free block ent %d is %d should " "be %d for dir ino %lld block %d\n"), i, be16_to_cpu(free->bests[i]), ent, id->ino, dabno); error++; } if (be16_to_cpu(free->bests[i]) != NULLDATAOFF) used++; if (ent != NULLDATAOFF) freetab->ents[be32_to_cpu(free->hdr.firstdb) + i] = NULLDATAOFF; } if (used != be32_to_cpu(free->hdr.nused)) { if (!sflag || v) dbprintf(_("bad free block nused %d should be %d for dir " "ino %lld block %d\n"), be32_to_cpu(free->hdr.nused), used, id->ino, dabno); error++; } } static void process_leaf_node_dir_v2_int( inodata_t *id, int v, xfs_dablk_t dabno, freetab_t *freetab) { int i; __be16 *lbp; xfs_dir2_leaf_t *leaf; xfs_dir2_leaf_entry_t *lep; xfs_dir2_leaf_tail_t *ltp; xfs_da_intnode_t *node; int stale; leaf = iocur_top->data; switch (be16_to_cpu(leaf->hdr.info.magic)) { case XFS_DIR2_LEAF1_MAGIC: if (be32_to_cpu(leaf->hdr.info.forw) || be32_to_cpu(leaf->hdr.info.back)) { if (!sflag || v) dbprintf(_("bad leaf block forw/back pointers " "%d/%d for dir ino %lld block %d\n"), be32_to_cpu(leaf->hdr.info.forw), be32_to_cpu(leaf->hdr.info.back), id->ino, dabno); error++; } if (dabno != mp->m_dirleafblk) { if (!sflag || v) dbprintf(_("single leaf block for dir ino %lld " "block %d should be at block %d\n"), id->ino, dabno, (xfs_dablk_t)mp->m_dirleafblk); error++; } ltp = xfs_dir2_leaf_tail_p(mp, leaf); lbp = xfs_dir2_leaf_bests_p(ltp); for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { if (freetab->nents <= i || freetab->ents[i] != be16_to_cpu(lbp[i])) { if (!sflag || v) dbprintf(_("bestfree %d for dir ino %lld " "block %d doesn't match table " "value %d\n"), freetab->nents <= i ? NULLDATAOFF : freetab->ents[i], id->ino, xfs_dir2_db_to_da(mp, i), be16_to_cpu(lbp[i])); } if (freetab->nents > i) freetab->ents[i] = NULLDATAOFF; } break; case XFS_DIR2_LEAFN_MAGIC: /* if it's at the root location then we can check the * pointers are null XXX */ break; case XFS_DA_NODE_MAGIC: node = iocur_top->data; if (be16_to_cpu(node->hdr.level) < 1 || be16_to_cpu(node->hdr.level) > XFS_DA_NODE_MAXDEPTH) { if (!sflag || v) dbprintf(_("bad node block level %d for dir ino " "%lld block %d\n"), be16_to_cpu(node->hdr.level), id->ino, dabno); error++; } return; default: if (!sflag || v) dbprintf(_("bad directory data magic # %#x for dir ino " "%lld block %d\n"), be16_to_cpu(leaf->hdr.info.magic), id->ino, dabno); error++; return; } lep = leaf->ents; for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; else if (dir_hash_see(be32_to_cpu(lep[i].hashval), be32_to_cpu(lep[i].address))) { if (!sflag || v) dbprintf(_("dir %lld block %d extra leaf entry " "%x %x\n"), id->ino, dabno, be32_to_cpu(lep[i].hashval), be32_to_cpu(lep[i].address)); error++; } } if (stale != be16_to_cpu(leaf->hdr.stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d stale mismatch " "%d/%d\n"), id->ino, dabno, stale, be16_to_cpu(leaf->hdr.stale)); error++; } } static xfs_ino_t process_node_dir_v1( blkmap_t *blkmap, int *dot, int *dotdot, inodata_t *id) { xfs_fsblock_t bno; xfs_fileoff_t dbno; xfs_ino_t lino; xfs_ino_t parent; int t; int v; int v2; v = verbose || id->ilist; parent = 0; dbno = NULLFILEOFF; push_cur(); while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, dbno); v2 = bno != NULLFSBLOCK && CHECK_BLIST(bno); if (bno == NULLFSBLOCK && dbno == 0) { if (!sflag || v) dbprintf(_("can't read root block for directory " "inode %lld\n"), id->ino); error++; } if (v || v2) dbprintf(_("dir inode %lld block %u=%llu\n"), id->ino, (__uint32_t)dbno, (xfs_dfsbno_t)bno); if (bno == NULLFSBLOCK) continue; pop_cur(); push_cur(); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { if (!sflag || v || v2) dbprintf(_("can't read block %u for directory " "inode %lld\n"), (__uint32_t)dbno, id->ino); error++; continue; } if (be16_to_cpu(((xfs_da_intnode_t *)iocur_top->data)-> hdr.info.magic) == XFS_DA_NODE_MAGIC) continue; lino = process_leaf_dir_v1_int(dot, dotdot, id); if (lino) { if (parent) { if (!sflag || v || v2) dbprintf(_("multiple .. entries in dir " "%lld\n"), id->ino); error++; } else parent = lino; } } pop_cur(); return parent; } static void process_quota( qtype_t qtype, inodata_t *id, blkmap_t *blkmap) { xfs_fsblock_t bno; int cb; xfs_dqblk_t *dqb; xfs_dqid_t dqid; u_int8_t exp_flags = 0; uint i; uint perblock; xfs_fileoff_t qbno; char *s = NULL; int scicb; int t = 0; switch (qtype) { case IS_USER_QUOTA: s = "user"; exp_flags = XFS_DQ_USER; break; case IS_PROJECT_QUOTA: s = "project"; exp_flags = XFS_DQ_PROJ; break; case IS_GROUP_QUOTA: s = "group"; exp_flags = XFS_DQ_GROUP; break; default: ASSERT(0); } perblock = (uint)(mp->m_sb.sb_blocksize / sizeof(*dqb)); dqid = 0; qbno = NULLFILEOFF; while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, qbno); dqid = (xfs_dqid_t)qbno * perblock; cb = CHECK_BLIST(bno); scicb = !sflag || id->ilist || cb; push_cur(); set_cur(&typtab[TYP_DQBLK], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if ((dqb = iocur_top->data) == NULL) { if (scicb) dbprintf(_("can't read block %lld for %s quota " "inode (fsblock %lld)\n"), (xfs_dfiloff_t)qbno, s, (xfs_dfsbno_t)bno); error++; pop_cur(); continue; } for (i = 0; i < perblock; i++, dqid++, dqb++) { if (verbose || id->ilist || cb) dbprintf(_("%s dqblk %lld entry %d id %u bc " "%lld ic %lld rc %lld\n"), s, (xfs_dfiloff_t)qbno, i, dqid, be64_to_cpu(dqb->dd_diskdq.d_bcount), be64_to_cpu(dqb->dd_diskdq.d_icount), be64_to_cpu(dqb->dd_diskdq.d_rtbcount)); if (be16_to_cpu(dqb->dd_diskdq.d_magic) != XFS_DQUOT_MAGIC) { if (scicb) dbprintf(_("bad magic number %#x for %s " "dqblk %lld entry %d id %u\n"), be16_to_cpu(dqb->dd_diskdq.d_magic), s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } if (dqb->dd_diskdq.d_version != XFS_DQUOT_VERSION) { if (scicb) dbprintf(_("bad version number %#x for " "%s dqblk %lld entry %d id " "%u\n"), dqb->dd_diskdq.d_version, s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } if (dqb->dd_diskdq.d_flags != exp_flags) { if (scicb) dbprintf(_("bad flags %#x for %s dqblk " "%lld entry %d id %u\n"), dqb->dd_diskdq.d_flags, s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } if (be32_to_cpu(dqb->dd_diskdq.d_id) != dqid) { if (scicb) dbprintf(_("bad id %u for %s dqblk %lld " "entry %d id %u\n"), be32_to_cpu(dqb->dd_diskdq.d_id), s, (xfs_dfiloff_t)qbno, i, dqid); error++; continue; } quota_add((qtype == IS_PROJECT_QUOTA) ? &dqid : NULL, (qtype == IS_GROUP_QUOTA) ? &dqid : NULL, (qtype == IS_USER_QUOTA) ? &dqid : NULL, 1, be64_to_cpu(dqb->dd_diskdq.d_bcount), be64_to_cpu(dqb->dd_diskdq.d_icount), be64_to_cpu(dqb->dd_diskdq.d_rtbcount)); } pop_cur(); } } static void process_rtbitmap( blkmap_t *blkmap) { int bit; int bitsperblock; xfs_fileoff_t bmbno; xfs_fsblock_t bno; xfs_drtbno_t extno; int len; int log; int offs; int prevbit; xfs_drfsbno_t rtbno; int start_bmbno; int start_bit; int t; xfs_rtword_t *words; bitsperblock = mp->m_sb.sb_blocksize * NBBY; bit = extno = prevbit = start_bmbno = start_bit = 0; bmbno = NULLFILEOFF; while ((bmbno = blkmap_next_off(blkmap, bmbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, bmbno); if (bno == NULLFSBLOCK) { if (!sflag) dbprintf(_("block %lld for rtbitmap inode is " "missing\n"), (xfs_dfiloff_t)bmbno); error++; continue; } push_cur(); set_cur(&typtab[TYP_RTBITMAP], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if ((words = iocur_top->data) == NULL) { if (!sflag) dbprintf(_("can't read block %lld for rtbitmap " "inode\n"), (xfs_dfiloff_t)bmbno); error++; pop_cur(); continue; } for (bit = 0; bit < bitsperblock && extno < mp->m_sb.sb_rextents; bit++, extno++) { if (xfs_isset(words, bit)) { rtbno = extno * mp->m_sb.sb_rextsize; set_rdbmap(rtbno, mp->m_sb.sb_rextsize, DBM_RTFREE); frextents++; if (prevbit == 0) { start_bmbno = (int)bmbno; start_bit = bit; prevbit = 1; } } else if (prevbit == 1) { len = ((int)bmbno - start_bmbno) * bitsperblock + (bit - start_bit); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; prevbit = 0; } } pop_cur(); if (extno == mp->m_sb.sb_rextents) break; } if (prevbit == 1) { len = ((int)bmbno - start_bmbno) * bitsperblock + (bit - start_bit); log = XFS_RTBLOCKLOG(len); offs = XFS_SUMOFFS(mp, log, start_bmbno); sumcompute[offs]++; } } static void process_rtsummary( blkmap_t *blkmap) { xfs_fsblock_t bno; char *bytes; xfs_fileoff_t sumbno; int t; sumbno = NULLFILEOFF; while ((sumbno = blkmap_next_off(blkmap, sumbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, sumbno); if (bno == NULLFSBLOCK) { if (!sflag) dbprintf(_("block %lld for rtsummary inode is " "missing\n"), (xfs_dfiloff_t)sumbno); error++; continue; } push_cur(); set_cur(&typtab[TYP_RTSUMMARY], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if ((bytes = iocur_top->data) == NULL) { if (!sflag) dbprintf(_("can't read block %lld for rtsummary " "inode\n"), (xfs_dfiloff_t)sumbno); error++; pop_cur(); continue; } memcpy((char *)sumfile + sumbno * mp->m_sb.sb_blocksize, bytes, mp->m_sb.sb_blocksize); pop_cur(); } } static xfs_ino_t process_sf_dir_v2( xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id) { inodata_t *cid; int i; int i8; xfs_ino_t lino; int offset; xfs_dir2_sf_t *sf; xfs_dir2_sf_entry_t *sfe; int v; sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip); addlink_inode(id); v = verbose || id->ilist; if (v) dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino); (*dot)++; sfe = xfs_dir2_sf_firstentry(sf); offset = XFS_DIR2_DATA_FIRST_OFFSET; for (i = sf->hdr.count - 1, i8 = 0; i >= 0; i--) { if ((__psint_t)sfe + xfs_dir2_sf_entsize_byentry(sf, sfe) - (__psint_t)sf > be64_to_cpu(dip->di_size)) { if (!sflag) dbprintf(_("dir %llu bad size in entry at %d\n"), id->ino, (int)((char *)sfe - (char *)sf)); error++; break; } lino = xfs_dir2_sf_get_inumber(sf, xfs_dir2_sf_inumberp(sfe)); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); if (cid == NULL) { if (!sflag) dbprintf(_("dir %lld entry %*.*s bad inode " "number %lld\n"), id->ino, sfe->namelen, sfe->namelen, sfe->name, lino); error++; } else { addlink_inode(cid); if (!cid->parent) cid->parent = id; addname_inode(cid, (char *)sfe->name, sfe->namelen); } if (v) dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"), id->ino, sfe->namelen, sfe->namelen, sfe->name, xfs_dir2_sf_get_offset(sfe), lino); if (xfs_dir2_sf_get_offset(sfe) < offset) { if (!sflag) dbprintf(_("dir %lld entry %*.*s bad offset %d\n"), id->ino, sfe->namelen, sfe->namelen, sfe->name, xfs_dir2_sf_get_offset(sfe)); error++; } offset = xfs_dir2_sf_get_offset(sfe) + xfs_dir2_data_entsize(sfe->namelen); sfe = xfs_dir2_sf_nextentry(sf, sfe); } if (i < 0 && (__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_size)) { if (!sflag) dbprintf(_("dir %llu size is %lld, should be %u\n"), id->ino, be64_to_cpu(dip->di_size), (uint)((char *)sfe - (char *)sf)); error++; } if (offset + (sf->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) + sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) { if (!sflag) dbprintf(_("dir %llu offsets too high\n"), id->ino); error++; } lino = xfs_dir2_sf_get_inumber(sf, &sf->hdr.parent); if (lino > XFS_DIR2_MAX_SHORT_INUM) i8++; cid = find_inode(lino, 1); if (cid) addlink_inode(cid); else { if (!sflag) dbprintf(_("dir %lld entry .. bad inode number %lld\n"), id->ino, lino); error++; } if (v) dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino); if (i8 != sf->hdr.i8count) { if (!sflag) dbprintf(_("dir %lld i8count mismatch is %d should be " "%d\n"), id->ino, sf->hdr.i8count, i8); error++; } (*dotdot)++; return cid ? lino : NULLFSINO; } static xfs_ino_t process_shortform_dir_v1( xfs_dinode_t *dip, int *dot, int *dotdot, inodata_t *id) { inodata_t *cid; int i; xfs_ino_t lino; xfs_dir_shortform_t *sf; xfs_dir_sf_entry_t *sfe; int v; sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip); addlink_inode(id); v = verbose || id->ilist; if (v) dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino); (*dot)++; sfe = &sf->list[0]; for (i = sf->hdr.count - 1; i >= 0; i--) { lino = XFS_GET_DIR_INO8(sfe->inumber); cid = find_inode(lino, 1); if (cid == NULL) { if (!sflag) dbprintf(_("dir %lld entry %*.*s bad inode " "number %lld\n"), id->ino, sfe->namelen, sfe->namelen, sfe->name, lino); error++; } else { addlink_inode(cid); if (!cid->parent) cid->parent = id; addname_inode(cid, (char *)sfe->name, sfe->namelen); } if (v) dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino, sfe->namelen, sfe->namelen, sfe->name, lino); sfe = xfs_dir_sf_nextentry(sfe); } if ((__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_size)) dbprintf(_("dir %llu size is %lld, should be %d\n"), id->ino, be64_to_cpu(dip->di_size), (int)((char *)sfe - (char *)sf)); lino = XFS_GET_DIR_INO8(sf->hdr.parent); cid = find_inode(lino, 1); if (cid) addlink_inode(cid); else { if (!sflag) dbprintf(_("dir %lld entry .. bad inode number %lld\n"), id->ino, lino); error++; } if (v) dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino); (*dotdot)++; return cid ? lino : NULLFSINO; } static void quota_add( xfs_dqid_t *prjid, xfs_dqid_t *grpid, xfs_dqid_t *usrid, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc) { if (qudo && usrid != NULL) quota_add1(qudata, *usrid, dq, bc, ic, rc); if (qgdo && grpid != NULL) quota_add1(qgdata, *grpid, dq, bc, ic, rc); if (qpdo && prjid != NULL) quota_add1(qpdata, *prjid, dq, bc, ic, rc); } static void quota_add1( qdata_t **qt, xfs_dqid_t id, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc) { qdata_t *qe; int qh; qinfo_t *qi; qh = (int)(id % QDATA_HASH_SIZE); qe = qt[qh]; while (qe) { if (qe->id == id) { qi = dq ? &qe->dq : &qe->count; qi->bc += bc; qi->ic += ic; qi->rc += rc; return; } qe = qe->next; } qe = xmalloc(sizeof(*qe)); qe->id = id; qi = dq ? &qe->dq : &qe->count; qi->bc = bc; qi->ic = ic; qi->rc = rc; qi = dq ? &qe->count : &qe->dq; qi->bc = qi->ic = qi->rc = 0; qe->next = qt[qh]; qt[qh] = qe; } static void quota_check( char *s, qdata_t **qt) { int i; qdata_t *next; qdata_t *qp; for (i = 0; i < QDATA_HASH_SIZE; i++) { qp = qt[i]; while (qp) { next = qp->next; if (qp->count.bc != qp->dq.bc || qp->count.ic != qp->dq.ic || qp->count.rc != qp->dq.rc) { if (!sflag) { dbprintf(_("%s quota id %u, have/exp"), s, qp->id); if (qp->count.bc != qp->dq.bc) dbprintf(_(" bc %lld/%lld"), qp->dq.bc, qp->count.bc); if (qp->count.ic != qp->dq.ic) dbprintf(_(" ic %lld/%lld"), qp->dq.ic, qp->count.ic); if (qp->count.rc != qp->dq.rc) dbprintf(_(" rc %lld/%lld"), qp->dq.rc, qp->count.rc); dbprintf("\n"); } error++; } xfree(qp); qp = next; } } xfree(qt); } static void quota_init(void) { qudo = mp->m_sb.sb_uquotino != 0 && mp->m_sb.sb_uquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD); qgdo = mp->m_sb.sb_gquotino != 0 && mp->m_sb.sb_gquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD); qpdo = mp->m_sb.sb_gquotino != 0 && mp->m_sb.sb_gquotino != NULLFSINO && (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) && (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD); if (qudo) qudata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); if (qgdo) qgdata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); if (qpdo) qpdata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *)); } static void scan_ag( xfs_agnumber_t agno) { xfs_agf_t *agf; xfs_agi_t *agi; int i; xfs_sb_t tsb; xfs_sb_t *sb = &tsb; agffreeblks = agflongest = 0; agfbtreeblks = -2; agicount = agifreecount = 0; push_cur(); /* 1 pushed */ set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (!iocur_top->data) { dbprintf(_("can't read superblock for ag %u\n"), agno); serious_error++; goto pop1_out; } libxfs_sb_from_disk(sb, iocur_top->data); if (sb->sb_magicnum != XFS_SB_MAGIC) { if (!sflag) dbprintf(_("bad sb magic # %#x in ag %u\n"), sb->sb_magicnum, agno); error++; } if (!xfs_sb_good_version(sb)) { if (!sflag) dbprintf(_("bad sb version # %#x in ag %u\n"), sb->sb_versionnum, agno); error++; sbver_err++; } if (!lazycount && xfs_sb_version_haslazysbcount(sb)) { lazycount = 1; } if (agno == 0 && sb->sb_inprogress != 0) { if (!sflag) dbprintf(_("mkfs not completed successfully\n")); error++; } set_dbmap(agno, XFS_SB_BLOCK(mp), 1, DBM_SB, agno, XFS_SB_BLOCK(mp)); if (sb->sb_logstart && XFS_FSB_TO_AGNO(mp, sb->sb_logstart) == agno) set_dbmap(agno, XFS_FSB_TO_AGBNO(mp, sb->sb_logstart), sb->sb_logblocks, DBM_LOG, agno, XFS_SB_BLOCK(mp)); push_cur(); /* 2 pushed */ set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agf = iocur_top->data) == NULL) { dbprintf(_("can't read agf block for ag %u\n"), agno); serious_error++; goto pop2_out; } if (be32_to_cpu(agf->agf_magicnum) != XFS_AGF_MAGIC) { if (!sflag) dbprintf(_("bad agf magic # %#x in ag %u\n"), be32_to_cpu(agf->agf_magicnum), agno); error++; } if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum))) { if (!sflag) dbprintf(_("bad agf version # %#x in ag %u\n"), be32_to_cpu(agf->agf_versionnum), agno); error++; } if (XFS_SB_BLOCK(mp) != XFS_AGF_BLOCK(mp)) set_dbmap(agno, XFS_AGF_BLOCK(mp), 1, DBM_AGF, agno, XFS_SB_BLOCK(mp)); if (sb->sb_agblocks > be32_to_cpu(agf->agf_length)) set_dbmap(agno, be32_to_cpu(agf->agf_length), sb->sb_agblocks - be32_to_cpu(agf->agf_length), DBM_MISSING, agno, XFS_SB_BLOCK(mp)); push_cur(); /* 3 pushed */ set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agi = iocur_top->data) == NULL) { dbprintf(_("can't read agi block for ag %u\n"), agno); serious_error++; goto pop3_out; } if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { if (!sflag) dbprintf(_("bad agi magic # %#x in ag %u\n"), be32_to_cpu(agi->agi_magicnum), agno); error++; } if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) { if (!sflag) dbprintf(_("bad agi version # %#x in ag %u\n"), be32_to_cpu(agi->agi_versionnum), agno); error++; } if (XFS_SB_BLOCK(mp) != XFS_AGI_BLOCK(mp) && XFS_AGF_BLOCK(mp) != XFS_AGI_BLOCK(mp)) set_dbmap(agno, XFS_AGI_BLOCK(mp), 1, DBM_AGI, agno, XFS_SB_BLOCK(mp)); scan_freelist(agf); fdblocks--; scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), 1, scanfunc_bno, TYP_BNOBT); fdblocks--; scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), 1, scanfunc_cnt, TYP_CNTBT); scan_sbtree(agf, be32_to_cpu(agi->agi_root), be32_to_cpu(agi->agi_level), 1, scanfunc_ino, TYP_INOBT); if (be32_to_cpu(agf->agf_freeblks) != agffreeblks) { if (!sflag) dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_freeblks), agffreeblks, agno); error++; } if (be32_to_cpu(agf->agf_longest) != agflongest) { if (!sflag) dbprintf(_("agf_longest %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_longest), agflongest, agno); error++; } if (lazycount && be32_to_cpu(agf->agf_btreeblks) != agfbtreeblks) { if (!sflag) dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_btreeblks), agfbtreeblks, agno); error++; } agf_aggr_freeblks += agffreeblks + agfbtreeblks; if (be32_to_cpu(agi->agi_count) != agicount) { if (!sflag) dbprintf(_("agi_count %u, counted %u in ag %u\n"), be32_to_cpu(agi->agi_count), agicount, agno); error++; } if (be32_to_cpu(agi->agi_freecount) != agifreecount) { if (!sflag) dbprintf(_("agi_freecount %u, counted %u in ag %u\n"), be32_to_cpu(agi->agi_freecount), agifreecount, agno); error++; } for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { if (be32_to_cpu(agi->agi_unlinked[i]) != NULLAGINO) { if (!sflag) { xfs_agino_t agino=be32_to_cpu(agi->agi_unlinked[i]); dbprintf(_("agi unlinked bucket %d is %u in ag " "%u (inode=%lld)\n"), i, agino, agno, XFS_AGINO_TO_INO(mp, agno, agino)); } error++; } } pop3_out: pop_cur(); pop2_out: pop_cur(); pop1_out: pop_cur(); } static void scan_freelist( xfs_agf_t *agf) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agfl_t *agfl; xfs_agblock_t bno; uint count; int i; if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) set_dbmap(seqno, XFS_AGFL_BLOCK(mp), 1, DBM_AGFL, seqno, XFS_SB_BLOCK(mp)); if (be32_to_cpu(agf->agf_flcount) == 0) return; push_cur(); set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agfl = iocur_top->data) == NULL) { dbprintf(_("can't read agfl block for ag %u\n"), seqno); serious_error++; pop_cur(); return; } i = be32_to_cpu(agf->agf_flfirst); count = 0; for (;;) { bno = be32_to_cpu(agfl->agfl_bno[i]); set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno, XFS_AGFL_BLOCK(mp)); count++; if (i == be32_to_cpu(agf->agf_fllast)) break; if (++i == XFS_AGFL_SIZE(mp)) i = 0; } if (count != be32_to_cpu(agf->agf_flcount)) { if (!sflag) dbprintf(_("freeblk count %u != flcount %u in ag %u\n"), count, be32_to_cpu(agf->agf_flcount), seqno); error++; } fdblocks += count; agf_aggr_freeblks += count; pop_cur(); } static void scan_lbtree( xfs_fsblock_t root, int nlevels, scan_lbtree_f_t func, dbm_t type, inodata_t *id, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int isroot, typnm_t btype) { push_cur(); set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, root), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { if (!sflag) dbprintf(_("can't read btree block %u/%u\n"), XFS_FSB_TO_AGNO(mp, root), XFS_FSB_TO_AGBNO(mp, root)); error++; pop_cur(); return; } (*func)(iocur_top->data, nlevels - 1, type, root, id, totd, toti, nex, blkmapp, isroot, btype); pop_cur(); } static void scan_sbtree( xfs_agf_t *agf, xfs_agblock_t root, int nlevels, int isroot, scan_sbtree_f_t func, typnm_t btype) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, seqno, root), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { if (!sflag) dbprintf(_("can't read btree block %u/%u\n"), seqno, root); error++; pop_cur(); return; } (*func)(iocur_top->data, nlevels - 1, agf, root, isroot); pop_cur(); } static void scanfunc_bmap( struct xfs_btree_block *block, int level, dbm_t type, xfs_fsblock_t bno, inodata_t *id, xfs_drfsbno_t *totd, xfs_drfsbno_t *toti, xfs_extnum_t *nex, blkmap_t **blkmapp, int isroot, typnm_t btype) { xfs_agblock_t agbno; xfs_agnumber_t agno; int i; xfs_bmbt_ptr_t *pp; xfs_bmbt_rec_t *rp; agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("bad magic # %#x in inode %lld bmbt block " "%u/%u\n"), be32_to_cpu(block->bb_magic), id->ino, agno, agbno); error++; } if (be16_to_cpu(block->bb_level) != level) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("expected level %d got %d in inode %lld bmbt " "block %u/%u\n"), level, be16_to_cpu(block->bb_level), id->ino, agno, agbno); error++; } set_dbmap(agno, agbno, 1, type, agno, agbno); set_inomap(agno, agbno, 1, id); (*toti)++; if (level == 0) { if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[0] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_bmap_dmnr[0])) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) " "in inode %lld bmap block %lld\n"), be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[0], mp->m_bmap_dmxr[0], id->ino, (xfs_dfsbno_t)bno); error++; return; } rp = XFS_BMBT_REC_ADDR(mp, block, 1); *nex += be16_to_cpu(block->bb_numrecs); process_bmbt_reclist(rp, be16_to_cpu(block->bb_numrecs), type, id, totd, blkmapp); return; } if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[1] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_bmap_dmnr[1])) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " "inode %lld bmap block %lld\n"), be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1], id->ino, (xfs_dfsbno_t)bno); error++; return; } pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[0]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, type, id, totd, toti, nex, blkmapp, 0, btype); } static void scanfunc_bno( struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot) { int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agblock_t lastblock; if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) { dbprintf(_("bad magic # %#x in btbno block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } fdblocks++; agfbtreeblks++; if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf(_("expected level %d got %d in btbno block " "%u/%u\n"), level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTBNO, seqno, bno); if (level == 0) { if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[0] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[0])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " "btbno block %u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[0], mp->m_alloc_mxr[0], seqno, bno); serious_error++; return; } rp = XFS_ALLOC_REC_ADDR(mp, block, 1); lastblock = 0; for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { set_dbmap(seqno, be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount), DBM_FREE1, seqno, bno); if (be32_to_cpu(rp[i].ar_startblock) <= lastblock) { dbprintf(_( "out-of-order bno btree record %d (%u %u) block %u/%u\n"), i, be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount), be32_to_cpu(agf->agf_seqno), bno); serious_error++; } else { lastblock = be32_to_cpu(rp[i].ar_startblock); } } return; } if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[1] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[1])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block " "%u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[1], mp->m_alloc_mxr[1], seqno, bno); serious_error++; return; } pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_bno, TYP_BNOBT); } static void scanfunc_cnt( struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; xfs_alloc_ptr_t *pp; xfs_alloc_rec_t *rp; xfs_extlen_t lastcount; if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) { dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } fdblocks++; agfbtreeblks++; if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf(_("expected level %d got %d in btcnt block " "%u/%u\n"), level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTCNT, seqno, bno); if (level == 0) { if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[0] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[0])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " "btbno block %u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[0], mp->m_alloc_mxr[0], seqno, bno); serious_error++; return; } rp = XFS_ALLOC_REC_ADDR(mp, block, 1); lastcount = 0; for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { check_set_dbmap(seqno, be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount), DBM_FREE1, DBM_FREE2, seqno, bno); fdblocks += be32_to_cpu(rp[i].ar_blockcount); agffreeblks += be32_to_cpu(rp[i].ar_blockcount); if (be32_to_cpu(rp[i].ar_blockcount) > agflongest) agflongest = be32_to_cpu(rp[i].ar_blockcount); if (be32_to_cpu(rp[i].ar_blockcount) < lastcount) { dbprintf(_( "out-of-order cnt btree record %d (%u %u) block %u/%u\n"), i, be32_to_cpu(rp[i].ar_startblock), be32_to_cpu(rp[i].ar_blockcount), be32_to_cpu(agf->agf_seqno), bno); } else { lastcount = be32_to_cpu(rp[i].ar_blockcount); } } return; } if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[1] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_alloc_mnr[1])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block " "%u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_alloc_mnr[1], mp->m_alloc_mxr[1], seqno, bno); serious_error++; return; } pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_cnt, TYP_CNTBT); } static void scanfunc_ino( struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot) { xfs_agino_t agino; xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; int isfree; int j; int nfree; int off; xfs_inobt_ptr_t *pp; xfs_inobt_rec_t *rp; if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { dbprintf(_("bad magic # %#x in inobt block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; return; } if (be16_to_cpu(block->bb_level) != level) { if (!sflag) dbprintf(_("expected level %d got %d in inobt block " "%u/%u\n"), level, be16_to_cpu(block->bb_level), seqno, bno); error++; } set_dbmap(seqno, bno, 1, DBM_BTINO, seqno, bno); if (level == 0) { if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[0] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[0])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " "inobt block %u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[0], mp->m_inobt_mxr[0], seqno, bno); serious_error++; return; } rp = XFS_INOBT_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { agino = be32_to_cpu(rp[i].ir_startino); off = XFS_INO_TO_OFFSET(mp, agino); if (off == 0) { if ((sbversion & XFS_SB_VERSION_ALIGNBIT) && mp->m_sb.sb_inoalignmt && (XFS_INO_TO_AGBNO(mp, agino) % mp->m_sb.sb_inoalignmt)) sbversion &= ~XFS_SB_VERSION_ALIGNBIT; set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, agino), (xfs_extlen_t)MAX(1, XFS_INODES_PER_CHUNK >> mp->m_sb.sb_inopblog), DBM_INODE, seqno, bno); } icount += XFS_INODES_PER_CHUNK; agicount += XFS_INODES_PER_CHUNK; ifree += be32_to_cpu(rp[i].ir_freecount); agifreecount += be32_to_cpu(rp[i].ir_freecount); push_cur(); set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, seqno, XFS_AGINO_TO_AGBNO(mp, agino)), (int)XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)), DB_RING_IGN, NULL); if (iocur_top->data == NULL) { if (!sflag) dbprintf(_("can't read inode block " "%u/%u\n"), seqno, XFS_AGINO_TO_AGBNO(mp, agino)); error++; pop_cur(); continue; } for (j = 0, nfree = 0; j < XFS_INODES_PER_CHUNK; j++) { isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j); if (isfree) nfree++; process_inode(agf, agino + j, (xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog)), isfree); } if (nfree != be32_to_cpu(rp[i].ir_freecount)) { if (!sflag) dbprintf(_("ir_freecount/free mismatch, " "inode chunk %u/%u, freecount " "%d nfree %d\n"), seqno, agino, be32_to_cpu(rp[i].ir_freecount), nfree); error++; } pop_cur(); } return; } if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[1] || (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[1])) { dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block " "%u/%u\n"), be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[1], mp->m_inobt_mxr[1], seqno, bno); serious_error++; return; } pp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_ino, TYP_INOBT); } static void set_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno) { check_set_dbmap(agno, agbno, len, DBM_UNKNOWN, type, c_agno, c_agbno); } static void set_inomap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, inodata_t *id) { xfs_extlen_t i; inodata_t **idp; int mayprint; if (!check_inomap(agno, agbno, len, id->ino)) return; mayprint = verbose | id->ilist | blist_size; for (i = 0, idp = &inomap[agno][agbno]; i < len; i++, idp++) { *idp = id; if (mayprint && (verbose || id->ilist || CHECK_BLISTA(agno, agbno + i))) dbprintf(_("setting inode to %lld for block %u/%u\n"), id->ino, agno, agbno + i); } } static void set_rdbmap( xfs_drfsbno_t bno, xfs_extlen_t len, dbm_t type) { check_set_rdbmap(bno, len, DBM_UNKNOWN, type); } static void set_rinomap( xfs_drfsbno_t bno, xfs_extlen_t len, inodata_t *id) { xfs_extlen_t i; inodata_t **idp; int mayprint; if (!check_rinomap(bno, len, id->ino)) return; mayprint = verbose | id->ilist | blist_size; for (i = 0, idp = &inomap[mp->m_sb.sb_agcount][bno]; i < len; i++, idp++) { *idp = id; if (mayprint && (verbose || id->ilist || CHECK_BLIST(bno + i))) dbprintf(_("setting inode to %lld for rtblock %llu\n"), id->ino, bno + i); } } static void setlink_inode( inodata_t *id, nlink_t nlink, int isdir, int security) { id->link_set = nlink; id->isdir = isdir; id->security = security; if (verbose || id->ilist) dbprintf(_("inode %lld nlink %u %s dir\n"), id->ino, nlink, isdir ? "is" : "not"); } xfsprogs-3.1.9ubuntu2/db/bit.h0000664000000000000000000000210611140033220013111 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define bitize(s) ((s) * NBBY) #define bitsz(t) bitize(sizeof(t)) #define bitszof(x,y) bitize(szof(x,y)) #define byteize(s) ((s) / NBBY) #define bitoffs(s) ((s) % NBBY) #define BVUNSIGNED 0 #define BVSIGNED 1 extern __int64_t getbitval(void *obj, int bitoff, int nbits, int flags); extern void setbitval(void *obuf, int bitoff, int nbits, void *ibuf); xfsprogs-3.1.9ubuntu2/db/input.h0000664000000000000000000000162711140033220013501 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern char **breakline(char *input, int *count); extern void doneline(char *input, char **vec); extern char *fetchline(void); extern void input_init(void); extern void pushfile(FILE *file); xfsprogs-3.1.9ubuntu2/db/bit.c0000664000000000000000000000754711140033220013122 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "bit.h" #undef setbit /* defined in param.h on Linux */ static int getbit(char *ptr, int bit); static void setbit(char *ptr, int bit, int val); static int getbit( char *ptr, int bit) { int mask; int shift; ptr += byteize(bit); bit = bitoffs(bit); shift = 7 - bit; mask = 1 << shift; return (*ptr & mask) >> shift; } static void setbit( char *ptr, int bit, int val) { int mask; int shift; ptr += byteize(bit); bit = bitoffs(bit); shift = 7 - bit; mask = (1 << shift); if (val) { *ptr |= mask; } else { mask = ~mask; *ptr &= mask; } } __int64_t getbitval( void *obj, int bitoff, int nbits, int flags) { int bit; int i; char *p; __int64_t rval; int signext; int z1, z2, z3, z4; ASSERT(nbits<=64); p = (char *)obj + byteize(bitoff); bit = bitoffs(bitoff); signext = (flags & BVSIGNED) != 0; z4 = ((__psint_t)p & 0xf) == 0 && bit == 0; if (nbits == 64 && z4) return be64_to_cpu(*(__be64 *)p); z3 = ((__psint_t)p & 0x7) == 0 && bit == 0; if (nbits == 32 && z3) { if (signext) return (__s32)be32_to_cpu(*(__be32 *)p); else return (__u32)be32_to_cpu(*(__be32 *)p); } z2 = ((__psint_t)p & 0x3) == 0 && bit == 0; if (nbits == 16 && z2) { if (signext) return (__s16)be16_to_cpu(*(__be16 *)p); else return (__u16)be16_to_cpu(*(__be16 *)p); } z1 = ((__psint_t)p & 0x1) == 0 && bit == 0; if (nbits == 8 && z1) { if (signext) return *(__s8 *)p; else return *(__u8 *)p; } for (i = 0, rval = 0LL; i < nbits; i++) { if (getbit(p, bit + i)) { /* If the last bit is on and we care about sign * bits and we don't have a full 64 bit * container, turn all bits on between the * sign bit and the most sig bit. */ /* handle endian swap here */ #if __BYTE_ORDER == LITTLE_ENDIAN if (i == 0 && signext && nbits < 64) rval = -1LL << nbits; rval |= 1LL << (nbits - i - 1); #else if ((i == (nbits - 1)) && signext && nbits < 64) rval |= (-1LL << nbits); rval |= 1LL << (nbits - i - 1); #endif } } return rval; } void setbitval( void *obuf, /* buffer to write into */ int bitoff, /* bit offset of where to write */ int nbits, /* number of bits to write */ void *ibuf) /* source bits */ { char *in = (char *)ibuf; char *out = (char *)obuf; int bit; #if BYTE_ORDER == LITTLE_ENDIAN int big = 0; #else int big = 1; #endif /* only need to swap LE integers */ if (big || (nbits!=16 && nbits!=32 && nbits!=64) ) { /* We don't have type info, so we can only assume * that 2,4 & 8 byte values are integers. sigh. */ /* byte aligned ? */ if (bitoff%NBBY) { /* no - bit copy */ for (bit=0; bit #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "bmroot.h" #include "io.h" #include "print.h" #include "bit.h" #include "init.h" static int bmroota_key_count(void *obj, int startoff); static int bmroota_key_offset(void *obj, int startoff, int idx); static int bmroota_ptr_count(void *obj, int startoff); static int bmroota_ptr_offset(void *obj, int startoff, int idx); static int bmrootd_key_count(void *obj, int startoff); static int bmrootd_key_offset(void *obj, int startoff, int idx); static int bmrootd_ptr_count(void *obj, int startoff); static int bmrootd_ptr_offset(void *obj, int startoff, int idx); #define OFF(f) bitize(offsetof(xfs_bmdr_block_t, bb_ ## f)) const field_t bmroota_flds[] = { { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "keys", FLDT_BMROOTAKEY, bmroota_key_offset, bmroota_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_BMROOTAPTR, bmroota_ptr_offset, bmroota_ptr_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA }, { NULL } }; const field_t bmrootd_flds[] = { { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, { "keys", FLDT_BMROOTDKEY, bmrootd_key_offset, bmrootd_key_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, { "ptrs", FLDT_BMROOTDPTR, bmrootd_ptr_offset, bmrootd_ptr_count, FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD }, { NULL } }; #define KOFF(f) bitize(offsetof(xfs_bmdr_key_t, br_ ## f)) const field_t bmroota_key_flds[] = { { "startoff", FLDT_DFILOFFA, OI(KOFF(startoff)), C1, 0, TYP_NONE }, { NULL } }; const field_t bmrootd_key_flds[] = { { "startoff", FLDT_DFILOFFD, OI(KOFF(startoff)), C1, 0, TYP_NONE }, { NULL } }; static int bmroota_key_count( void *obj, int startoff) { xfs_bmdr_block_t *block; #ifdef DEBUG xfs_dinode_t *dip = obj; #endif ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); return be16_to_cpu(block->bb_numrecs); } static int bmroota_key_offset( void *obj, int startoff, int idx) { xfs_bmdr_block_t *block; /* REFERENCED */ xfs_dinode_t *dip; xfs_bmdr_key_t *kp; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); kp = XFS_BMDR_KEY_ADDR(block, idx); return bitize((int)((char *)kp - (char *)block)); } static int bmroota_ptr_count( void *obj, int startoff) { xfs_bmdr_block_t *block; #ifdef DEBUG xfs_dinode_t *dip = obj; #endif ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); return be16_to_cpu(block->bb_numrecs); } static int bmroota_ptr_offset( void *obj, int startoff, int idx) { xfs_bmdr_block_t *block; xfs_dinode_t *dip; xfs_bmdr_ptr_t *pp; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); pp = XFS_BMDR_PTR_ADDR(block, idx, xfs_bmdr_maxrecs(mp, XFS_DFORK_ASIZE(dip, mp), 0)); return bitize((int)((char *)pp - (char *)block)); } int bmroota_size( void *obj, int startoff, int idx) { xfs_dinode_t *dip; #ifdef DEBUG xfs_bmdr_block_t *block; #endif ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); ASSERT(idx == 0); dip = obj; #ifdef DEBUG block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(XFS_DFORK_Q(dip) && (char *)block == XFS_DFORK_APTR(dip)); #endif return bitize((int)XFS_DFORK_ASIZE(dip, mp)); } static int bmrootd_key_count( void *obj, int startoff) { xfs_bmdr_block_t *block; #ifdef DEBUG xfs_dinode_t *dip = obj; #endif ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT((char *)block == XFS_DFORK_DPTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); return be16_to_cpu(block->bb_numrecs); } static int bmrootd_key_offset( void *obj, int startoff, int idx) { xfs_bmdr_block_t *block; xfs_bmdr_key_t *kp; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(be16_to_cpu(block->bb_level) > 0); kp = XFS_BMDR_KEY_ADDR(block, idx); return bitize((int)((char *)kp - (char *)block)); } static int bmrootd_ptr_count( void *obj, int startoff) { xfs_bmdr_block_t *block; #ifdef DEBUG xfs_dinode_t *dip = obj; #endif ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT((char *)block == XFS_DFORK_DPTR(dip)); ASSERT(be16_to_cpu(block->bb_level) > 0); return be16_to_cpu(block->bb_numrecs); } static int bmrootd_ptr_offset( void *obj, int startoff, int idx) { xfs_bmdr_block_t *block; xfs_bmdr_ptr_t *pp; xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); dip = obj; block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff)); ASSERT(be16_to_cpu(block->bb_level) > 0); pp = XFS_BMDR_PTR_ADDR(block, idx, xfs_bmdr_maxrecs(mp, XFS_DFORK_DSIZE(dip, mp), 0)); return bitize((int)((char *)pp - (char *)block)); } int bmrootd_size( void *obj, int startoff, int idx) { xfs_dinode_t *dip; ASSERT(bitoffs(startoff) == 0); ASSERT(obj == iocur_top->data); ASSERT(idx == 0); dip = obj; return bitize((int)XFS_DFORK_DSIZE(dip, mp)); } xfsprogs-3.1.9ubuntu2/db/faddr.h0000664000000000000000000000326511140033220013422 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef void (*adfnc_t)(void *obj, int bit, typnm_t next); extern void fa_agblock(void *obj, int bit, typnm_t next); extern void fa_agino(void *obj, int bit, typnm_t next); extern void fa_attrblock(void *obj, int bit, typnm_t next); extern void fa_cfileoffd(void *obj, int bit, typnm_t next); extern void fa_cfsblock(void *obj, int bit, typnm_t next); extern void fa_dfiloffd(void *obj, int bit, typnm_t next); extern void fa_dfsbno(void *obj, int bit, typnm_t next); extern void fa_dinode_union(void *obj, int bit, typnm_t next); extern void fa_dirblock(void *obj, int bit, typnm_t next); extern void fa_drfsbno(void *obj, int bit, typnm_t next); extern void fa_drtbno(void *obj, int bit, typnm_t next); extern void fa_ino(void *obj, int bit, typnm_t next); extern void fa_cfileoffa(void *obj, int bit, typnm_t next); extern void fa_dfiloffa(void *obj, int bit, typnm_t next); extern void fa_ino4(void *obj, int bit, typnm_t next); extern void fa_ino8(void *obj, int bit, typnm_t next); xfsprogs-3.1.9ubuntu2/db/debug.c0000664000000000000000000000245111146407622013440 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "debug.h" #include "output.h" static int debug_f(int argc, char **argv); static const cmdinfo_t debug_cmd = { "debug", NULL, debug_f, 0, 1, 0, N_("[flagbits]"), N_("set debug option bits"), NULL }; long debug_state; static int debug_f( int argc, char **argv) { char *p; if (argc > 1) { debug_state = strtol(argv[1], &p, 0); if (*p != '\0') { dbprintf(_("bad value for debug %s\n"), argv[1]); return 0; } } dbprintf("debug = %ld\n", debug_state); return 0; } void debug_init(void) { add_command(&debug_cmd); } xfsprogs-3.1.9ubuntu2/db/init.c0000664000000000000000000000767212062210562013320 0ustar /* * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "command.h" #include "init.h" #include "input.h" #include "io.h" #include "init.h" #include "sig.h" #include "output.h" #include "malloc.h" static char **cmdline; static int ncmdline; char *fsdevice; int blkbb; int exitcode; int expert_mode; int force; xfs_mount_t xmount; xfs_mount_t *mp; libxfs_init_t x; xfs_agnumber_t cur_agno = NULLAGNUMBER; static void usage(void) { fprintf(stderr, _( "Usage: %s [-fFrxV] [-p prog] [-l logdev] [-c cmd]... device\n" ), progname); exit(1); } void init( int argc, char **argv) { xfs_sb_t *sbp; void *bufp = NULL; int c; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); progname = basename(argv[0]); while ((c = getopt(argc, argv, "c:fFip:rxVl:")) != EOF) { switch (c) { case 'c': cmdline = xrealloc(cmdline, (ncmdline+1)*sizeof(char*)); cmdline[ncmdline++] = optarg; break; case 'f': x.disfile = 1; break; case 'F': force = 1; break; case 'i': x.isreadonly = (LIBXFS_ISREADONLY|LIBXFS_ISINACTIVE); break; case 'p': progname = optarg; break; case 'r': x.isreadonly = LIBXFS_ISREADONLY; break; case 'l': x.logname = optarg; break; case 'x': expert_mode = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': usage(); /*NOTREACHED*/ } } if (optind + 1 != argc) { usage(); /*NOTREACHED*/ } fsdevice = argv[optind]; if (!x.disfile) x.volname = fsdevice; else x.dname = fsdevice; if (!libxfs_init(&x)) { fputs(_("\nfatal error -- couldn't initialize XFS library\n"), stderr); exit(1); } if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) { fprintf(stderr, _("%s: %s is invalid (cannot read first 512 " "bytes)\n"), progname, fsdevice); exit(1); } /* copy SB from buffer to in-core, converting architecture as we go */ libxfs_sb_from_disk(&xmount.m_sb, bufp); xfree(bufp); sbp = &xmount.m_sb; if (sbp->sb_magicnum != XFS_SB_MAGIC) { fprintf(stderr, _("%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n"), progname, fsdevice, sbp->sb_magicnum); if (!force) exit(EXIT_FAILURE); } mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, LIBXFS_MOUNT_ROOTINOS | LIBXFS_MOUNT_DEBUGGER); if (!mp) { mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, LIBXFS_MOUNT_DEBUGGER); if (!mp) { fprintf(stderr, _("%s: device %s unusable (not an XFS " "filesystem?)\n"), progname, fsdevice); exit(1); } } blkbb = 1 << mp->m_blkbb_log; push_cur(); init_commands(); init_sig(); } int main( int argc, char **argv) { int c, i, done = 0; char *input; char **v; pushfile(stdin); init(argc, argv); for (i = 0; !done && i < ncmdline; i++) { v = breakline(cmdline[i], &c); if (c) done = command(c, v); xfree(v); } if (cmdline) { xfree(cmdline); goto close_devices; } while (!done) { if ((input = fetchline()) == NULL) break; v = breakline(input, &c); if (c) done = command(c, v); doneline(input, v); } close_devices: if (x.ddev) libxfs_device_close(x.ddev); if (x.logdev && x.logdev != x.ddev) libxfs_device_close(x.logdev); if (x.rtdev) libxfs_device_close(x.rtdev); return exitcode; } xfsprogs-3.1.9ubuntu2/db/agf.c0000664000000000000000000000733611146407622013116 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "command.h" #include "type.h" #include "faddr.h" #include "fprint.h" #include "field.h" #include "io.h" #include "bit.h" #include "output.h" #include "init.h" #include "agf.h" static int agf_f(int argc, char **argv); static void agf_help(void); static const cmdinfo_t agf_cmd = { "agf", NULL, agf_f, 0, 1, 1, N_("[agno]"), N_("set address to agf header"), agf_help }; const field_t agf_hfld[] = { { "", FLDT_AGF, OI(0), C1, 0, TYP_NONE }, { NULL } }; #define OFF(f) bitize(offsetof(xfs_agf_t, agf_ ## f)) #define SZ(f) bitszof(xfs_agf_t, agf_ ## f) const field_t agf_flds[] = { { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, { "versionnum", FLDT_UINT32D, OI(OFF(versionnum)), C1, 0, TYP_NONE }, { "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE }, { "length", FLDT_AGBLOCK, OI(OFF(length)), C1, 0, TYP_NONE }, { "roots", FLDT_AGBLOCK, OI(OFF(roots)), CI(XFS_BTNUM_AGF), FLD_ARRAY|FLD_SKIPALL, TYP_NONE }, { "bnoroot", FLDT_AGBLOCK, OI(OFF(roots) + XFS_BTNUM_BNO * SZ(roots[XFS_BTNUM_BNO])), C1, 0, TYP_BNOBT }, { "cntroot", FLDT_AGBLOCK, OI(OFF(roots) + XFS_BTNUM_CNT * SZ(roots[XFS_BTNUM_CNT])), C1, 0, TYP_CNTBT }, { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF), FLD_ARRAY|FLD_SKIPALL, TYP_NONE }, { "bnolevel", FLDT_UINT32D, OI(OFF(levels) + XFS_BTNUM_BNO * SZ(levels[XFS_BTNUM_BNO])), C1, 0, TYP_NONE }, { "cntlevel", FLDT_UINT32D, OI(OFF(levels) + XFS_BTNUM_CNT * SZ(levels[XFS_BTNUM_CNT])), C1, 0, TYP_NONE }, { "flfirst", FLDT_UINT32D, OI(OFF(flfirst)), C1, 0, TYP_NONE }, { "fllast", FLDT_UINT32D, OI(OFF(fllast)), C1, 0, TYP_NONE }, { "flcount", FLDT_UINT32D, OI(OFF(flcount)), C1, 0, TYP_NONE }, { "freeblks", FLDT_EXTLEN, OI(OFF(freeblks)), C1, 0, TYP_NONE }, { "longest", FLDT_EXTLEN, OI(OFF(longest)), C1, 0, TYP_NONE }, { "btreeblks", FLDT_UINT32D, OI(OFF(btreeblks)), C1, 0, TYP_NONE }, { NULL } }; static void agf_help(void) { dbprintf(_( "\n" " set allocation group free block list\n" "\n" " Example:\n" "\n" " agf 2 - move location to AGF in 2nd filesystem allocation group\n" "\n" " Located in the second sector of each allocation group, the AGF\n" " contains the root of two different freespace btrees:\n" " The 'cnt' btree keeps track freespace indexed on section size.\n" " The 'bno' btree tracks sections of freespace indexed on block number.\n" )); } static int agf_f( int argc, char **argv) { xfs_agnumber_t agno; char *p; if (argc > 1) { agno = (xfs_agnumber_t)strtoul(argv[1], &p, 0); if (*p != '\0' || agno >= mp->m_sb.sb_agcount) { dbprintf(_("bad allocation group number %s\n"), argv[1]); return 0; } cur_agno = agno; } else if (cur_agno == NULLAGNUMBER) cur_agno = 0; ASSERT(typtab[TYP_AGF].typnm == TYP_AGF); set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, cur_agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_ADD, NULL); return 0; } void agf_init(void) { add_command(&agf_cmd); } int agf_size( void *obj, int startoff, int idx) { return bitize(mp->m_sb.sb_sectsize); } xfsprogs-3.1.9ubuntu2/db/debug.h0000664000000000000000000000145011140033220013422 0ustar /* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define DEBUG_FLIST 0x1 extern long debug_state; extern void debug_init(void); xfsprogs-3.1.9ubuntu2/db/frag.c0000664000000000000000000002667111650373060013301 0ustar /* * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "bmap.h" #include "command.h" #include "frag.h" #include "io.h" #include "output.h" #include "type.h" #include "init.h" #include "malloc.h" typedef struct extent { xfs_fileoff_t startoff; xfs_filblks_t blockcount; } extent_t; typedef struct extmap { int naents; int nents; extent_t ents[1]; } extmap_t; #define EXTMAP_SIZE(n) \ (offsetof(extmap_t, ents) + (sizeof(extent_t) * (n))) static int aflag; static int dflag; static __uint64_t extcount_actual; static __uint64_t extcount_ideal; static int fflag; static int lflag; static int qflag; static int Rflag; static int rflag; static int vflag; typedef void (*scan_lbtree_f_t)(struct xfs_btree_block *block, int level, extmap_t **extmapp, typnm_t btype); typedef void (*scan_sbtree_f_t)(struct xfs_btree_block *block, int level, xfs_agf_t *agf); static extmap_t *extmap_alloc(xfs_extnum_t nex); static xfs_extnum_t extmap_ideal(extmap_t *extmap); static void extmap_set_ext(extmap_t **extmapp, xfs_fileoff_t o, xfs_extlen_t c); static int frag_f(int argc, char **argv); static int init(int argc, char **argv); static void process_bmbt_reclist(xfs_bmbt_rec_t *rp, int numrecs, extmap_t **extmapp); static void process_btinode(xfs_dinode_t *dip, extmap_t **extmapp, int whichfork); static void process_exinode(xfs_dinode_t *dip, extmap_t **extmapp, int whichfork); static void process_fork(xfs_dinode_t *dip, int whichfork); static void process_inode(xfs_agf_t *agf, xfs_agino_t agino, xfs_dinode_t *dip); static void scan_ag(xfs_agnumber_t agno); static void scan_lbtree(xfs_fsblock_t root, int nlevels, scan_lbtree_f_t func, extmap_t **extmapp, typnm_t btype); static void scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root, int nlevels, scan_sbtree_f_t func, typnm_t btype); static void scanfunc_bmap(struct xfs_btree_block *block, int level, extmap_t **extmapp, typnm_t btype); static void scanfunc_ino(struct xfs_btree_block *block, int level, xfs_agf_t *agf); static const cmdinfo_t frag_cmd = { "frag", NULL, frag_f, 0, -1, 0, "[-a] [-d] [-f] [-l] [-q] [-R] [-r] [-v]", "get file fragmentation data", NULL }; static extmap_t * extmap_alloc( xfs_extnum_t nex) { extmap_t *extmap; if (nex < 1) nex = 1; extmap = xmalloc(EXTMAP_SIZE(nex)); extmap->naents = nex; extmap->nents = 0; return extmap; } static xfs_extnum_t extmap_ideal( extmap_t *extmap) { extent_t *ep; xfs_extnum_t rval; for (ep = &extmap->ents[0], rval = 0; ep < &extmap->ents[extmap->nents]; ep++) { if (ep == &extmap->ents[0] || ep->startoff != ep[-1].startoff + ep[-1].blockcount) rval++; } return rval; } static void extmap_set_ext( extmap_t **extmapp, xfs_fileoff_t o, xfs_extlen_t c) { extmap_t *extmap; extent_t *ent; extmap = *extmapp; if (extmap->nents == extmap->naents) { extmap->naents++; extmap = xrealloc(extmap, EXTMAP_SIZE(extmap->naents)); *extmapp = extmap; } ent = &extmap->ents[extmap->nents]; ent->startoff = o; ent->blockcount = c; extmap->nents++; } void frag_init(void) { add_command(&frag_cmd); } /* * Get file fragmentation information. */ static int frag_f( int argc, char **argv) { xfs_agnumber_t agno; double answer; if (!init(argc, argv)) return 0; for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) scan_ag(agno); if (extcount_actual) answer = (double)(extcount_actual - extcount_ideal) * 100.0 / (double)extcount_actual; else answer = 0.0; dbprintf(_("actual %llu, ideal %llu, fragmentation factor %.2f%%\n"), extcount_actual, extcount_ideal, answer); return 0; } static int init( int argc, char **argv) { int c; aflag = dflag = fflag = lflag = qflag = Rflag = rflag = vflag = 0; optind = 0; while ((c = getopt(argc, argv, "adflqRrv")) != EOF) { switch (c) { case 'a': aflag = 1; break; case 'd': dflag = 1; break; case 'f': fflag = 1; break; case 'l': lflag = 1; break; case 'q': qflag = 1; break; case 'R': Rflag = 1; break; case 'r': rflag = 1; break; case 'v': vflag = 1; break; default: dbprintf(_("bad option for frag command\n")); return 0; } } if (!aflag && !dflag && !fflag && !lflag && !qflag && !Rflag && !rflag) aflag = dflag = fflag = lflag = qflag = Rflag = rflag = 1; extcount_actual = extcount_ideal = 0; return 1; } static void process_bmbt_reclist( xfs_bmbt_rec_t *rp, int numrecs, extmap_t **extmapp) { xfs_dfilblks_t c; int f; int i; xfs_dfiloff_t o; xfs_dfsbno_t s; for (i = 0; i < numrecs; i++, rp++) { convert_extent(rp, &o, &s, &c, &f); extmap_set_ext(extmapp, (xfs_fileoff_t)o, (xfs_extlen_t)c); } } static void process_btinode( xfs_dinode_t *dip, extmap_t **extmapp, int whichfork) { xfs_bmdr_block_t *dib; int i; xfs_bmbt_ptr_t *pp; dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); if (be16_to_cpu(dib->bb_level) == 0) { xfs_bmbt_rec_t *rp = XFS_BMDR_REC_ADDR(dib, 1); process_bmbt_reclist(rp, be16_to_cpu(dib->bb_numrecs), extmapp); return; } pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork), 0)); for (i = 0; i < be16_to_cpu(dib->bb_numrecs); i++) scan_lbtree(be64_to_cpu(pp[i]), be16_to_cpu(dib->bb_level), scanfunc_bmap, extmapp, whichfork == XFS_DATA_FORK ? TYP_BMAPBTD : TYP_BMAPBTA); } static void process_exinode( xfs_dinode_t *dip, extmap_t **extmapp, int whichfork) { xfs_bmbt_rec_t *rp; rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp); } static void process_fork( xfs_dinode_t *dip, int whichfork) { extmap_t *extmap; int nex; nex = XFS_DFORK_NEXTENTS(dip, whichfork); if (!nex) return; extmap = extmap_alloc(nex); switch (XFS_DFORK_FORMAT(dip, whichfork)) { case XFS_DINODE_FMT_EXTENTS: process_exinode(dip, &extmap, whichfork); break; case XFS_DINODE_FMT_BTREE: process_btinode(dip, &extmap, whichfork); break; } extcount_actual += extmap->nents; extcount_ideal += extmap_ideal(extmap); xfree(extmap); } static void process_inode( xfs_agf_t *agf, xfs_agino_t agino, xfs_dinode_t *dip) { __uint64_t actual; __uint64_t ideal; xfs_ino_t ino; int skipa; int skipd; ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino); switch (be16_to_cpu(dip->di_mode) & S_IFMT) { case S_IFDIR: skipd = !dflag; break; case S_IFREG: if (!rflag && (be16_to_cpu(dip->di_flags) & XFS_DIFLAG_REALTIME)) skipd = 1; else if (!Rflag && (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino)) skipd = 1; else if (!qflag && (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)) skipd = 1; else skipd = !fflag; break; case S_IFLNK: skipd = !lflag; break; default: skipd = 1; break; } actual = extcount_actual; ideal = extcount_ideal; if (!skipd) process_fork(dip, XFS_DATA_FORK); skipa = !aflag || !XFS_DFORK_Q(dip); if (!skipa) process_fork(dip, XFS_ATTR_FORK); if (vflag && (!skipd || !skipa)) dbprintf(_("inode %lld actual %lld ideal %lld\n"), ino, extcount_actual - actual, extcount_ideal - ideal); } static void scan_ag( xfs_agnumber_t agno) { xfs_agf_t *agf; xfs_agi_t *agi; push_cur(); set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agf = iocur_top->data) == NULL) { dbprintf(_("can't read agf block for ag %u\n"), agno); pop_cur(); return; } push_cur(); set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agi = iocur_top->data) == NULL) { dbprintf(_("can't read agi block for ag %u\n"), agno); pop_cur(); pop_cur(); return; } scan_sbtree(agf, be32_to_cpu(agi->agi_root), be32_to_cpu(agi->agi_level), scanfunc_ino, TYP_INOBT); pop_cur(); pop_cur(); } static void scan_lbtree( xfs_fsblock_t root, int nlevels, scan_lbtree_f_t func, extmap_t **extmapp, typnm_t btype) { push_cur(); set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, root), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { dbprintf(_("can't read btree block %u/%u\n"), XFS_FSB_TO_AGNO(mp, root), XFS_FSB_TO_AGBNO(mp, root)); return; } (*func)(iocur_top->data, nlevels - 1, extmapp, btype); pop_cur(); } static void scan_sbtree( xfs_agf_t *agf, xfs_agblock_t root, int nlevels, scan_sbtree_f_t func, typnm_t btype) { xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); push_cur(); set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, seqno, root), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { dbprintf(_("can't read btree block %u/%u\n"), seqno, root); return; } (*func)(iocur_top->data, nlevels - 1, agf); pop_cur(); } static void scanfunc_bmap( struct xfs_btree_block *block, int level, extmap_t **extmapp, typnm_t btype) { int i; xfs_bmbt_ptr_t *pp; xfs_bmbt_rec_t *rp; int nrecs; nrecs = be16_to_cpu(block->bb_numrecs); if (level == 0) { if (nrecs > mp->m_bmap_dmxr[0]) { dbprintf(_("invalid numrecs (%u) in %s block\n"), nrecs, typtab[btype].name); return; } rp = XFS_BMBT_REC_ADDR(mp, block, 1); process_bmbt_reclist(rp, nrecs, extmapp); return; } if (nrecs > mp->m_bmap_dmxr[1]) { dbprintf(_("invalid numrecs (%u) in %s block\n"), nrecs, typtab[btype].name); return; } pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[0]); for (i = 0; i < nrecs; i++) scan_lbtree(be64_to_cpu(pp[i]), level, scanfunc_bmap, extmapp, btype); } static void scanfunc_ino( struct xfs_btree_block *block, int level, xfs_agf_t *agf) { xfs_agino_t agino; xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); int i; int j; int off; xfs_inobt_ptr_t *pp; xfs_inobt_rec_t *rp; if (level == 0) { rp = XFS_INOBT_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { agino = be32_to_cpu(rp[i].ir_startino); off = XFS_INO_TO_OFFSET(mp, agino); push_cur(); set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, seqno, XFS_AGINO_TO_AGBNO(mp, agino)), XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)), DB_RING_IGN, NULL); if (iocur_top->data == NULL) { dbprintf(_("can't read inode block %u/%u\n"), seqno, XFS_AGINO_TO_AGBNO(mp, agino)); continue; } for (j = 0; j < XFS_INODES_PER_CHUNK; j++) { if (XFS_INOBT_IS_FREE_DISK(&rp[i], j)) continue; process_inode(agf, agino + j, (xfs_dinode_t *) ((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog))); } pop_cur(); } return; } pp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) scan_sbtree(agf, be32_to_cpu(pp[i]), level, scanfunc_ino, TYP_INOBT); } xfsprogs-3.1.9ubuntu2/fsck/0000775000000000000000000000000012062211564012541 5ustar xfsprogs-3.1.9ubuntu2/fsck/Makefile0000664000000000000000000000050511307015331014174 0ustar # # Copyright (c) 2006 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs LSRCFILES = xfs_fsck.sh default: $(LTCOMMAND) include $(BUILDRULES) install: default $(INSTALL) -m 755 -d $(PKG_ROOT_SBIN_DIR) $(INSTALL) -m 755 xfs_fsck.sh $(PKG_ROOT_SBIN_DIR)/fsck.xfs install-dev: xfsprogs-3.1.9ubuntu2/fsck/xfs_fsck.sh0000775000000000000000000000070211140033220014670 0ustar #!/bin/sh -f # # Copyright (c) 2006 Silicon Graphics, Inc. All Rights Reserved. # AUTO=false while getopts ":aApy" c do case $c in a|A|p|y) AUTO=true;; esac done eval DEV=\${$#} if [ ! -e $DEV ]; then echo "$0: $DEV does not exist" exit 8 fi if $AUTO; then echo "$0: XFS file system." else echo "If you wish to check the consistency of an XFS filesystem or" echo "repair a damaged filesystem, see xfs_check(8) and xfs_repair(8)." fi exit 0 xfsprogs-3.1.9ubuntu2/m4/0000775000000000000000000000000012254353666012150 5ustar xfsprogs-3.1.9ubuntu2/m4/Makefile0000664000000000000000000000106711330256617013604 0ustar # # Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. # TOPDIR = .. include $(TOPDIR)/include/builddefs CONFIGURE = \ libtool.m4 \ ltoptions.m4 \ ltsugar.m4 \ ltversion.m4 \ lt~obsolete.m4 LSRCFILES = \ manual_format.m4 \ package_aiodev.m4 \ package_blkid.m4 \ package_globals.m4 \ package_libcdev.m4 \ package_pthread.m4 \ package_types.m4 \ package_utilies.m4 \ package_uuiddev.m4 \ multilib.m4 \ $(CONFIGURE) default: include $(BUILDRULES) install install-dev install-lib: default realclean: distclean rm -f $(CONFIGURE) xfsprogs-3.1.9ubuntu2/m4/package_aiodev.m40000664000000000000000000000143311432652134015322 0ustar # # Check if we have a libaio.h installed # AC_DEFUN([AC_PACKAGE_WANT_AIO], [ AC_CHECK_HEADERS(libaio.h, [ have_aio=true ], [ have_aio=false ]) AC_SUBST(have_aio) ]) # # Check if we have an aio.h installed # AC_DEFUN([AC_PACKAGE_NEED_AIO_H], [ AC_CHECK_HEADERS(aio.h) if test $ac_cv_header_aio_h = no; then echo echo 'FATAL ERROR: could not find a valid header.' exit 1 fi ]) # # Check if we have the lio_listio routine in either libc/librt # AC_DEFUN([AC_PACKAGE_NEED_LIO_LISTIO], [ AC_CHECK_FUNCS(lio_listio) if test $ac_cv_func_lio_listio = yes; then librt="" else AC_CHECK_LIB(rt, lio_listio,, [ echo echo 'FATAL ERROR: could not find a library with lio_listio.' exit 1],[-lpthread]) librt="-lrt" fi AC_SUBST(librt) ]) xfsprogs-3.1.9ubuntu2/m4/package_blkid.m40000664000000000000000000000065411323235441015141 0ustar # # See if blkid has the topology bits # AC_DEFUN([AC_HAVE_BLKID_TOPO], [ enable_blkid="$1" if test "$enable_blkid" = "yes"; then AC_SEARCH_LIBS([blkid_probe_all], [blkid]) AC_CHECK_FUNCS(blkid_probe_get_topology) if test $ac_cv_func_blkid_probe_get_topology = yes; then libblkid="-lblkid" else libblkd="" enable_blkid="no" AC_SUBST(enable_blkid) fi fi AC_SUBST(libblkid) ]) xfsprogs-3.1.9ubuntu2/m4/package_utilies.m40000664000000000000000000000757611330256617015552 0ustar # # Check for specified utility (env var) - if unset, fail. # AC_DEFUN([AC_PACKAGE_NEED_UTILITY], [ if test -z "$2"; then echo echo FATAL ERROR: $3 does not seem to be installed. echo $1 cannot be built without a working $4 installation. exit 1 fi ]) # #check compiler can generate dependencies # AC_DEFUN([AC_PACKAGE_GCC_DEPS], [AC_CACHE_CHECK(whether gcc -MM is supported, ac_cv_gcc_nodeps, [cat > conftest.c < int main() { exit(0); } EOF ac_cv_gcc_nodeps=no if ${CC} -MM conftest.c >/dev/null 2>&1; then ac_cv_gcc_nodeps=yes fi rm -f conftest.c a.out ]) ]) # # Generic macro, sets up all of the global build variables. # The following environment variables may be set to override defaults: # CC MAKE LIBTOOL TAR ZIP MAKEDEPEND AWK SED ECHO SORT # MSGFMT MSGMERGE XGETTEXT RPM # AC_DEFUN([AC_PACKAGE_UTILITIES], [ AC_PROG_CC cc="$CC" AC_SUBST(cc) AC_PACKAGE_NEED_UTILITY($1, "$cc", cc, [C compiler]) if test -z "$MAKE"; then AC_PATH_PROG(MAKE, gmake,, /usr/bin:/usr/local/bin:/usr/freeware/bin) fi if test -z "$MAKE"; then AC_PATH_PROG(MAKE, make,, /usr/bin) fi make=$MAKE AC_SUBST(make) AC_PACKAGE_NEED_UTILITY($1, "$make", make, [GNU make]) if test -z "$TAR"; then AC_PATH_PROG(TAR, tar,, /usr/freeware/bin:/bin:/usr/local/bin:/usr/bin) fi tar=$TAR AC_SUBST(tar) if test -z "$ZIP"; then AC_PATH_PROG(ZIP, gzip,, /bin:/usr/bin:/usr/local/bin:/usr/freeware/bin) fi zip=$ZIP AC_SUBST(zip) AC_PACKAGE_GCC_DEPS() makedepend="$cc -MM" if test $ac_cv_gcc_nodeps = no; then makedepend=/bin/true fi AC_SUBST(makedepend) if test -z "$AWK"; then AC_PATH_PROG(AWK, awk,, /bin:/usr/bin) fi awk=$AWK AC_SUBST(awk) if test -z "$SED"; then AC_PATH_PROG(SED, sed,, /bin:/usr/bin) fi sed=$SED AC_SUBST(sed) if test -z "$ECHO"; then AC_PATH_PROG(ECHO, echo,, /bin:/usr/bin) fi echo=$ECHO AC_SUBST(echo) if test -z "$SORT"; then AC_PATH_PROG(SORT, sort,, /bin:/usr/bin) fi sort=$SORT AC_SUBST(sort) dnl check if symbolic links are supported AC_PROG_LN_S if test "$enable_gettext" = yes; then if test -z "$MSGFMT"; then AC_PATH_PROG(MSGFMT, msgfmt,, /usr/bin:/usr/local/bin:/usr/freeware/bin) fi msgfmt=$MSGFMT AC_SUBST(msgfmt) AC_PACKAGE_NEED_UTILITY($1, "$msgfmt", msgfmt, gettext) if test -z "$MSGMERGE"; then AC_PATH_PROG(MSGMERGE, msgmerge,, /usr/bin:/usr/local/bin:/usr/freeware/bin) fi msgmerge=$MSGMERGE AC_SUBST(msgmerge) AC_PACKAGE_NEED_UTILITY($1, "$msgmerge", msgmerge, gettext) if test -z "$XGETTEXT"; then AC_PATH_PROG(XGETTEXT, xgettext,, /usr/bin:/usr/local/bin:/usr/freeware/bin) fi xgettext=$XGETTEXT AC_SUBST(xgettext) AC_PACKAGE_NEED_UTILITY($1, "$xgettext", xgettext, gettext) fi if test -z "$RPM"; then AC_PATH_PROG(RPM, rpm,, /bin:/usr/bin:/usr/freeware/bin) fi rpm=$RPM AC_SUBST(rpm) dnl .. and what version is rpm rpm_version=0 test -n "$RPM" && test -x "$RPM" && rpm_version=`$RPM --version \ | awk '{print $NF}' | awk -F. '{V=1; print $V}'` AC_SUBST(rpm_version) dnl At some point in rpm 4.0, rpm can no longer build rpms, and dnl rpmbuild is needed (rpmbuild may go way back; not sure) dnl So, if rpm version >= 4.0, look for rpmbuild. Otherwise build w/ rpm if test $rpm_version -ge 4; then AC_PATH_PROG(RPMBUILD, rpmbuild) rpmbuild=$RPMBUILD else rpmbuild=$RPM fi AC_SUBST(rpmbuild) ]) xfsprogs-3.1.9ubuntu2/m4/package_libcdev.m40000664000000000000000000000713512062210562015463 0ustar # # Check if we have a working fadvise system call # AC_DEFUN([AC_HAVE_FADVISE], [ AC_MSG_CHECKING([for fadvise ]) AC_TRY_COMPILE([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ], [ posix_fadvise(0, 1, 0, POSIX_FADV_NORMAL); ], have_fadvise=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_fadvise) ]) # # Check if we have a working madvise system call # AC_DEFUN([AC_HAVE_MADVISE], [ AC_MSG_CHECKING([for madvise ]) AC_TRY_COMPILE([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ], [ posix_madvise(0, 0, MADV_NORMAL); ], have_madvise=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_madvise) ]) # # Check if we have a working mincore system call # AC_DEFUN([AC_HAVE_MINCORE], [ AC_MSG_CHECKING([for mincore ]) AC_TRY_COMPILE([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ], [ mincore(0, 0, 0); ], have_mincore=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_mincore) ]) # # Check if we have a working sendfile system call # AC_DEFUN([AC_HAVE_SENDFILE], [ AC_MSG_CHECKING([for sendfile ]) AC_TRY_COMPILE([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ], [ sendfile(0, 0, 0, 0); ], have_sendfile=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_sendfile) ]) # # Check if we have a getmntent libc call (IRIX, Linux) # AC_DEFUN([AC_HAVE_GETMNTENT], [ AC_MSG_CHECKING([for getmntent ]) AC_TRY_COMPILE([ #include #include ], [ getmntent(0); ], have_getmntent=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_getmntent) ]) # # Check if we have a getmntinfo libc call (FreeBSD, Mac OS X) # AC_DEFUN([AC_HAVE_GETMNTINFO], [ AC_MSG_CHECKING([for getmntinfo ]) AC_TRY_COMPILE([ #include #include #include ], [ getmntinfo(0, 0); ], have_getmntinfo=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_getmntinfo) ]) # # Check if we have a fallocate libc call (Linux) # AC_DEFUN([AC_HAVE_FALLOCATE], [ AC_MSG_CHECKING([for fallocate]) AC_TRY_LINK([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include ], [ fallocate(0, 0, 0, 0); ], have_fallocate=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_fallocate) ]) # # Check if we have the fiemap ioctl (Linux) # AC_DEFUN([AC_HAVE_FIEMAP], [ AC_MSG_CHECKING([for fiemap]) AC_TRY_LINK([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include ], [ struct fiemap *fiemap; ioctl(0, FS_IOC_FIEMAP, (unsigned long)fiemap); ], have_fiemap=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_fiemap) ]) # # Check if we have a preadv libc call (Linux) # AC_DEFUN([AC_HAVE_PREADV], [ AC_MSG_CHECKING([for preadv]) AC_TRY_LINK([ #define _FILE_OFFSET_BITS 64 #define _BSD_SOURCE #include ], [ preadv(0, 0, 0, 0); ], have_preadv=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_preadv) ]) # # Check if we have a sync_file_range libc call (Linux) # AC_DEFUN([AC_HAVE_SYNC_FILE_RANGE], [ AC_MSG_CHECKING([for sync_file_range]) AC_TRY_LINK([ #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ], [ sync_file_range(0, 0, 0, 0); ], have_sync_file_range=yes AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) AC_SUBST(have_sync_file_range) ]) xfsprogs-3.1.9ubuntu2/m4/libtool.m40000664000000000000000000106055312254353666014070 0ustar # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS xfsprogs-3.1.9ubuntu2/m4/package_uuiddev.m40000664000000000000000000000137011140033220015501 0ustar AC_DEFUN([AC_PACKAGE_NEED_UUID_H], [ AC_CHECK_HEADERS([uuid.h sys/uuid.h uuid/uuid.h]) if test $ac_cv_header_uuid_h = no -a \ $ac_cv_header_sys_uuid_h = no -a \ $ac_cv_header_uuid_uuid_h = no; then echo echo 'FATAL ERROR: could not find a valid UUID header.' echo 'Install the Universally Unique Identifiers development package.' exit 1 fi ]) AC_DEFUN([AC_PACKAGE_NEED_UUIDCOMPARE], [ AC_CHECK_FUNCS(uuid_compare) if test $ac_cv_func_uuid_compare = yes; then libuuid="" else AC_CHECK_LIB(uuid, uuid_compare,, [ echo echo 'FATAL ERROR: could not find a valid UUID library.' echo 'Install the Universally Unique Identifiers library package.' exit 1]) libuuid="-luuid" fi AC_SUBST(libuuid) ]) xfsprogs-3.1.9ubuntu2/m4/lt~obsolete.m40000664000000000000000000001375611711735052014766 0ustar # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) xfsprogs-3.1.9ubuntu2/m4/package_pthread.m40000664000000000000000000000072511140033220015466 0ustar AC_DEFUN([AC_PACKAGE_NEED_PTHREAD_H], [ AC_CHECK_HEADERS(pthread.h) if test $ac_cv_header_pthread_h = no; then AC_CHECK_HEADERS(pthread.h,, [ echo echo 'FATAL ERROR: could not find a valid pthread header.' exit 1]) fi ]) AC_DEFUN([AC_PACKAGE_NEED_PTHREADMUTEXINIT], [ AC_CHECK_LIB(pthread, pthread_mutex_init,, [ echo echo 'FATAL ERROR: could not find a valid pthread library.' exit 1 ]) libpthread=-lpthread AC_SUBST(libpthread) ]) xfsprogs-3.1.9ubuntu2/m4/multilib.m40000664000000000000000000000345411140033220014207 0ustar # The AC_MULTILIB macro was extracted and modified from # gettext-0.15's AC_LIB_PREPARE_MULTILIB macro in the lib-prefix.m4 file # so that the correct paths can be used for 64-bit libraries. # dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_MULTILIB creates a variable libdirsuffix, containing dnl the suffix of the libdir, either "" or "64". dnl Only do this if the given enable parameter is "yes". AC_DEFUN([AC_MULTILIB], [ dnl There is no formal standard regarding lib and lib64. The current dnl practice is that on a system supporting 32-bit and 64-bit instruction dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit dnl libraries go under $prefix/lib. We determine the compiler's default dnl mode by looking at the compiler's library search path. If at least dnl of its elements ends in /lib64 or points to a directory whose absolute dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the dnl default, namely "lib". enable_lib64="$1" libdirsuffix="" searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test "$enable_lib64" = "yes" -a -n "$searchpath"; then save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) libdirsuffix=64 ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) libdirsuffix=64 ;; esac ;; esac fi done IFS="$save_IFS" fi AC_SUBST(libdirsuffix) ]) xfsprogs-3.1.9ubuntu2/m4/ltsugar.m40000664000000000000000000001042411711735051014061 0ustar # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) xfsprogs-3.1.9ubuntu2/m4/ltoptions.m40000664000000000000000000003007311711735051014435 0ustar # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) xfsprogs-3.1.9ubuntu2/m4/package_types.m40000664000000000000000000000173612062210562015220 0ustar # # Check if we have a type for the pointer's size integer (__psint_t) # AC_DEFUN([AC_TYPE_PSINT], [ AC_MSG_CHECKING([for __psint_t ]) AC_TRY_COMPILE([ #include #include #include ], [ __psint_t psint; ], AC_DEFINE(HAVE___PSINT_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ]) # # Check if we have a type for the pointer's size unsigned (__psunsigned_t) # AC_DEFUN([AC_TYPE_PSUNSIGNED], [ AC_MSG_CHECKING([for __psunsigned_t ]) AC_TRY_COMPILE([ #include #include #include ], [ __psunsigned_t psuint; ], AC_DEFINE(HAVE___PSUNSIGNED_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ]) # # Check if we have a type for __u32 # AC_DEFUN([AC_TYPE_U32], [ AC_MSG_CHECKING([for __u32 ]) AC_TRY_COMPILE([ #include #include #include ], [ __u32 u32; ], AC_DEFINE(HAVE___U32) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ]) xfsprogs-3.1.9ubuntu2/m4/package_globals.m40000664000000000000000000000250011352301337015467 0ustar # # Generic macro, sets up all of the global packaging variables. # The following environment variables may be set to override defaults: # DEBUG OPTIMIZER MALLOCLIB PLATFORM DISTRIBUTION INSTALL_USER INSTALL_GROUP # BUILD_VERSION # AC_DEFUN([AC_PACKAGE_GLOBALS], [ pkg_name="$1" AC_SUBST(pkg_name) AC_PROG_CC . ./VERSION pkg_version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION} AC_SUBST(pkg_version) pkg_release=$PKG_BUILD test -z "$BUILD_VERSION" || pkg_release="$BUILD_VERSION" AC_SUBST(pkg_release) DEBUG=${DEBUG:-'-DDEBUG'} dnl -DNDEBUG debug_build="$DEBUG" AC_SUBST(debug_build) OPTIMIZER=${OPTIMIZER:-'-g -O2'} opt_build="$OPTIMIZER" AC_SUBST(opt_build) MALLOCLIB=${MALLOCLIB:-''} dnl /usr/lib/libefence.a malloc_lib="$MALLOCLIB" AC_SUBST(malloc_lib) pkg_user=`id -u -n` test -z "$INSTALL_USER" || pkg_user="$INSTALL_USER" AC_SUBST(pkg_user) pkg_group=`id -g -n` test -z "$INSTALL_GROUP" || pkg_group="$INSTALL_GROUP" AC_SUBST(pkg_group) pkg_distribution=`uname -s` test -z "$DISTRIBUTION" || pkg_distribution="$DISTRIBUTION" AC_SUBST(pkg_distribution) pkg_platform=`uname -s | tr 'A-Z' 'a-z' | tr -d / | sed -e 's/irix64/irix/'` test -z "$PLATFORM" || pkg_platform="$PLATFORM" AC_SUBST(pkg_platform) ]) xfsprogs-3.1.9ubuntu2/m4/ltversion.m40000664000000000000000000000126211711735051014425 0ustar # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) xfsprogs-3.1.9ubuntu2/m4/manual_format.m40000664000000000000000000000075111140033220015210 0ustar # # Find format of installed man pages. # Always gzipped on Debian, but not Redhat pre-7.0. # We don't deal with bzip2'd man pages, which Mandrake uses, # someone will send us a patch sometime hopefully. :-) # AC_DEFUN([AC_MANUAL_FORMAT], [ have_zipped_manpages=false for d in ${prefix}/share/man ${prefix}/man ; do if test -f $d/man1/man.1.gz then have_zipped_manpages=true break fi done AC_SUBST(have_zipped_manpages) ])